summaryrefslogtreecommitdiffstats
path: root/src/corelib/tools
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@nokia.com>2009-03-23 10:18:55 +0100
committerSimon Hausmann <simon.hausmann@nokia.com>2009-03-23 10:18:55 +0100
commite5fcad302d86d316390c6b0f62759a067313e8a9 (patch)
treec2afbf6f1066b6ce261f14341cf6d310e5595bc1 /src/corelib/tools
Long live Qt 4.5!
Diffstat (limited to 'src/corelib/tools')
-rw-r--r--src/corelib/tools/qalgorithms.h565
-rw-r--r--src/corelib/tools/qbitarray.cpp728
-rw-r--r--src/corelib/tools/qbitarray.h174
-rw-r--r--src/corelib/tools/qbytearray.cpp4240
-rw-r--r--src/corelib/tools/qbytearray.h589
-rw-r--r--src/corelib/tools/qbytearraymatcher.cpp323
-rw-r--r--src/corelib/tools/qbytearraymatcher.h93
-rw-r--r--src/corelib/tools/qcache.h216
-rw-r--r--src/corelib/tools/qchar.cpp1618
-rw-r--r--src/corelib/tools/qchar.h397
-rw-r--r--src/corelib/tools/qcontainerfwd.h71
-rw-r--r--src/corelib/tools/qcryptographichash.cpp196
-rw-r--r--src/corelib/tools/qcryptographichash.h84
-rw-r--r--src/corelib/tools/qdatetime.cpp5506
-rw-r--r--src/corelib/tools/qdatetime.h333
-rw-r--r--src/corelib/tools/qdatetime_p.h285
-rw-r--r--src/corelib/tools/qdumper.cpp1157
-rw-r--r--src/corelib/tools/qharfbuzz.cpp169
-rw-r--r--src/corelib/tools/qharfbuzz_p.h77
-rw-r--r--src/corelib/tools/qhash.cpp1843
-rw-r--r--src/corelib/tools/qhash.h1017
-rw-r--r--src/corelib/tools/qiterator.h202
-rw-r--r--src/corelib/tools/qline.cpp867
-rw-r--r--src/corelib/tools/qline.h424
-rw-r--r--src/corelib/tools/qlinkedlist.cpp1158
-rw-r--r--src/corelib/tools/qlinkedlist.h504
-rw-r--r--src/corelib/tools/qlist.h691
-rw-r--r--src/corelib/tools/qlistdata.cpp1742
-rw-r--r--src/corelib/tools/qlocale.cpp7220
-rw-r--r--src/corelib/tools/qlocale.h678
-rw-r--r--src/corelib/tools/qlocale_data_p.h3391
-rw-r--r--src/corelib/tools/qlocale_p.h206
-rw-r--r--src/corelib/tools/qmap.cpp1588
-rw-r--r--src/corelib/tools/qmap.h1026
-rw-r--r--src/corelib/tools/qpair.h127
-rw-r--r--src/corelib/tools/qpodlist_p.h263
-rw-r--r--src/corelib/tools/qpoint.cpp665
-rw-r--r--src/corelib/tools/qpoint.h361
-rw-r--r--src/corelib/tools/qqueue.cpp129
-rw-r--r--src/corelib/tools/qqueue.h69
-rw-r--r--src/corelib/tools/qrect.cpp2471
-rw-r--r--src/corelib/tools/qrect.h858
-rw-r--r--src/corelib/tools/qregexp.cpp4070
-rw-r--r--src/corelib/tools/qregexp.h155
-rw-r--r--src/corelib/tools/qringbuffer_p.h319
-rw-r--r--src/corelib/tools/qset.h352
-rw-r--r--src/corelib/tools/qshareddata.cpp550
-rw-r--r--src/corelib/tools/qshareddata.h242
-rw-r--r--src/corelib/tools/qsharedpointer.cpp868
-rw-r--r--src/corelib/tools/qsharedpointer.h148
-rw-r--r--src/corelib/tools/qsharedpointer_impl.h585
-rw-r--r--src/corelib/tools/qsize.cpp824
-rw-r--r--src/corelib/tools/qsize.h364
-rw-r--r--src/corelib/tools/qstack.cpp129
-rw-r--r--src/corelib/tools/qstack.h82
-rw-r--r--src/corelib/tools/qstring.cpp8083
-rw-r--r--src/corelib/tools/qstring.h1234
-rw-r--r--src/corelib/tools/qstringlist.cpp673
-rw-r--r--src/corelib/tools/qstringlist.h259
-rw-r--r--src/corelib/tools/qstringmatcher.cpp323
-rw-r--r--src/corelib/tools/qstringmatcher.h98
-rw-r--r--src/corelib/tools/qtextboundaryfinder.cpp476
-rw-r--r--src/corelib/tools/qtextboundaryfinder.h114
-rw-r--r--src/corelib/tools/qtimeline.cpp773
-rw-r--r--src/corelib/tools/qtimeline.h142
-rw-r--r--src/corelib/tools/qtools_p.h65
-rw-r--r--src/corelib/tools/qunicodetables.cpp9404
-rw-r--r--src/corelib/tools/qunicodetables_p.h231
-rw-r--r--src/corelib/tools/qvarlengtharray.h238
-rw-r--r--src/corelib/tools/qvector.cpp968
-rw-r--r--src/corelib/tools/qvector.h776
-rw-r--r--src/corelib/tools/qvsnprintf.cpp133
-rw-r--r--src/corelib/tools/tools.pri104
73 files changed, 77103 insertions, 0 deletions
diff --git a/src/corelib/tools/qalgorithms.h b/src/corelib/tools/qalgorithms.h
new file mode 100644
index 0000000000..3bfa6ad399
--- /dev/null
+++ b/src/corelib/tools/qalgorithms.h
@@ -0,0 +1,565 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QALGORITHMS_H
+#define QALGORITHMS_H
+
+#include <QtCore/qglobal.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Core)
+
+/*
+ Warning: The contents of QAlgorithmsPrivate is not a part of the public Qt API
+ and may be changed from version to version or even be completely removed.
+*/
+namespace QAlgorithmsPrivate {
+
+template <typename RandomAccessIterator, typename T, typename LessThan>
+Q_OUTOFLINE_TEMPLATE void qSortHelper(RandomAccessIterator start, RandomAccessIterator end, const T &t, LessThan lessThan);
+template <typename RandomAccessIterator, typename T>
+inline void qSortHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &dummy);
+
+template <typename RandomAccessIterator, typename T, typename LessThan>
+Q_OUTOFLINE_TEMPLATE void qStableSortHelper(RandomAccessIterator start, RandomAccessIterator end, const T &t, LessThan lessThan);
+template <typename RandomAccessIterator, typename T>
+inline void qStableSortHelper(RandomAccessIterator, RandomAccessIterator, const T &);
+
+template <typename RandomAccessIterator, typename T, typename LessThan>
+Q_OUTOFLINE_TEMPLATE RandomAccessIterator qLowerBoundHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan);
+template <typename RandomAccessIterator, typename T, typename LessThan>
+Q_OUTOFLINE_TEMPLATE RandomAccessIterator qUpperBoundHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan);
+template <typename RandomAccessIterator, typename T, typename LessThan>
+Q_OUTOFLINE_TEMPLATE RandomAccessIterator qBinaryFindHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan);
+
+}
+
+template <typename InputIterator, typename OutputIterator>
+inline OutputIterator qCopy(InputIterator begin, InputIterator end, OutputIterator dest)
+{
+ while (begin != end)
+ *dest++ = *begin++;
+ return dest;
+}
+
+template <typename BiIterator1, typename BiIterator2>
+inline BiIterator2 qCopyBackward(BiIterator1 begin, BiIterator1 end, BiIterator2 dest)
+{
+ while (begin != end)
+ *--dest = *--end;
+ return dest;
+}
+
+template <typename InputIterator1, typename InputIterator2>
+inline bool qEqual(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2)
+{
+ for (; first1 != last1; ++first1, ++first2)
+ if (!(*first1 == *first2))
+ return false;
+ return true;
+}
+
+template <typename ForwardIterator, typename T>
+inline void qFill(ForwardIterator first, ForwardIterator last, const T &val)
+{
+ for (; first != last; ++first)
+ *first = val;
+}
+
+template <typename Container, typename T>
+inline void qFill(Container &container, const T &val)
+{
+ qFill(container.begin(), container.end(), val);
+}
+
+template <typename InputIterator, typename T>
+inline InputIterator qFind(InputIterator first, InputIterator last, const T &val)
+{
+ while (first != last && !(*first == val))
+ ++first;
+ return first;
+}
+
+template <typename Container, typename T>
+inline typename Container::const_iterator qFind(const Container &container, const T &val)
+{
+ return qFind(container.constBegin(), container.constEnd(), val);
+}
+
+template <typename InputIterator, typename T, typename Size>
+inline void qCount(InputIterator first, InputIterator last, const T &value, Size &n)
+{
+ for (; first != last; ++first)
+ if (*first == value)
+ ++n;
+}
+
+template <typename Container, typename T, typename Size>
+inline void qCount(const Container &container, const T &value, Size &n)
+{
+ qCount(container.constBegin(), container.constEnd(), value, n);
+}
+
+
+#if defined Q_CC_MSVC && _MSC_VER < 1300
+template <typename T>
+inline void qSwap(T &value1, T &value2)
+{
+ qSwap_helper<T>(value1, value2, (T *)0);
+}
+#else
+template <typename T>
+inline void qSwap(T &value1, T &value2)
+{
+ T t = value1;
+ value1 = value2;
+ value2 = t;
+}
+#endif
+
+#ifdef qdoc
+template <typename T>
+LessThan qLess()
+{
+}
+
+template <typename T>
+LessThan qGreater()
+{
+}
+#else
+template <typename T>
+class qLess
+{
+public:
+ inline bool operator()(const T &t1, const T &t2) const
+ {
+ return (t1 < t2);
+ }
+};
+
+template <typename T>
+class qGreater
+{
+public:
+ inline bool operator()(const T &t1, const T &t2) const
+ {
+ return (t2 < t1);
+ }
+};
+#endif
+
+template <typename RandomAccessIterator>
+inline void qSort(RandomAccessIterator start, RandomAccessIterator end)
+{
+ if (start != end)
+ QAlgorithmsPrivate::qSortHelper(start, end, *start);
+}
+
+template <typename RandomAccessIterator, typename LessThan>
+inline void qSort(RandomAccessIterator start, RandomAccessIterator end, LessThan lessThan)
+{
+ if (start != end)
+ QAlgorithmsPrivate::qSortHelper(start, end, *start, lessThan);
+}
+
+template<typename Container>
+inline void qSort(Container &c)
+{
+#ifdef Q_CC_BOR
+ // Work around Borland 5.5 optimizer bug
+ c.detach();
+#endif
+ if (!c.empty())
+ QAlgorithmsPrivate::qSortHelper(c.begin(), c.end(), *c.begin());
+}
+
+template <typename RandomAccessIterator>
+inline void qStableSort(RandomAccessIterator start, RandomAccessIterator end)
+{
+ if (start != end)
+ QAlgorithmsPrivate::qStableSortHelper(start, end, *start);
+}
+
+template <typename RandomAccessIterator, typename LessThan>
+inline void qStableSort(RandomAccessIterator start, RandomAccessIterator end, LessThan lessThan)
+{
+ if (start != end)
+ QAlgorithmsPrivate::qStableSortHelper(start, end, *start, lessThan);
+}
+
+template<typename Container>
+inline void qStableSort(Container &c)
+{
+#ifdef Q_CC_BOR
+ // Work around Borland 5.5 optimizer bug
+ c.detach();
+#endif
+ if (!c.empty())
+ QAlgorithmsPrivate::qStableSortHelper(c.begin(), c.end(), *c.begin());
+}
+
+template <typename RandomAccessIterator, typename T>
+Q_OUTOFLINE_TEMPLATE RandomAccessIterator qLowerBound(RandomAccessIterator begin, RandomAccessIterator end, const T &value)
+{
+ // Implementation is duplicated from QAlgorithmsPrivate to keep existing code
+ // compiling. We have to allow using *begin and value with different types,
+ // and then implementing operator< for those types.
+ RandomAccessIterator middle;
+ int n = end - begin;
+ int half;
+
+ while (n > 0) {
+ half = n >> 1;
+ middle = begin + half;
+ if (*middle < value) {
+ begin = middle + 1;
+ n -= half + 1;
+ } else {
+ n = half;
+ }
+ }
+ return begin;
+}
+
+template <typename RandomAccessIterator, typename T, typename LessThan>
+Q_OUTOFLINE_TEMPLATE RandomAccessIterator qLowerBound(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan)
+{
+ return QAlgorithmsPrivate::qLowerBoundHelper(begin, end, value, lessThan);
+}
+
+template <typename Container, typename T>
+Q_OUTOFLINE_TEMPLATE typename Container::const_iterator qLowerBound(const Container &container, const T &value)
+{
+ return QAlgorithmsPrivate::qLowerBoundHelper(container.constBegin(), container.constEnd(), value, qLess<T>());
+}
+
+template <typename RandomAccessIterator, typename T>
+Q_OUTOFLINE_TEMPLATE RandomAccessIterator qUpperBound(RandomAccessIterator begin, RandomAccessIterator end, const T &value)
+{
+ // Implementation is duplicated from QAlgorithmsPrivate.
+ RandomAccessIterator middle;
+ int n = end - begin;
+ int half;
+
+ while (n > 0) {
+ half = n >> 1;
+ middle = begin + half;
+ if (value < *middle) {
+ n = half;
+ } else {
+ begin = middle + 1;
+ n -= half + 1;
+ }
+ }
+ return begin;
+}
+
+template <typename RandomAccessIterator, typename T, typename LessThan>
+Q_OUTOFLINE_TEMPLATE RandomAccessIterator qUpperBound(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan)
+{
+ return QAlgorithmsPrivate::qUpperBoundHelper(begin, end, value, lessThan);
+}
+
+template <typename Container, typename T>
+Q_OUTOFLINE_TEMPLATE typename Container::const_iterator qUpperBound(const Container &container, const T &value)
+{
+ return QAlgorithmsPrivate::qUpperBoundHelper(container.constBegin(), container.constEnd(), value, qLess<T>());
+}
+
+template <typename RandomAccessIterator, typename T>
+Q_OUTOFLINE_TEMPLATE RandomAccessIterator qBinaryFind(RandomAccessIterator begin, RandomAccessIterator end, const T &value)
+{
+ // Implementation is duplicated from QAlgorithmsPrivate.
+ qint64 l = 0;
+ qint64 r = end - begin - 1;
+ if (r < 0)
+ return end;
+ qint64 i = (l + r + 1) / 2;
+
+ while (r != l) {
+ if (value < begin[i])
+ r = i - 1;
+ else
+ l = i;
+ i = (l + r + 1) / 2;
+ }
+ if (begin[i] < value || value < begin[i])
+ return end;
+ else
+ return begin + i;
+}
+
+template <typename RandomAccessIterator, typename T, typename LessThan>
+Q_OUTOFLINE_TEMPLATE RandomAccessIterator qBinaryFind(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan)
+{
+ return QAlgorithmsPrivate::qBinaryFindHelper(begin, end, value, lessThan);
+}
+
+template <typename Container, typename T>
+Q_OUTOFLINE_TEMPLATE typename Container::const_iterator qBinaryFind(const Container &container, const T &value)
+{
+ return QAlgorithmsPrivate::qBinaryFindHelper(container.constBegin(), container.constEnd(), value, qLess<T>());
+}
+
+template <typename ForwardIterator>
+Q_OUTOFLINE_TEMPLATE void qDeleteAll(ForwardIterator begin, ForwardIterator end)
+{
+ while (begin != end) {
+ delete *begin;
+ ++begin;
+ }
+}
+
+template <typename Container>
+inline void qDeleteAll(const Container &c)
+{
+ qDeleteAll(c.begin(), c.end());
+}
+
+/*
+ Warning: The contents of QAlgorithmsPrivate is not a part of the public Qt API
+ and may be changed from version to version or even be completely removed.
+*/
+namespace QAlgorithmsPrivate {
+
+template <typename RandomAccessIterator, typename T, typename LessThan>
+Q_OUTOFLINE_TEMPLATE void qSortHelper(RandomAccessIterator start, RandomAccessIterator end, const T &t, LessThan lessThan)
+{
+top:
+ int span = end - start;
+ if (span < 2)
+ return;
+
+ --end;
+ RandomAccessIterator low = start, high = end - 1;
+ RandomAccessIterator pivot = start + span / 2;
+
+ if (lessThan(*end, *start))
+ qSwap(*end, *start);
+ if (span == 2)
+ return;
+
+ if (lessThan(*pivot, *start))
+ qSwap(*pivot, *start);
+ if (lessThan(*end, *pivot))
+ qSwap(*end, *pivot);
+ if (span == 3)
+ return;
+
+ qSwap(*pivot, *end);
+
+ while (low < high) {
+ while (low < high && lessThan(*low, *end))
+ ++low;
+
+ while (high > low && lessThan(*end, *high))
+ --high;
+
+ if (low < high) {
+ qSwap(*low, *high);
+ ++low;
+ --high;
+ } else {
+ break;
+ }
+ }
+
+ if (lessThan(*low, *end))
+ ++low;
+
+ qSwap(*end, *low);
+ qSortHelper(start, low, t, lessThan);
+
+ start = low + 1;
+ ++end;
+ goto top;
+}
+
+template <typename RandomAccessIterator, typename T>
+inline void qSortHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &dummy)
+{
+ qSortHelper(begin, end, dummy, qLess<T>());
+}
+
+template <typename RandomAccessIterator>
+Q_OUTOFLINE_TEMPLATE void qReverse(RandomAccessIterator begin, RandomAccessIterator end)
+{
+ --end;
+ while (begin < end)
+ qSwap(*begin++, *end--);
+}
+
+template <typename RandomAccessIterator>
+Q_OUTOFLINE_TEMPLATE void qRotate(RandomAccessIterator begin, RandomAccessIterator middle, RandomAccessIterator end)
+{
+ qReverse(begin, middle);
+ qReverse(middle, end);
+ qReverse(begin, end);
+}
+
+template <typename RandomAccessIterator, typename T, typename LessThan>
+Q_OUTOFLINE_TEMPLATE void qMerge(RandomAccessIterator begin, RandomAccessIterator pivot, RandomAccessIterator end, T &t, LessThan lessThan)
+{
+ const int len1 = pivot - begin;
+ const int len2 = end - pivot;
+
+ if (len1 == 0 || len2 == 0)
+ return;
+
+ if (len1 + len2 == 2) {
+ if (lessThan(*(begin + 1), *(begin)))
+ qSwap(*begin, *(begin + 1));
+ return;
+ }
+
+ RandomAccessIterator firstCut;
+ RandomAccessIterator secondCut;
+ int len2Half;
+ if (len1 > len2) {
+ const int len1Half = len1 / 2;
+ firstCut = begin + len1Half;
+ secondCut = qLowerBound(pivot, end, *firstCut, lessThan);
+ len2Half = secondCut - pivot;
+ } else {
+ len2Half = len2 / 2;
+ secondCut = pivot + len2Half;
+ firstCut = qUpperBound(begin, pivot, *secondCut, lessThan);
+ }
+
+ qRotate(firstCut, pivot, secondCut);
+ const RandomAccessIterator newPivot = firstCut + len2Half;
+ qMerge(begin, firstCut, newPivot, t, lessThan);
+ qMerge(newPivot, secondCut, end, t, lessThan);
+}
+
+template <typename RandomAccessIterator, typename T, typename LessThan>
+Q_OUTOFLINE_TEMPLATE void qStableSortHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &t, LessThan lessThan)
+{
+ const int span = end - begin;
+ if (span < 2)
+ return;
+
+ const RandomAccessIterator middle = begin + span / 2;
+ qStableSortHelper(begin, middle, t, lessThan);
+ qStableSortHelper(middle, end, t, lessThan);
+ qMerge(begin, middle, end, t, lessThan);
+}
+
+template <typename RandomAccessIterator, typename T>
+inline void qStableSortHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &dummy)
+{
+ qStableSortHelper(begin, end, dummy, qLess<T>());
+}
+
+template <typename RandomAccessIterator, typename T, typename LessThan>
+Q_OUTOFLINE_TEMPLATE RandomAccessIterator qLowerBoundHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan)
+{
+ RandomAccessIterator middle;
+ int n = end - begin;
+ int half;
+
+ while (n > 0) {
+ half = n >> 1;
+ middle = begin + half;
+ if (lessThan(*middle, value)) {
+ begin = middle + 1;
+ n -= half + 1;
+ } else {
+ n = half;
+ }
+ }
+ return begin;
+}
+
+
+template <typename RandomAccessIterator, typename T, typename LessThan>
+Q_OUTOFLINE_TEMPLATE RandomAccessIterator qUpperBoundHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan)
+{
+ RandomAccessIterator middle;
+ int n = end - begin;
+ int half;
+
+ while (n > 0) {
+ half = n >> 1;
+ middle = begin + half;
+ if (lessThan(value, *middle)) {
+ n = half;
+ } else {
+ begin = middle + 1;
+ n -= half + 1;
+ }
+ }
+ return begin;
+}
+
+template <typename RandomAccessIterator, typename T, typename LessThan>
+Q_OUTOFLINE_TEMPLATE RandomAccessIterator qBinaryFindHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan)
+{
+ qint64 l = 0;
+ qint64 r = end - begin - 1;
+ if (r < 0)
+ return end;
+ qint64 i = (l + r + 1) / 2;
+
+ while (r != l) {
+ if (lessThan(value, begin[i]))
+ r = i - 1;
+ else
+ l = i;
+ i = (l + r + 1) / 2;
+ }
+ if (lessThan(begin[i], value) || lessThan(value, begin[i]))
+ return end;
+ else
+ return begin + i;
+}
+
+} //namespace QAlgorithmsPrivate
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QALGORITHMS_H
diff --git a/src/corelib/tools/qbitarray.cpp b/src/corelib/tools/qbitarray.cpp
new file mode 100644
index 0000000000..a947ab53bc
--- /dev/null
+++ b/src/corelib/tools/qbitarray.cpp
@@ -0,0 +1,728 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qbitarray.h"
+#include <qdatastream.h>
+#include <qdebug.h>
+#include <string.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QBitArray
+ \brief The QBitArray class provides an array of bits.
+
+ \ingroup tools
+ \ingroup shared
+ \reentrant
+
+ A QBitArray is an array that gives access to individual bits and
+ provides operators (\link operator&() AND\endlink, \link
+ operator|() OR\endlink, \link operator^() XOR\endlink, and \link
+ operator~() NOT\endlink) that work on entire arrays of bits. It
+ uses \l{implicit sharing} (copy-on-write) to reduce memory usage
+ and to avoid the needless copying of data.
+
+ The following code constructs a QBitArray containing 200 bits
+ initialized to false (0):
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qbitarray.cpp 0
+
+ To initialize the bits to true, either pass \c true as second
+ argument to the constructor, or call fill() later on.
+
+ QBitArray uses 0-based indexes, just like C++ arrays. To access
+ the bit at a particular index position, you can use operator[]().
+ On non-const bit arrays, operator[]() returns a reference to a
+ bit that can be used on the left side of an assignment. For
+ example:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qbitarray.cpp 1
+
+ For technical reasons, it is more efficient to use testBit() and
+ setBit() to access bits in the array than operator[](). For
+ example:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qbitarray.cpp 2
+
+ QBitArray supports \c{&} (\link operator&() AND\endlink), \c{|}
+ (\link operator|() OR\endlink), \c{^} (\link operator^()
+ XOR\endlink), \c{~} (\link operator~() NOT\endlink), as well as
+ \c{&=}, \c{|=}, and \c{^=}. These operators work in the same way
+ as the built-in C++ bitwise operators of the same name. For
+ example:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qbitarray.cpp 3
+
+ For historical reasons, QBitArray distinguishes between a null
+ bit array and an empty bit array. A \e null bit array is a bit
+ array that is initialized using QBitArray's default constructor.
+ An \e empty bit array is any bit array with size 0. A null bit
+ array is always empty, but an empty bit array isn't necessarily
+ null:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qbitarray.cpp 4
+
+ All functions except isNull() treat null bit arrays the same as
+ empty bit arrays; for example, QBitArray() compares equal to
+ QBitArray(0). We recommend that you always use isEmpty() and
+ avoid isNull().
+
+ \sa QByteArray, QVector
+*/
+
+/*! \fn QBitArray::QBitArray()
+
+ Constructs an empty bit array.
+
+ \sa isEmpty()
+*/
+
+/*!
+ Constructs a bit array containing \a size bits. The bits are
+ initialized with \a value, which defaults to false (0).
+*/
+QBitArray::QBitArray(int size, bool value)
+{
+ if (!size) {
+ d.resize(0);
+ return;
+ }
+ d.resize(1 + (size+7)/8);
+ uchar* c = reinterpret_cast<uchar*>(d.data());
+ memset(c, value ? 0xff : 0, d.size());
+ *c = d.size()*8 - size;
+ if (value && size && size % 8)
+ *(c+1+size/8) &= (1 << (size%8)) - 1;
+}
+
+/*! \fn int QBitArray::size() const
+
+ Returns the number of bits stored in the bit array.
+
+ \sa resize()
+*/
+
+/*! \fn int QBitArray::count() const
+
+ Same as size().
+*/
+
+/*!
+ If \a on is true, this function returns the number of
+ 1-bits stored in the bit array; otherwise the number
+ of 0-bits is returned.
+*/
+int QBitArray::count(bool on) const
+{
+ int numBits = 0;
+ int len = size();
+#if 0
+ for (int i = 0; i < len; ++i)
+ numBits += testBit(i);
+#else
+ // See http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel
+ const quint8 *bits = reinterpret_cast<const quint8 *>(d.data()) + 1;
+ while (len >= 32) {
+ quint32 v = quint32(bits[0]) | (quint32(bits[1]) << 8) | (quint32(bits[2]) << 16) | (quint32(bits[3]) << 24);
+ quint32 c = ((v & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f;
+ c += (((v & 0xfff000) >> 12) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f;
+ c += ((v >> 24) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f;
+ len -= 32;
+ bits += 4;
+ numBits += int(c);
+ }
+ while (len >= 24) {
+ quint32 v = quint32(bits[0]) | (quint32(bits[1]) << 8) | (quint32(bits[2]) << 16);
+ quint32 c = ((v & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f;
+ c += (((v & 0xfff000) >> 12) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f;
+ len -= 24;
+ bits += 3;
+ numBits += int(c);
+ }
+ while (len >= 0) {
+ if (bits[len / 8] & (1 << ((len - 1) & 7)))
+ ++numBits;
+ --len;
+ }
+#endif
+ return on ? numBits : size() - numBits;
+}
+
+/*!
+ Resizes the bit array to \a size bits.
+
+ If \a size is greater than the current size, the bit array is
+ extended to make it \a size bits with the extra bits added to the
+ end. The new bits are initialized to false (0).
+
+ If \a size is less than the current size, bits are removed from
+ the end.
+
+ \sa size()
+*/
+void QBitArray::resize(int size)
+{
+ if (!size) {
+ d.resize(0);
+ } else {
+ int s = d.size();
+ d.resize(1 + (size+7)/8);
+ uchar* c = reinterpret_cast<uchar*>(d.data());
+ if (size > (s << 3))
+ memset(c + s, 0, d.size() - s);
+ *c = d.size()*8 - size;
+ }
+}
+
+/*! \fn bool QBitArray::isEmpty() const
+
+ Returns true if this bit array has size 0; otherwise returns
+ false.
+
+ \sa size()
+*/
+
+/*! \fn bool QBitArray::isNull() const
+
+ Returns true if this bit array is null; otherwise returns false.
+
+ Example:
+ \snippet doc/src/snippets/code/src_corelib_tools_qbitarray.cpp 5
+
+ Qt makes a distinction between null bit arrays and empty bit
+ arrays for historical reasons. For most applications, what
+ matters is whether or not a bit array contains any data,
+ and this can be determined using isEmpty().
+
+ \sa isEmpty()
+*/
+
+/*! \fn bool QBitArray::fill(bool value, int size = -1)
+
+ Sets every bit in the bit array to \a value, returning true if successful;
+ otherwise returns false. If \a size is different from -1 (the default),
+ the bit array is resized to \a size beforehand.
+
+ Example:
+ \snippet doc/src/snippets/code/src_corelib_tools_qbitarray.cpp 6
+
+ \sa resize()
+*/
+
+/*!
+ \overload
+
+ Sets bits at index positions \a begin up to and excluding \a end
+ to \a value.
+
+ \a begin and \a end must be a valid index position in the bit
+ array (i.e., 0 <= \a begin <= size() and 0 <= \a end <= size()).
+*/
+
+void QBitArray::fill(bool value, int begin, int end)
+{
+ while (begin < end && begin & 0x7)
+ setBit(begin++, value);
+ int len = end - begin;
+ if (len <= 0)
+ return;
+ int s = len & ~0x7;
+ uchar *c = reinterpret_cast<uchar*>(d.data());
+ memset(c + (begin >> 3) + 1, value ? 0xff : 0, s >> 3);
+ begin += s;
+ while (begin < end)
+ setBit(begin++, value);
+}
+
+/*! \fn bool QBitArray::isDetached() const
+
+ \internal
+*/
+
+/*! \fn void QBitArray::detach()
+
+ \internal
+*/
+
+/*! \fn void QBitArray::clear()
+
+ Clears the contents of the bit array and makes it empty.
+
+ \sa resize(), isEmpty()
+*/
+
+/*! \fn void QBitArray::truncate(int pos)
+
+ Truncates the bit array at index position \a pos.
+
+ If \a pos is beyond the end of the array, nothing happens.
+
+ \sa resize()
+*/
+
+/*! \fn bool QBitArray::toggleBit(int i)
+
+ Inverts the value of the bit at index position \a i, returning the
+ previous value of that bit as either true (if it was set) or false (if
+ it was unset).
+
+ If the previous value was 0, the new value will be 1. If the
+ previous value was 1, the new value will be 0.
+
+ \a i must be a valid index position in the bit array (i.e., 0 <=
+ \a i < size()).
+
+ \sa setBit(), clearBit()
+*/
+
+/*! \fn bool QBitArray::testBit(int i) const
+
+ Returns true if the bit at index position \a i is 1; otherwise
+ returns false.
+
+ \a i must be a valid index position in the bit array (i.e., 0 <=
+ \a i < size()).
+
+ \sa setBit(), clearBit()
+*/
+
+/*! \fn bool QBitArray::setBit(int i)
+
+ Sets the bit at index position \a i to 1.
+
+ \a i must be a valid index position in the bit array (i.e., 0 <=
+ \a i < size()).
+
+ \sa clearBit(), toggleBit()
+*/
+
+/*! \fn void QBitArray::setBit(int i, bool value)
+
+ \overload
+
+ Sets the bit at index position \a i to \a value.
+*/
+
+/*! \fn void QBitArray::clearBit(int i)
+
+ Sets the bit at index position \a i to 0.
+
+ \a i must be a valid index position in the bit array (i.e., 0 <=
+ \a i < size()).
+
+ \sa setBit(), toggleBit()
+*/
+
+/*! \fn bool QBitArray::at(int i) const
+
+ Returns the value of the bit at index position \a i.
+
+ \a i must be a valid index position in the bit array (i.e., 0 <=
+ \a i < size()).
+
+ \sa operator[]()
+*/
+
+/*! \fn QBitRef QBitArray::operator[](int i)
+
+ Returns the bit at index position \a i as a modifiable reference.
+
+ \a i must be a valid index position in the bit array (i.e., 0 <=
+ \a i < size()).
+
+ Example:
+ \snippet doc/src/snippets/code/src_corelib_tools_qbitarray.cpp 7
+
+ The return value is of type QBitRef, a helper class for QBitArray.
+ When you get an object of type QBitRef, you can assign to
+ it, and the assignment will apply to the bit in the QBitArray
+ from which you got the reference.
+
+ The functions testBit(), setBit(), and clearBit() are slightly
+ faster.
+
+ \sa at(), testBit(), setBit(), clearBit()
+*/
+
+/*! \fn bool QBitArray::operator[](int i) const
+
+ \overload
+*/
+
+/*! \fn bool QBitArray::operator[](uint i)
+
+ \overload
+*/
+
+/*! \fn bool QBitArray::operator[](uint i) const
+
+ \overload
+*/
+
+/*! \fn QBitArray::QBitArray(const QBitArray &other)
+
+ Constructs a copy of \a other.
+
+ This operation takes \l{constant time}, because QBitArray is
+ \l{implicitly shared}. This makes returning a QBitArray from a
+ function very fast. If a shared instance is modified, it will be
+ copied (copy-on-write), and that takes \l{linear time}.
+
+ \sa operator=()
+*/
+
+/*! \fn QBitArray &QBitArray::operator=(const QBitArray &other)
+
+ Assigns \a other to this bit array and returns a reference to
+ this bit array.
+*/
+
+/*! \fn bool QBitArray::operator==(const QBitArray &other) const
+
+ Returns true if \a other is equal to this bit array; otherwise
+ returns false.
+
+ \sa operator!=()
+*/
+
+/*! \fn bool QBitArray::operator!=(const QBitArray &other) const
+
+ Returns true if \a other is not equal to this bit array;
+ otherwise returns false.
+
+ \sa operator==()
+*/
+
+/*!
+ Performs the AND operation between all bits in this bit array and
+ \a other. Assigns the result to this bit array, and returns a
+ reference to it.
+
+ The result has the length of the longest of the two bit arrays,
+ with any missing bits (if one array is shorter than the other)
+ taken to be 0.
+
+ Example:
+ \snippet doc/src/snippets/code/src_corelib_tools_qbitarray.cpp 8
+
+ \sa operator&(), operator|=(), operator^=(), operator~()
+*/
+
+QBitArray &QBitArray::operator&=(const QBitArray &other)
+{
+ resize(qMax(size(), other.size()));
+ uchar *a1 = reinterpret_cast<uchar*>(d.data()) + 1;
+ const uchar *a2 = reinterpret_cast<const uchar*>(other.d.constData()) + 1;
+ int n = other.d.size() -1 ;
+ int p = d.size() - 1 - n;
+ while (n-- > 0)
+ *a1++ &= *a2++;
+ while (p-- > 0)
+ *a1++ = 0;
+ return *this;
+}
+
+/*!
+ Performs the OR operation between all bits in this bit array and
+ \a other. Assigns the result to this bit array, and returns a
+ reference to it.
+
+ The result has the length of the longest of the two bit arrays,
+ with any missing bits (if one array is shorter than the other)
+ taken to be 0.
+
+ Example:
+ \snippet doc/src/snippets/code/src_corelib_tools_qbitarray.cpp 9
+
+ \sa operator|(), operator&=(), operator^=(), operator~()
+*/
+
+QBitArray &QBitArray::operator|=(const QBitArray &other)
+{
+ resize(qMax(size(), other.size()));
+ uchar *a1 = reinterpret_cast<uchar*>(d.data()) + 1;
+ const uchar *a2 = reinterpret_cast<const uchar *>(other.d.constData()) + 1;
+ int n = other.d.size() - 1;
+ while (n-- > 0)
+ *a1++ |= *a2++;
+ return *this;
+}
+
+/*!
+ Performs the XOR operation between all bits in this bit array and
+ \a other. Assigns the result to this bit array, and returns a
+ reference to it.
+
+ The result has the length of the longest of the two bit arrays,
+ with any missing bits (if one array is shorter than the other)
+ taken to be 0.
+
+ Example:
+ \snippet doc/src/snippets/code/src_corelib_tools_qbitarray.cpp 10
+
+ \sa operator^(), operator&=(), operator|=(), operator~()
+*/
+
+QBitArray &QBitArray::operator^=(const QBitArray &other)
+{
+ resize(qMax(size(), other.size()));
+ uchar *a1 = reinterpret_cast<uchar*>(d.data()) + 1;
+ const uchar *a2 = reinterpret_cast<const uchar *>(other.d.constData()) + 1;
+ int n = other.d.size() - 1;
+ while (n-- > 0)
+ *a1++ ^= *a2++;
+ return *this;
+}
+
+/*!
+ Returns a bit array that contains the inverted bits of this bit
+ array.
+
+ Example:
+ \snippet doc/src/snippets/code/src_corelib_tools_qbitarray.cpp 11
+
+ \sa operator&(), operator|(), operator^()
+*/
+
+QBitArray QBitArray::operator~() const
+{
+ int sz = size();
+ QBitArray a(sz);
+ const uchar *a1 = reinterpret_cast<const uchar *>(d.constData()) + 1;
+ uchar *a2 = reinterpret_cast<uchar*>(a.d.data()) + 1;
+ int n = d.size() - 1;
+
+ while (n-- > 0)
+ *a2++ = ~*a1++;
+
+ if (sz && sz%8)
+ *(a2-1) &= (1 << (sz%8)) - 1;
+ return a;
+}
+
+/*!
+ \relates QBitArray
+
+ Returns a bit array that is the AND of the bit arrays \a a1 and \a
+ a2.
+
+ The result has the length of the longest of the two bit arrays,
+ with any missing bits (if one array is shorter than the other)
+ taken to be 0.
+
+ Example:
+ \snippet doc/src/snippets/code/src_corelib_tools_qbitarray.cpp 12
+
+ \sa QBitArray::operator&=(), operator|(), operator^()
+*/
+
+QBitArray operator&(const QBitArray &a1, const QBitArray &a2)
+{
+ QBitArray tmp = a1;
+ tmp &= a2;
+ return tmp;
+}
+
+/*!
+ \relates QBitArray
+
+ Returns a bit array that is the OR of the bit arrays \a a1 and \a
+ a2.
+
+ The result has the length of the longest of the two bit arrays,
+ with any missing bits (if one array is shorter than the other)
+ taken to be 0.
+
+ Example:
+ \snippet doc/src/snippets/code/src_corelib_tools_qbitarray.cpp 13
+
+ \sa QBitArray::operator|=(), operator&(), operator^()
+*/
+
+QBitArray operator|(const QBitArray &a1, const QBitArray &a2)
+{
+ QBitArray tmp = a1;
+ tmp |= a2;
+ return tmp;
+}
+
+/*!
+ \relates QBitArray
+
+ Returns a bit array that is the XOR of the bit arrays \a a1 and \a
+ a2.
+
+ The result has the length of the longest of the two bit arrays,
+ with any missing bits (if one array is shorter than the other)
+ taken to be 0.
+
+ Example:
+ \snippet doc/src/snippets/code/src_corelib_tools_qbitarray.cpp 14
+
+ \sa QBitArray::operator^=(), operator&(), operator|()
+*/
+
+QBitArray operator^(const QBitArray &a1, const QBitArray &a2)
+{
+ QBitArray tmp = a1;
+ tmp ^= a2;
+ return tmp;
+}
+
+/*!
+ \class QBitRef
+ \reentrant
+ \brief The QBitRef class is an internal class, used with QBitArray.
+
+ \internal
+
+ The QBitRef is required by the indexing [] operator on bit arrays.
+ It is not for use in any other context.
+*/
+
+/*! \fn QBitRef::QBitRef (QBitArray& a, int i)
+
+ Constructs a reference to element \a i in the QBitArray \a a.
+ This is what QBitArray::operator[] constructs its return value
+ with.
+*/
+
+/*! \fn QBitRef::operator bool() const
+
+ Returns the value referenced by the QBitRef.
+*/
+
+/*! \fn bool QBitRef::operator!() const
+
+ \internal
+*/
+
+/*! \fn QBitRef& QBitRef::operator= (const QBitRef& v)
+
+ Sets the value referenced by the QBitRef to that referenced by
+ QBitRef \a v.
+*/
+
+/*! \fn QBitRef& QBitRef::operator= (bool v)
+ \overload
+
+ Sets the value referenced by the QBitRef to \a v.
+*/
+
+
+/*****************************************************************************
+ QBitArray stream functions
+ *****************************************************************************/
+
+/*!
+ \relates QBitArray
+
+ Writes bit array \a ba to stream \a out.
+
+ \sa \link datastreamformat.html Format of the QDataStream operators \endlink
+*/
+#ifndef QT_NO_DATASTREAM
+QDataStream &operator<<(QDataStream &out, const QBitArray &ba)
+{
+ quint32 len = ba.size();
+ out << len;
+ if (len > 0)
+ out.writeRawData(ba.d.constData() + 1, ba.d.size() - 1);
+ return out;
+}
+
+/*!
+ \relates QBitArray
+
+ Reads a bit array into \a ba from stream \a in.
+
+ \sa \link datastreamformat.html Format of the QDataStream operators \endlink
+*/
+
+QDataStream &operator>>(QDataStream &in, QBitArray &ba)
+{
+ ba.clear();
+ quint32 len;
+ in >> len;
+ if (len == 0) {
+ ba.clear();
+ return in;
+ }
+
+ const quint32 Step = 8 * 1024 * 1024;
+ quint32 totalBytes = (len + 7) / 8;
+ quint32 allocated = 0;
+
+ while (allocated < totalBytes) {
+ int blockSize = qMin(Step, totalBytes - allocated);
+ ba.d.resize(allocated + blockSize + 1);
+ if (in.readRawData(ba.d.data() + 1 + allocated, blockSize) != blockSize) {
+ ba.clear();
+ in.setStatus(QDataStream::ReadPastEnd);
+ return in;
+ }
+ allocated += blockSize;
+ }
+
+ int paddingMask = ~((0x1 << (len & 0x7)) - 1);
+ if (paddingMask != ~0x0 && (ba.d.constData()[ba.d.size() - 1] & paddingMask)) {
+ ba.clear();
+ in.setStatus(QDataStream::ReadCorruptData);
+ return in;
+ }
+
+ *ba.d.data() = ba.d.size() * 8 - len;
+ return in;
+}
+#endif
+
+/*!
+ \fn DataPtr &QBitArray::data_ptr()
+ \internal
+*/
+
+/*!
+ \typedef QBitArray::DataPtr
+ \internal
+*/
+
+QT_END_NAMESPACE
diff --git a/src/corelib/tools/qbitarray.h b/src/corelib/tools/qbitarray.h
new file mode 100644
index 0000000000..d754b0717d
--- /dev/null
+++ b/src/corelib/tools/qbitarray.h
@@ -0,0 +1,174 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QBITARRAY_H
+#define QBITARRAY_H
+
+#include <QtCore/qbytearray.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Core)
+
+class QBitRef;
+class Q_CORE_EXPORT QBitArray
+{
+ friend Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QBitArray &);
+ friend Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QBitArray &);
+ friend Q_CORE_EXPORT uint qHash(const QBitArray &key);
+ QByteArray d;
+
+public:
+ inline QBitArray() {}
+ explicit QBitArray(int size, bool val = false);
+ QBitArray(const QBitArray &other) : d(other.d) {}
+ inline QBitArray &operator=(const QBitArray &other) { d = other.d; return *this; }
+
+ inline int size() const { return (d.size() << 3) - *d.constData(); }
+ inline int count() const { return (d.size() << 3) - *d.constData(); }
+ int count(bool on) const;
+ // ### Qt 5: Store the number of set bits separately
+
+ inline bool isEmpty() const { return d.isEmpty(); }
+ inline bool isNull() const { return d.isNull(); }
+
+ void resize(int size);
+
+ inline void detach() { d.detach(); }
+ inline bool isDetached() const { return d.isDetached(); }
+ inline void clear() { d.clear(); }
+
+ bool testBit(int i) const;
+ void setBit(int i);
+ void setBit(int i, bool val);
+ void clearBit(int i);
+ bool toggleBit(int i);
+
+ bool at(int i) const;
+ QBitRef operator[](int i);
+ bool operator[](int i) const;
+ QBitRef operator[](uint i);
+ bool operator[](uint i) const;
+
+ QBitArray& operator&=(const QBitArray &);
+ QBitArray& operator|=(const QBitArray &);
+ QBitArray& operator^=(const QBitArray &);
+ QBitArray operator~() const;
+
+ inline bool operator==(const QBitArray& a) const { return d == a.d; }
+ inline bool operator!=(const QBitArray& a) const { return d != a.d; }
+
+ inline bool fill(bool val, int size = -1);
+ void fill(bool val, int first, int last);
+
+ inline void truncate(int pos) { if (pos < size()) resize(pos); }
+
+public:
+ typedef QByteArray::DataPtr DataPtr;
+ inline DataPtr &data_ptr() { return d.data_ptr(); }
+};
+
+inline bool QBitArray::fill(bool aval, int asize)
+{ *this = QBitArray((asize < 0 ? this->size() : asize), aval); return true; }
+
+Q_CORE_EXPORT QBitArray operator&(const QBitArray &, const QBitArray &);
+Q_CORE_EXPORT QBitArray operator|(const QBitArray &, const QBitArray &);
+Q_CORE_EXPORT QBitArray operator^(const QBitArray &, const QBitArray &);
+
+inline bool QBitArray::testBit(int i) const
+{ Q_ASSERT(i >= 0 && i < size());
+ return (*(reinterpret_cast<const uchar*>(d.constData())+1+(i>>3)) & (1 << (i & 7))) != 0; }
+
+inline void QBitArray::setBit(int i)
+{ Q_ASSERT(i >= 0 && i < size());
+ *(reinterpret_cast<uchar*>(d.data())+1+(i>>3)) |= (1 << (i & 7)); }
+
+inline void QBitArray::clearBit(int i)
+{ Q_ASSERT(i >= 0 && i < size());
+ *(reinterpret_cast<uchar*>(d.data())+1+(i>>3)) &= ~(1 << (i & 7)); }
+
+inline void QBitArray::setBit(int i, bool val)
+{ if (val) setBit(i); else clearBit(i); }
+
+inline bool QBitArray::toggleBit(int i)
+{ Q_ASSERT(i >= 0 && i < size());
+ uchar b = 1<< (i&7); uchar* p = reinterpret_cast<uchar*>(d.data())+1+(i>>3);
+ uchar c = *p&b; *p^=b; return c!=0; }
+
+inline bool QBitArray::operator[](int i) const { return testBit(i); }
+inline bool QBitArray::operator[](uint i) const { return testBit(i); }
+inline bool QBitArray::at(int i) const { return testBit(i); }
+
+class Q_CORE_EXPORT QBitRef
+{
+private:
+ QBitArray& a;
+ int i;
+ inline QBitRef(QBitArray& array, int idx) : a(array), i(idx) {}
+ friend class QBitArray;
+public:
+ inline operator bool() const { return a.testBit(i); }
+ inline bool operator!() const { return !a.testBit(i); }
+ QBitRef& operator=(const QBitRef& val) { a.setBit(i, val); return *this; }
+ QBitRef& operator=(bool val) { a.setBit(i, val); return *this; }
+};
+
+inline QBitRef QBitArray::operator[](int i)
+{ Q_ASSERT(i >= 0); return QBitRef(*this, i); }
+inline QBitRef QBitArray::operator[](uint i)
+{ return QBitRef(*this, i); }
+
+
+#ifndef QT_NO_DATASTREAM
+Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QBitArray &);
+Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QBitArray &);
+#endif
+
+Q_DECLARE_TYPEINFO(QBitArray, Q_MOVABLE_TYPE);
+Q_DECLARE_SHARED(QBitArray)
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QBITARRAY_H
diff --git a/src/corelib/tools/qbytearray.cpp b/src/corelib/tools/qbytearray.cpp
new file mode 100644
index 0000000000..6aa35f3414
--- /dev/null
+++ b/src/corelib/tools/qbytearray.cpp
@@ -0,0 +1,4240 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qbytearray.h"
+#include "qbytearraymatcher.h"
+#include "qtools_p.h"
+#include "qstring.h"
+#include "qlist.h"
+#include "qlocale.h"
+#include "qlocale_p.h"
+#include "qunicodetables_p.h"
+#ifndef QT_NO_DATASTREAM
+#include <qdatastream.h>
+#endif
+
+#ifndef QT_NO_COMPRESS
+#include <zlib.h>
+#endif
+#include <ctype.h>
+#include <limits.h>
+#include <string.h>
+#include <stdlib.h>
+
+#define IS_RAW_DATA(d) ((d)->data != (d)->array)
+
+QT_BEGIN_NAMESPACE
+
+
+int qFindByteArray(
+ const char *haystack0, int haystackLen, int from,
+ const char *needle0, int needleLen);
+
+
+int qAllocMore(int alloc, int extra)
+{
+ if (alloc == 0 && extra == 0)
+ return 0;
+ const int page = 1 << 12;
+ int nalloc;
+ alloc += extra;
+ if (alloc < 1<<6) {
+ nalloc = (1<<3) + ((alloc >>3) << 3);
+ } else {
+ // don't do anything if the loop will overflow signed int.
+ if (alloc >= INT_MAX/2)
+ return INT_MAX;
+ nalloc = (alloc < page) ? 1 << 3 : page;
+ while (nalloc < alloc) {
+ if (nalloc <= 0)
+ return INT_MAX;
+ nalloc *= 2;
+ }
+ }
+ return nalloc - extra;
+}
+
+/*****************************************************************************
+ 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 0, it immediately returns 0.
+
+ Ownership is passed to the caller, so the returned string must be
+ deleted using \c delete[].
+*/
+
+char *qstrdup(const char *src)
+{
+ if (!src)
+ return 0;
+ 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 0,
+ it immediately returns 0.
+
+ This function assumes that \a dst is large enough to hold the
+ contents of \a src.
+
+ \sa qstrncpy()
+*/
+
+char *qstrcpy(char *dst, const char *src)
+{
+ if (!src)
+ return 0;
+#if defined(_MSC_VER) && _MSC_VER >= 1400
+ int len = qstrlen(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 0;
+#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 0, returns 0 immediately.
+
+ This function assumes that \a dst is at least \a len characters
+ long.
+
+ \sa qstrcpy()
+*/
+
+char *qstrncpy(char *dst, const char *src, uint len)
+{
+ if (!src || !dst)
+ return 0;
+#if defined(_MSC_VER) && _MSC_VER >= 1400
+ strncpy_s(dst, len, src, len-1);
+#else
+ strncpy(dst, src, len);
+#endif
+ if (len > 0)
+ 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 0.
+
+ \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 0, 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 0.
+
+ Special case 2: Returns an arbitrary non-zero value if \a str1 is 0
+ or \a str2 is 0 (but not both).
+
+ \sa qstrncmp(), qstricmp(), qstrnicmp(), {8-bit Character Comparisons}
+*/
+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 0.
+
+ Special case 2: Returns a random non-zero value if \a str1 is 0
+ or \a str2 is 0 (but not both).
+
+ \sa qstrcmp(), qstricmp(), qstrnicmp(), {8-bit Character Comparisons}
+*/
+
+/*! \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 0.
+
+ Special case 2: Returns a random non-zero value if \a str1 is 0
+ or \a str2 is 0 (but not both).
+
+ \sa qstrcmp(), qstrncmp(), qstrnicmp(), {8-bit Character Comparisons}
+*/
+
+int qstricmp(const char *str1, const char *str2)
+{
+ register const uchar *s1 = reinterpret_cast<const uchar *>(str1);
+ register const uchar *s2 = reinterpret_cast<const uchar *>(str2);
+ int res;
+ uchar c;
+ if (!s1 || !s2)
+ return s1 ? 1 : (s2 ? -1 : 0);
+ for (; !(res = (c = QChar::toLower((ushort)*s1)) - QChar::toLower((ushort)*s2)); s1++, s2++)
+ if (!c) // strings are equal
+ break;
+ return res;
+}
+
+/*! \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 0.
+
+ Special case 2: Returns a random non-zero value if \a str1 is 0
+ or \a str2 is 0 (but not both).
+
+ \sa qstrcmp(), qstrncmp(), qstricmp(), {8-bit Character Comparisons}
+*/
+
+int qstrnicmp(const char *str1, const char *str2, uint len)
+{
+ register const uchar *s1 = reinterpret_cast<const uchar *>(str1);
+ register 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 = QChar::toLower((ushort)*s1)) - QChar::toLower((ushort)*s2)))
+ return res;
+ if (!c) // strings are equal
+ break;
+ }
+ return 0;
+}
+
+/*!
+ \internal
+ */
+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) {
+ register 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
+ */
+int qstrcmp(const QByteArray &str1, const QByteArray &str2)
+{
+ int l1 = str1.length();
+ int l2 = str2.length();
+ int ret = memcmp(str1, str2, 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
+{
+ register unsigned int i;
+ register 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).
+
+ \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)
+{
+ register quint16 crc = 0xffff;
+ 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)];
+ }
+ 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 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, (uchar*)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.
+
+ \bold{Note:} If you want to use this function to uncompress external
+ data compressed using zlib, you first need to prepend four bytes to the
+ byte array that contain the expected length (as an unsigned integer)
+ of the uncompressed data encoded in big-endian order (most significant
+ byte first).
+
+ \sa qCompress()
+*/
+
+/*! \relates QByteArray
+
+ \overload
+
+ Uncompresses the first \a nbytes of \a data and returns a new byte
+ array with the uncompressed data.
+*/
+
+#ifndef QT_NO_COMPRESS
+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 = (data[0] << 24) | (data[1] << 16) |
+ (data[2] << 8) | (data[3] );
+ ulong len = qMax(expectedSize, 1ul);
+ QByteArray baunzip;
+ int res;
+ do {
+ baunzip.resize(len);
+ res = ::uncompress((uchar*)baunzip.data(), &len,
+ (uchar*)data+4, nbytes-4);
+
+ switch (res) {
+ case Z_OK:
+ if ((int)len != baunzip.size())
+ baunzip.resize(len);
+ break;
+ case Z_MEM_ERROR:
+ qWarning("qUncompress: Z_MEM_ERROR: Not enough memory");
+ break;
+ case Z_BUF_ERROR:
+ len *= 2;
+ break;
+ case Z_DATA_ERROR:
+ qWarning("qUncompress: Z_DATA_ERROR: Input data is corrupted");
+ break;
+ }
+ } while (res == Z_BUF_ERROR);
+
+ if (res != Z_OK)
+ baunzip = QByteArray();
+
+ return baunzip;
+}
+#endif
+
+static inline bool qIsUpper(char c)
+{
+ return c >= 'A' && c <= 'Z';
+}
+
+static inline char qToLower(char c)
+{
+ if (c >= 'A' && c <= 'Z')
+ return c - 'A' + 'a';
+ else
+ return c;
+}
+
+Q_CORE_EXPORT QByteArray::Data QByteArray::shared_null = {Q_BASIC_ATOMIC_INITIALIZER(1),
+ 0, 0, shared_null.array, {0} };
+QByteArray::Data QByteArray::shared_empty = { Q_BASIC_ATOMIC_INITIALIZER(1),
+ 0, 0, shared_empty.array, {0} };
+
+/*!
+ \class QByteArray
+ \brief The QByteArray class provides an array of bytes.
+
+ \ingroup tools
+ \ingroup shared
+ \ingroup text
+ \mainclass
+ \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 doc/src/snippets/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 doc/src/snippets/code/src_corelib_tools_qbytearray.cpp 1
+
+ For read-only access, an alternative syntax is to use at():
+
+ \snippet doc/src/snippets/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. 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. 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 doc/src/snippets/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 doc/src/snippets/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.
+
+ QByteArrays 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 doc/src/snippets/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 pointer to a
+ '\\0' character for a null byte array (\e not a null pointer),
+ and QByteArray() compares equal to QByteArray(""). We recommend
+ that you always use isEmpty() and avoid isNull().
+
+ \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>=(), toLower() and toUpper().
+
+ This issue does not apply to QStrings since they represent
+ characters using Unicode.
+
+ \sa QString, QBitArray
+*/
+
+/*! \fn QByteArray::iterator QByteArray::begin()
+
+ \internal
+*/
+
+/*! \fn QByteArray::const_iterator QByteArray::begin() const
+
+ \internal
+*/
+
+/*! \fn QByteArray::const_iterator QByteArray::constBegin() const
+
+ \internal
+*/
+
+/*! \fn QByteArray::iterator QByteArray::end()
+
+ \internal
+*/
+
+/*! \fn QByteArray::const_iterator QByteArray::end() const
+
+ \internal
+*/
+
+/*! \fn QByteArray::const_iterator QByteArray::constEnd() const
+
+ \internal
+*/
+
+/*! \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 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), and that takes \l{linear time}.
+
+ \sa operator=()
+*/
+
+/*! \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)
+{
+ other.d->ref.ref();
+ if (!d->ref.deref())
+ qFree(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 = &shared_null;
+ } else if (!*str) {
+ x = &shared_empty;
+ } else {
+ int len = qstrlen(str);
+ if (d->ref != 1 || len > d->alloc || (len < d->size && len < d->alloc >> 1))
+ realloc(len);
+ x = d;
+ memcpy(x->data, str, len + 1); // include null terminator
+ x->size = len;
+ }
+ x->ref.ref();
+ if (!d->ref.deref())
+ qFree(d);
+ d = x;
+ return *this;
+}
+
+/*! \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.
+
+ Example:
+ \snippet doc/src/snippets/code/src_corelib_tools_qbytearray.cpp 6
+
+ \sa isEmpty(), resize()
+*/
+
+/*! \fn bool QByteArray::isEmpty() const
+
+ Returns true if the byte array has size 0; otherwise returns false.
+
+ Example:
+ \snippet doc/src/snippets/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
+
+ 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.
+
+ Example:
+ \snippet doc/src/snippets/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 *}.
+
+ 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. 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[]()
+*/
+
+/*! \fn void QByteArray::detach()
+
+ \internal
+*/
+
+/*! \fn bool QByteArray::isDetached() 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 doc/src/snippets/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.
+
+ \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 QBool QByteArray::contains(const QByteArray &ba) const
+
+ Returns true if the byte array contains an occurrence of the byte
+ array \a ba; otherwise returns false.
+
+ \sa indexOf(), count()
+*/
+
+/*! \fn QBool QByteArray::contains(const char *str) const
+
+ \overload
+
+ Returns true if the byte array contains the string \a str;
+ otherwise returns false.
+*/
+
+/*! \fn QBool QByteArray::contains(char ch) const
+
+ \overload
+
+ Returns true if the byte array contains the character \a ch;
+ otherwise returns false.
+*/
+
+/*!
+
+ Truncates the byte array at index position \a pos.
+
+ If \a pos is beyond the end of the array, nothing happens.
+
+ Example:
+ \snippet doc/src/snippets/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 doc/src/snippets/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 doc/src/snippets/code/src_corelib_tools_qbytearray.cpp 12
+
+ This operation is typically very fast (\l{constant time}),
+ because QByteArray preallocates extra space at the end of the
+ character data so it can grow without reallocating the entire
+ data each time.
+
+ \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::toAscii().
+
+ If the QString contains non-ASCII Unicode characters, using this
+ operator can lead to loss of information. You can disable this
+ operator by defining \c QT_NO_CAST_TO_ASCII when you compile your
+ applications. You then need to call QString::toAscii() (or
+ QString::toLatin1() or QString::toUtf8() 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 true if this byte array is null; otherwise returns false.
+
+ Example:
+ \snippet doc/src/snippets/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()
+*/
+
+/*! \fn QByteArray::QByteArray(const char *str)
+
+ Constructs a byte array initialized with the string \a str.
+
+ QByteArray makes a deep copy of the string data.
+*/
+
+QByteArray::QByteArray(const char *str)
+{
+ if (!str) {
+ d = &shared_null;
+ } else if (!*str) {
+ d = &shared_empty;
+ } else {
+ int len = qstrlen(str);
+ d = static_cast<Data *>(qMalloc(sizeof(Data)+len));
+ if (!d) {
+ d = &shared_null;
+ } else {
+ d->ref = 0;;
+ d->alloc = d->size = len;
+ d->data = d->array;
+ memcpy(d->array, str, len+1); // include null terminator
+ }
+ }
+ d->ref.ref();
+}
+
+/*!
+ 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.
+
+ QByteArray makes a deep copy of the string data.
+
+ \sa fromRawData()
+*/
+
+QByteArray::QByteArray(const char *data, int size)
+{
+ if (!data) {
+ d = &shared_null;
+ } else if (size <= 0) {
+ d = &shared_empty;
+ } else {
+ d = static_cast<Data *>(qMalloc(sizeof(Data) + size));
+ if (!d) {
+ d = &shared_null;
+ } else {
+ d->ref = 0;
+ d->alloc = d->size = size;
+ d->data = d->array;
+ memcpy(d->array, data, size);
+ d->array[size] = '\0';
+ }
+ }
+ d->ref.ref();
+}
+
+/*!
+ 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 = &shared_null;
+ } else {
+ d = static_cast<Data *>(qMalloc(sizeof(Data)+size));
+ if (!d) {
+ d = &shared_null;
+ } else {
+ d->ref = 0;
+ d->alloc = d->size = size;
+ d->data = d->array;
+ d->array[size] = '\0';
+ memset(d->array, ch, size);
+ }
+ }
+ d->ref.ref();
+}
+
+/*!
+ 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()
+*/
+
+void QByteArray::resize(int size)
+{
+ if (size <= 0) {
+ Data *x = &shared_empty;
+ x->ref.ref();
+ if (!d->ref.deref())
+ qFree(d);
+ d = x;
+ } else if (d == &shared_null) {
+ //
+ // Optimize the idiom:
+ // QByteArray a;
+ // a.resize(sz);
+ // ...
+ // which is used in place of the Qt 3 idiom:
+ // QByteArray a(sz);
+ //
+ Data *x = static_cast<Data *>(qMalloc(sizeof(Data)+size));
+ if (!x)
+ return;
+ x->ref = 1;
+ x->alloc = x->size = size;
+ x->data = x->array;
+ x->array[size] = '\0';
+ (void) d->ref.deref(); // cannot be 0, x points to shared_null
+ d = x;
+ } else {
+ if (d->ref != 1 || size > d->alloc || (size < d->size && size < d->alloc >> 1))
+ realloc(qAllocMore(size, sizeof(Data)));
+ if (d->alloc >= size) {
+ d->size = size;
+ if (d->data == d->array) {
+ d->array[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 doc/src/snippets/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::realloc(int alloc)
+{
+ if (d->ref != 1 || d->data != d->array) {
+ Data *x = static_cast<Data *>(qMalloc(sizeof(Data) + alloc));
+ if (!x)
+ return;
+ x->size = qMin(alloc, d->size);
+ ::memcpy(x->array, d->data, x->size);
+ x->array[x->size] = '\0';
+ x->ref = 1;
+ x->alloc = alloc;
+ x->data = x->array;
+ if (!d->ref.deref())
+ qFree(d);
+ d = x;
+ } else {
+ Data *x = static_cast<Data *>(qRealloc(d, sizeof(Data) + alloc));
+ if (!x)
+ return;
+ x->alloc = alloc;
+ x->data = x->array;
+ d = x;
+ }
+}
+
+void QByteArray::expand(int i)
+{
+ resize(qMax(i + 1, d->size));
+}
+
+/*!
+ \internal
+ Return a QByteArray that is sure to be NUL-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 (d->data == d->array)
+ 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 doc/src/snippets/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 \e this is an empty QByteArray, then \e this will just share
+ the data held in \a ba. In this case, no copying of data is done.
+
+ \sa append(), insert()
+*/
+
+QByteArray &QByteArray::prepend(const QByteArray &ba)
+{
+ if ((d == &shared_null || d == &shared_empty) && !IS_RAW_DATA(ba.d)) {
+ *this = ba;
+ } else if (ba.d != &shared_null) {
+ 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)
+{
+ if (str) {
+ int len = qstrlen(str);
+ if (d->ref != 1 || d->size + len > d->alloc)
+ realloc(qAllocMore(d->size + len, sizeof(Data)));
+ memmove(d->data+len, d->data, d->size);
+ memcpy(d->data, str, len);
+ d->size += len;
+ d->data[d->size] = '\0';
+ }
+ return *this;
+}
+
+/*!
+ \overload
+
+ Prepends the character \a ch to this byte array.
+*/
+
+QByteArray &QByteArray::prepend(char ch)
+{
+ if (d->ref != 1 || d->size + 1 > d->alloc)
+ realloc(qAllocMore(d->size + 1, sizeof(Data)));
+ 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 doc/src/snippets/code/src_corelib_tools_qbytearray.cpp 16
+
+ This is the same as insert(size(), \a ba).
+
+ This operation is typically very fast (\l{constant time}),
+ because QByteArray preallocates extra space at the end of the
+ character data so it can grow without reallocating the entire
+ data each time.
+
+ Note: QByteArray is an \l{implicitly shared} class. Consequently,
+ if \e this is an empty QByteArray, then \e this will just share
+ the data held in \a ba. In this case, no copying of data is done.
+
+ \sa operator+=(), prepend(), insert()
+*/
+
+QByteArray &QByteArray::append(const QByteArray &ba)
+{
+ if ((d == &shared_null || d == &shared_empty) && !IS_RAW_DATA(ba.d)) {
+ *this = ba;
+ } else if (ba.d != &shared_null) {
+ if (d->ref != 1 || d->size + ba.d->size > d->alloc)
+ realloc(qAllocMore(d->size + ba.d->size, sizeof(Data)));
+ 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::toAscii().
+
+ If the QString contains non-ASCII Unicode characters, using this
+ function can lead to loss of information. You can disable this
+ function by defining \c QT_NO_CAST_TO_ASCII when you compile your
+ applications. You then need to call QString::toAscii() (or
+ QString::toLatin1() or QString::toUtf8() 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) {
+ int len = qstrlen(str);
+ if (d->ref != 1 || d->size + len > d->alloc)
+ realloc(qAllocMore(d->size + len, sizeof(Data)));
+ 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 the length of the
+ string is zero, nothing will be appended to the byte array.
+*/
+
+QByteArray &QByteArray::append(const char *str, int len)
+{
+ if (len < 0)
+ len = qstrlen(str);
+ if (str && len) {
+ if (d->ref != 1 || d->size + len > d->alloc)
+ realloc(qAllocMore(d->size + len, sizeof(Data)));
+ memcpy(d->data + d->size, str, len); // include null terminator
+ d->size += len;
+ d->data[d->size] = '\0';
+ }
+ return *this;
+}
+
+/*!
+ \overload
+
+ Appends the character \a ch to this byte array.
+*/
+
+QByteArray& QByteArray::append(char ch)
+{
+ if (d->ref != 1 || d->size + 1 > d->alloc)
+ realloc(qAllocMore(d->size + 1, sizeof(Data)));
+ 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 == 0)
+ 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 doc/src/snippets/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::toAscii().
+
+ If \a i is greater than size(), the array is first extended using
+ resize().
+
+ If the QString contains non-ASCII Unicode characters, using this
+ function can lead to loss of information. You can disable this
+ function by defining \c QT_NO_CAST_TO_ASCII when you compile your
+ applications. You then need to call QString::toAscii() (or
+ QString::toLatin1() or QString::toUtf8() 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
+
+ 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);
+}
+
+/*!
+ 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 doc/src/snippets/code/src_corelib_tools_qbytearray.cpp 18
+
+ \sa insert(), replace()
+*/
+
+QByteArray &QByteArray::remove(int pos, int len)
+{
+ if (len <= 0 || pos >= d->size || pos < 0)
+ return *this;
+ detach();
+ if (pos + len >= d->size) {
+ 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 doc/src/snippets/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);
+ // ### optimise me
+ remove(pos, len);
+ return insert(pos, copy);
+ }
+}
+
+/*! \fn QByteArray &QByteArray::replace(int pos, int len, const char *after)
+
+ \overload
+*/
+QByteArray &QByteArray::replace(int pos, int len, const char *after)
+{
+ int alen = qstrlen(after);
+ 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);
+ }
+}
+
+// ### optimise 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 doc/src/snippets/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 zero-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);
+ memcpy(copy, after, asize);
+ a = copy;
+ }
+ if (before >= d->data && before < d->data + d->size) {
+ char *copy = (char *)malloc(bsize);
+ 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((char *)a);
+ if (b != before)
+ ::free((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::toAscii().
+
+ If the QString contains non-ASCII Unicode characters, using this
+ function can lead to loss of information. You can disable this
+ function by defining \c QT_NO_CAST_TO_ASCII when you compile your
+ applications. You then need to call QString::toAscii() (or
+ QString::toLatin1() or QString::toUtf8() 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::toAscii().
+
+ If the QString contains non-ASCII Unicode characters, using this
+ function can lead to loss of information. You can disable this
+ function by defining \c QT_NO_CAST_TO_ASCII when you compile your
+ applications. You then need to call QString::toAscii() (or
+ QString::toLatin1() or QString::toUtf8() 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:
+
+ \code
+ QByteArray ba("ab");
+ ba.repeated(4); // returns "abababab"
+ \endcode
+*/
+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 != resultSize)
+ return QByteArray(); // not enough memory
+
+ qMemCopy(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) {
+ qMemCopy(end, result.d->data, sizeSoFar);
+ end += sizeSoFar;
+ sizeSoFar <<= 1;
+ }
+ qMemCopy(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 doc/src/snippets/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::toAscii().
+
+ If the QString contains non-ASCII Unicode characters, using this
+ function can lead to loss of information. You can disable this
+ function by defining \c QT_NO_CAST_TO_ASCII when you compile your
+ applications. You then need to call QString::toAscii() (or
+ QString::toLatin1() or QString::toUtf8() 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 doc/src/snippets/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 doc/src/snippets/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::toAscii().
+
+ If the QString contains non-ASCII Unicode characters, using this
+ function can lead to loss of information. You can disable this
+ function by defining \c QT_NO_CAST_TO_ASCII when you compile your
+ applications. You then need to call QString::toAscii() (or
+ QString::toLatin1() or QString::toUtf8() 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 doc/src/snippets/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().
+*/
+
+/*!
+ Returns true if this byte array starts with byte array \a ba;
+ otherwise returns false.
+
+ Example:
+ \snippet doc/src/snippets/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 true if this byte array starts with string \a str;
+ otherwise returns false.
+*/
+bool QByteArray::startsWith(const char *str) const
+{
+ if (!str || !*str)
+ return true;
+ int len = qstrlen(str);
+ if (d->size < len)
+ return false;
+ return qstrncmp(d->data, str, len) == 0;
+}
+
+/*! \overload
+
+ Returns true if this byte array starts with character \a ch;
+ otherwise returns false.
+*/
+bool QByteArray::startsWith(char ch) const
+{
+ if (d->size == 0)
+ return false;
+ return d->data[0] == ch;
+}
+
+/*!
+ Returns true if this byte array ends with byte array \a ba;
+ otherwise returns false.
+
+ Example:
+ \snippet doc/src/snippets/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 true if this byte array ends with string \a str; otherwise
+ returns false.
+*/
+bool QByteArray::endsWith(const char *str) const
+{
+ if (!str || !*str)
+ return true;
+ int len = qstrlen(str);
+ if (d->size < len)
+ return false;
+ return qstrncmp(d->data + d->size - len, str, len) == 0;
+}
+
+/*! \overload
+
+ Returns true if this byte array ends with character \a ch;
+ otherwise returns 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 doc/src/snippets/code/src_corelib_tools_qbytearray.cpp 27
+
+ \sa right(), mid(), startsWith(), 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 doc/src/snippets/code/src_corelib_tools_qbytearray.cpp 28
+
+ \sa endsWith(), left(), mid()
+*/
+
+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 doc/src/snippets/code/src_corelib_tools_qbytearray.cpp 29
+
+ \sa left(), right()
+*/
+
+QByteArray QByteArray::mid(int pos, int len) const
+{
+ if (d == &shared_null || d == &shared_empty || pos >= d->size)
+ return QByteArray();
+ if (len < 0)
+ len = d->size - pos;
+ if (pos < 0) {
+ len += pos;
+ pos = 0;
+ }
+ if (len + pos > d->size)
+ len = d->size - pos;
+ if (pos == 0 && len == d->size)
+ return *this;
+ return QByteArray(d->data + pos, len);
+}
+
+/*!
+ Returns a lowercase copy of the byte array. The bytearray is
+ interpreted as a Latin-1 encoded string.
+
+ Example:
+ \snippet doc/src/snippets/code/src_corelib_tools_qbytearray.cpp 30
+
+ \sa toUpper(), {8-bit Character Comparisons}
+*/
+QByteArray QByteArray::toLower() const
+{
+ QByteArray s(*this);
+ register uchar *p = reinterpret_cast<uchar *>(s.data());
+ if (p) {
+ while (*p) {
+ *p = QChar::toLower((ushort)*p);
+ p++;
+ }
+ }
+ return s;
+}
+
+/*!
+ Returns an uppercase copy of the byte array. The bytearray is
+ interpreted as a Latin-1 encoded string.
+
+ Example:
+ \snippet doc/src/snippets/code/src_corelib_tools_qbytearray.cpp 31
+
+ \sa toLower(), {8-bit Character Comparisons}
+*/
+
+QByteArray QByteArray::toUpper() const
+{
+ QByteArray s(*this);
+ register uchar *p = reinterpret_cast<uchar *>(s.data());
+ if (p) {
+ while (*p) {
+ *p = QChar::toUpper((ushort)*p);
+ p++;
+ }
+ }
+ return s;
+}
+
+/*! \fn void QByteArray::clear()
+
+ Clears the contents of the byte array and makes it empty.
+
+ \sa resize(), isEmpty()
+*/
+
+void QByteArray::clear()
+{
+ if (!d->ref.deref())
+ qFree(d);
+ d = &shared_null;
+ d->ref.ref();
+}
+
+/*! \relates QByteArray
+
+ Writes byte array \a ba to the stream \a out and returns a reference
+ to the stream.
+
+ \sa {Format of the QDataStream operators}
+*/
+#ifndef QT_NO_DATASTREAM
+
+QDataStream &operator<<(QDataStream &out, const QByteArray &ba)
+{
+ if (ba.isNull() && out.version() >= 6) {
+ out << (quint32)0xffffffff;
+ return out;
+ }
+ return out.writeBytes(ba, ba.size());
+}
+
+/*! \relates QByteArray
+
+ Reads a byte array into \a ba from the stream \a in and returns a
+ reference to the stream.
+
+ \sa {Format of the QDataStream operators}
+*/
+
+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 true if this byte array is equal to string \a str;
+ otherwise returns false.
+
+ The Unicode data is converted into 8-bit characters using
+ QString::toAscii().
+
+ 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::fromAscii(), QString::fromLatin1(),
+ QString::fromUtf8(), 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 true if this byte array is not equal to string \a str;
+ otherwise returns false.
+
+ The Unicode data is converted into 8-bit characters using
+ QString::toAscii().
+
+ 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::fromAscii(), QString::fromLatin1(),
+ QString::fromUtf8(), 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 true if this byte array is lexically less than string \a
+ str; otherwise returns false.
+
+ The Unicode data is converted into 8-bit characters using
+ QString::toAscii().
+
+ 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::fromAscii(), QString::fromLatin1(),
+ QString::fromUtf8(), 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 true if this byte array is lexically greater than string
+ \a str; otherwise returns false.
+
+ The Unicode data is converted into 8-bit characters using
+ QString::toAscii().
+
+ 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::fromAscii(), QString::fromLatin1(),
+ QString::fromUtf8(), 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 true if this byte array is lexically less than or equal
+ to string \a str; otherwise returns false.
+
+ The Unicode data is converted into 8-bit characters using
+ QString::toAscii().
+
+ 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::fromAscii(), QString::fromLatin1(),
+ QString::fromUtf8(), 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 true if this byte array is greater than or equal to string
+ \a str; otherwise returns false.
+
+ The Unicode data is converted into 8-bit characters using
+ QString::toAscii().
+
+ 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::fromAscii(), QString::fromLatin1(),
+ QString::fromUtf8(), 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 true if byte array \a a1 is equal to byte array \a a2;
+ otherwise returns false.
+*/
+
+/*! \fn bool operator==(const QByteArray &a1, const char *a2)
+ \relates QByteArray
+
+ \overload
+
+ Returns true if byte array \a a1 is equal to string \a a2;
+ otherwise returns false.
+*/
+
+/*! \fn bool operator==(const char *a1, const QByteArray &a2)
+ \relates QByteArray
+
+ \overload
+
+ Returns true if string \a a1 is equal to byte array \a a2;
+ otherwise returns false.
+*/
+
+/*! \fn bool operator!=(const QByteArray &a1, const QByteArray &a2)
+ \relates QByteArray
+
+ \overload
+
+ Returns true if byte array \a a1 is not equal to byte array \a a2;
+ otherwise returns false.
+*/
+
+/*! \fn bool operator!=(const QByteArray &a1, const char *a2)
+ \relates QByteArray
+
+ \overload
+
+ Returns true if byte array \a a1 is not equal to string \a a2;
+ otherwise returns false.
+*/
+
+/*! \fn bool operator!=(const char *a1, const QByteArray &a2)
+ \relates QByteArray
+
+ \overload
+
+ Returns true if string \a a1 is not equal to byte array \a a2;
+ otherwise returns false.
+*/
+
+/*! \fn bool operator<(const QByteArray &a1, const QByteArray &a2)
+ \relates QByteArray
+
+ \overload
+
+ Returns true if byte array \a a1 is lexically less than byte array
+ \a a2; otherwise returns false.
+*/
+
+/*! \fn inline bool operator<(const QByteArray &a1, const char *a2)
+ \relates QByteArray
+
+ \overload
+
+ Returns true if byte array \a a1 is lexically less than string
+ \a a2; otherwise returns false.
+*/
+
+/*! \fn bool operator<(const char *a1, const QByteArray &a2)
+ \relates QByteArray
+
+ \overload
+
+ Returns true if string \a a1 is lexically less than byte array
+ \a a2; otherwise returns false.
+*/
+
+/*! \fn bool operator<=(const QByteArray &a1, const QByteArray &a2)
+ \relates QByteArray
+
+ \overload
+
+ Returns true if byte array \a a1 is lexically less than or equal
+ to byte array \a a2; otherwise returns false.
+*/
+
+/*! \fn bool operator<=(const QByteArray &a1, const char *a2)
+ \relates QByteArray
+
+ \overload
+
+ Returns true if byte array \a a1 is lexically less than or equal
+ to string \a a2; otherwise returns false.
+*/
+
+/*! \fn bool operator<=(const char *a1, const QByteArray &a2)
+ \relates QByteArray
+
+ \overload
+
+ Returns true if string \a a1 is lexically less than or equal
+ to byte array \a a2; otherwise returns false.
+*/
+
+/*! \fn bool operator>(const QByteArray &a1, const QByteArray &a2)
+ \relates QByteArray
+
+ \overload
+
+ Returns true if byte array \a a1 is lexically greater than byte
+ array \a a2; otherwise returns false.
+*/
+
+/*! \fn bool operator>(const QByteArray &a1, const char *a2)
+ \relates QByteArray
+
+ \overload
+
+ Returns true if byte array \a a1 is lexically greater than string
+ \a a2; otherwise returns false.
+*/
+
+/*! \fn bool operator>(const char *a1, const QByteArray &a2)
+ \relates QByteArray
+
+ \overload
+
+ Returns true if string \a a1 is lexically greater than byte array
+ \a a2; otherwise returns false.
+*/
+
+/*! \fn bool operator>=(const QByteArray &a1, const QByteArray &a2)
+ \relates QByteArray
+
+ \overload
+
+ Returns true if byte array \a a1 is lexically greater than or
+ equal to byte array \a a2; otherwise returns false.
+*/
+
+/*! \fn bool operator>=(const QByteArray &a1, const char *a2)
+ \relates QByteArray
+
+ \overload
+
+ Returns true if byte array \a a1 is lexically greater than or
+ equal to string \a a2; otherwise returns false.
+*/
+
+/*! \fn bool operator>=(const char *a1, const QByteArray &a2)
+ \relates QByteArray
+
+ \overload
+
+ Returns true if string \a a1 is lexically greater than or
+ equal to byte array \a a2; otherwise returns false.
+*/
+
+/*! \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.
+*/
+
+/*!
+ 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++
+ isspace() function returns true. This includes the ASCII
+ characters '\\t', '\\n', '\\v', '\\f', '\\r', and ' '.
+
+ Example:
+ \snippet doc/src/snippets/code/src_corelib_tools_qbytearray.cpp 32
+
+ \sa trimmed()
+*/
+QByteArray QByteArray::simplified() const
+{
+ if (d->size == 0)
+ return *this;
+ QByteArray result;
+ result.resize(d->size);
+ const char *from = d->data;
+ const char *fromend = from + d->size;
+ int outc=0;
+ char *to = result.d->data;
+ for (;;) {
+ while (from!=fromend && isspace(uchar(*from)))
+ from++;
+ while (from!=fromend && !isspace(uchar(*from)))
+ to[outc++] = *from++;
+ if (from!=fromend)
+ to[outc++] = ' ';
+ else
+ break;
+ }
+ if (outc > 0 && to[outc-1] == ' ')
+ outc--;
+ result.resize(outc);
+ return result;
+}
+
+/*!
+ Returns a byte array that has whitespace removed from the start
+ and the end.
+
+ Whitespace means any character for which the standard C++
+ isspace() function returns true. This includes the ASCII
+ characters '\\t', '\\n', '\\v', '\\f', '\\r', and ' '.
+
+ Example:
+ \snippet doc/src/snippets/code/src_corelib_tools_qbytearray.cpp 33
+
+ Unlike simplified(), trimmed() leaves internal whitespace alone.
+
+ \sa simplified()
+*/
+QByteArray QByteArray::trimmed() const
+{
+ if (d->size == 0)
+ return *this;
+ const char *s = d->data;
+ if (!isspace(uchar(*s)) && !isspace(uchar(s[d->size-1])))
+ return *this;
+ int start = 0;
+ int end = d->size - 1;
+ while (start<=end && isspace(uchar(s[start]))) // skip white space from start
+ start++;
+ if (start <= end) { // only white space
+ while (end && isspace(uchar(s[end]))) // skip white space from end
+ end--;
+ }
+ int l = end - start + 1;
+ if (l <= 0) {
+ shared_empty.ref.ref();
+ return QByteArray(&shared_empty, 0, 0);
+ }
+ return QByteArray(s+start, l);
+}
+
+/*!
+ 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 doc/src/snippets/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 doc/src/snippets/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 == &shared_null; }
+
+
+/*!
+ 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 0: if a conversion error occurs, *\a{ok} is set to
+ false; otherwise *\a{ok} is set to 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
+{
+#if defined(QT_CHECK_RANGE)
+ if (base != 0 && (base < 2 || base > 36)) {
+ qWarning("QByteArray::toLongLong: Invalid base %d", base);
+ base = 10;
+ }
+#endif
+
+ return QLocalePrivate::bytearrayToLongLong(nulTerminated().constData(), base, ok);
+}
+
+/*!
+ 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 0: if a conversion error occurs, *\a{ok} is set to
+ false; otherwise *\a{ok} is set to 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
+{
+#if defined(QT_CHECK_RANGE)
+ if (base != 0 && (base < 2 || base > 36)) {
+ qWarning("QByteArray::toULongLong: Invalid base %d", base);
+ base = 10;
+ }
+#endif
+
+ return QLocalePrivate::bytearrayToUnsLongLong(nulTerminated().constData(), base, ok);
+}
+
+
+/*!
+ 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 0: if a conversion error occurs, *\a{ok} is set to
+ false; otherwise *\a{ok} is set to true.
+
+ \snippet doc/src/snippets/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
+{
+ qlonglong v = toLongLong(ok, base);
+ if (v < INT_MIN || v > INT_MAX) {
+ if (ok)
+ *ok = false;
+ v = 0;
+ }
+ return int(v);
+}
+
+/*!
+ 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 0: if a conversion error occurs, *\a{ok} is set to
+ false; otherwise *\a{ok} is set to 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
+{
+ qulonglong v = toULongLong(ok, base);
+ if (v > UINT_MAX) {
+ if (ok)
+ *ok = false;
+ v = 0;
+ }
+ return uint(v);
+}
+
+/*!
+ \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 0: if a conversion error occurs, *\a{ok} is set to
+ false; otherwise *\a{ok} is set to true.
+
+ \snippet doc/src/snippets/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
+{
+ qlonglong v = toLongLong(ok, base);
+ if (v < LONG_MIN || v > LONG_MAX) {
+ if (ok)
+ *ok = false;
+ v = 0;
+ }
+ return long(v);
+}
+
+/*!
+ \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 0: if a conversion error occurs, *\a{ok} is set to
+ false; otherwise *\a{ok} is set to 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
+{
+ qulonglong v = toULongLong(ok, base);
+ if (v > ULONG_MAX) {
+ if (ok)
+ *ok = false;
+ v = 0;
+ }
+ return ulong(v);
+}
+
+/*!
+ 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 0: if a conversion error occurs, *\a{ok} is set to
+ false; otherwise *\a{ok} is set to 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
+{
+ qlonglong v = toLongLong(ok, base);
+ if (v < SHRT_MIN || v > SHRT_MAX) {
+ if (ok)
+ *ok = false;
+ v = 0;
+ }
+ return short(v);
+}
+
+/*!
+ 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 0: if a conversion error occurs, *\a{ok} is set to
+ false; otherwise *\a{ok} is set to 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
+{
+ qulonglong v = toULongLong(ok, base);
+ if (v > USHRT_MAX) {
+ if (ok)
+ *ok = false;
+ v = 0;
+ }
+ return ushort(v);
+}
+
+
+/*!
+ Returns the byte array converted to a \c double value.
+
+ Returns 0.0 if the conversion fails.
+
+ If \a ok is not 0: if a conversion error occurs, *\a{ok} is set to
+ false; otherwise *\a{ok} is set to true.
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qbytearray.cpp 38
+
+ \note The conversion of the number is performed in the default C locale,
+ irrespective of the user's locale.
+
+ \sa number()
+*/
+
+double QByteArray::toDouble(bool *ok) const
+{
+ return QLocalePrivate::bytearrayToDouble(nulTerminated().constData(), ok);
+}
+
+/*!
+ Returns the byte array converted to a \c float value.
+
+ Returns 0.0 if the conversion fails.
+
+ If \a ok is not 0: if a conversion error occurs, *\a{ok} is set to
+ false; otherwise *\a{ok} is set to true.
+
+ \note The conversion of the number is performed in the default C locale,
+ irrespective of the user's locale.
+
+ \sa number()
+*/
+
+float QByteArray::toFloat(bool *ok) const
+{
+ return float(toDouble(ok));
+}
+
+/*!
+ Returns a copy of the byte array, encoded as Base64.
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qbytearray.cpp 39
+
+ The algorithm used to encode Base64-encoded data is defined in \l{RFC 2045}.
+
+ \sa fromBase64()
+*/
+QByteArray QByteArray::toBase64() const
+{
+ const char alphabet[] = "ABCDEFGH" "IJKLMNOP" "QRSTUVWX" "YZabcdef"
+ "ghijklmn" "opqrstuv" "wxyz0123" "456789+/";
+ const char padchar = '=';
+ int padlen = 0;
+
+ QByteArray tmp;
+ tmp.resize(((d->size * 4) / 3) + 3);
+
+ int i = 0;
+ char *out = tmp.data();
+ while (i < d->size) {
+ 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(d->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) *out++ = padchar;
+ else *out++ = alphabet[l];
+ if (padlen > 0) *out++ = padchar;
+ else *out++ = alphabet[m];
+ }
+
+ 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.
+
+ Example:
+ \snippet doc/src/snippets/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()
+*/
+
+/*!
+ \overload
+
+ \sa toLongLong()
+*/
+
+QByteArray &QByteArray::setNum(qlonglong n, int base)
+{
+#if defined(QT_CHECK_RANGE)
+ if (base < 2 || base > 36) {
+ qWarning("QByteArray::setNum: Invalid base %d", base);
+ base = 10;
+ }
+#endif
+ QLocale locale(QLocale::C);
+ *this = locale.d()->longLongToString(n, -1, base).toLatin1();
+ return *this;
+}
+
+/*!
+ \overload
+
+ \sa toULongLong()
+*/
+
+QByteArray &QByteArray::setNum(qulonglong n, int base)
+{
+#if defined(QT_CHECK_RANGE)
+ if (base < 2 || base > 36) {
+ qWarning("QByteArray::setNum: Invalid base %d", base);
+ base = 10;
+ }
+#endif
+ QLocale locale(QLocale::C);
+ *this = locale.d()->unsLongLongToString(n, -1, base).toLatin1();
+ 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 \i Format \i Meaning
+ \row \i \c e \i format as [-]9.9e[+|-]999
+ \row \i \c E \i format as [-]9.9E[+|-]999
+ \row \i \c f \i format as [-]9.9
+ \row \i \c g \i use \c e or \c f format, whichever is the most concise
+ \row \i \c G \i 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)
+{
+ QLocalePrivate::DoubleForm form = QLocalePrivate::DFDecimal;
+ uint flags = 0;
+
+ if (qIsUpper(f))
+ flags = QLocalePrivate::CapitalEorX;
+ f = qToLower(f);
+
+ switch (f) {
+ case 'f':
+ form = QLocalePrivate::DFDecimal;
+ break;
+ case 'e':
+ form = QLocalePrivate::DFExponent;
+ break;
+ case 'g':
+ form = QLocalePrivate::DFSignificantDigits;
+ break;
+ default:
+#if defined(QT_CHECK_RANGE)
+ qWarning("QByteArray::setNum: Invalid format char '%c'", f);
+#endif
+ break;
+ }
+
+ QLocale locale(QLocale::C);
+ *this = locale.d()->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 doc/src/snippets/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 \i Format \i Meaning
+ \row \i \c e \i format as [-]9.9e[+|-]999
+ \row \i \c E \i format as [-]9.9E[+|-]999
+ \row \i \c f \i format as [-]9.9
+ \row \i \c g \i use \c e or \c f format, whichever is the most concise
+ \row \i \c G \i 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 doc/src/snippets/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 doc/src/snippets/code/src_corelib_tools_qbytearray.cpp 43
+
+ \warning A byte array created with fromRawData() is \e not
+ null-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 data(), constData()
+*/
+
+QByteArray QByteArray::fromRawData(const char *data, int size)
+{
+ Data *x = static_cast<Data *>(qMalloc(sizeof(Data)));
+ if (data) {
+ x->data = const_cast<char *>(data);
+ } else {
+ x->data = x->array;
+ size = 0;
+ }
+ x->ref = 1;
+ x->alloc = x->size = size;
+ *x->array = '\0';
+ return QByteArray(x, 0, 0);
+}
+
+/*!
+ 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 doc/src/snippets/code/src_corelib_tools_qbytearray.cpp 44
+
+ The algorithm used to decode Base64-encoded data is defined in \l{RFC 2045}.
+
+ \sa toBase64()
+*/
+QByteArray QByteArray::fromBase64(const QByteArray &base64)
+{
+ unsigned int buf = 0;
+ int nbits = 0;
+ QByteArray tmp;
+ tmp.resize((base64.size() * 3) / 4);
+
+ 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 == '+')
+ d = 62;
+ else if (ch == '/')
+ 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 doc/src/snippets/code/src_corelib_tools_qbytearray.cpp 45
+
+ \sa toHex()
+*/
+QByteArray QByteArray::fromHex(const QByteArray &hexEncoded)
+{
+ QByteArray res;
+ res.resize((hexEncoded.size() + 1)/ 2);
+ uchar *result = (uchar *)res.data() + res.size();
+
+ bool odd_digit = true;
+ for (int i = hexEncoded.size() - 1; i >= 0; --i) {
+ int ch = hexEncoded.at(i);
+ int tmp;
+ if (ch >= '0' && ch <= '9')
+ tmp = ch - '0';
+ else if (ch >= 'a' && ch <= 'f')
+ tmp = ch - 'a' + 10;
+ else if (ch >= 'A' && ch <= 'F')
+ tmp = ch - 'A' + 10;
+ else
+ 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
+{
+ QByteArray hex;
+ hex.resize(d->size*2);
+ char *hexData = hex.data();
+ const uchar *data = (const uchar *)d->data;
+ for (int i = 0; i < d->size; ++i) {
+ int j = (data[i] >> 4) & 0xf;
+ if (j <= 9)
+ hexData[i*2] = (j + '0');
+ else
+ hexData[i*2] = (j + 'a' - 10);
+ j = data[i] & 0xf;
+ if (j <= 9)
+ hexData[i*2+1] = (j + '0');
+ else
+ hexData[i*2+1] = (j + 'a' - 10);
+ }
+ 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:
+ \code
+ QByteArray text = QByteArray::fromPercentEncoding("Qt%20is%20great%33");
+ text.data(); // returns "Qt is great!"
+ \endcode
+
+ \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;
+}
+
+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 inline char toHexHelper(char c)
+{
+ static const char hexnumbers[] = "0123456789ABCDEF";
+ return hexnumbers[c & 0xf];
+}
+
+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 = 0;
+ 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++] = toHexHelper((c & 0xf0) >> 4);
+ output[length++] = toHexHelper(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, 0, '%');
+}
+
+/*!
+ \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:
+
+ \code
+ QByteArray text = "{a fishy string?}";
+ QByteArray ba = text.toPercentEncoding("{}", "s");
+ qDebug(ba.constData());
+ // prints "{a fi%73hy %73tring%3F}"
+ \endcode
+
+ 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
+ \internal
+*/
+
+/*! \typedef QByteArray::iterator
+ \internal
+*/
+
+/*! \typedef QByteArray::const_reference
+ \internal
+*/
+
+/*! \typedef QByteArray::reference
+ \internal
+*/
+
+/*!
+ \fn QByteArray::QByteArray(int size)
+
+ Use QByteArray(int, char) instead.
+*/
+
+
+/*!
+ \fn QByteArray QByteArray::leftJustify(uint width, char fill, bool truncate) const
+
+ Use leftJustified() instead.
+*/
+
+/*!
+ \fn QByteArray QByteArray::rightJustify(uint width, char fill, bool truncate) const
+
+ Use rightJustified() instead.
+*/
+
+/*!
+ \fn QByteArray& QByteArray::duplicate(const QByteArray& a)
+
+ \oldcode
+ QByteArray bdata;
+ bdata.duplicate(original);
+ \newcode
+ QByteArray bdata;
+ bdata = original;
+ \endcode
+
+ \note QByteArray uses implicit sharing so if you modify a copy, only the
+ copy is changed.
+*/
+
+/*!
+ \fn QByteArray& QByteArray::duplicate(const char *a, uint n)
+
+ \overload
+
+ \oldcode
+ QByteArray bdata;
+ bdata.duplicate(ptr, size);
+ \newcode
+ QByteArray bdata;
+ bdata = QByteArray(ptr, size);
+ \endcode
+
+ \note QByteArray uses implicit sharing so if you modify a copy, only the
+ copy is changed.
+*/
+
+/*!
+ \fn QByteArray& QByteArray::setRawData(const char *a, uint n)
+
+ Use fromRawData() instead.
+*/
+
+/*!
+ \fn void QByteArray::resetRawData(const char *data, uint n)
+
+ Use clear() instead.
+*/
+
+/*!
+ \fn QByteArray QByteArray::lower() const
+
+ Use toLower() instead.
+*/
+
+/*!
+ \fn QByteArray QByteArray::upper() const
+
+ Use toUpper() instead.
+*/
+
+/*!
+ \fn QByteArray QByteArray::stripWhiteSpace() const
+
+ Use trimmed() instead.
+*/
+
+/*!
+ \fn QByteArray QByteArray::simplifyWhiteSpace() const
+
+ Use simplified() instead.
+*/
+
+/*!
+ \fn int QByteArray::find(char c, int from = 0) const
+
+ Use indexOf() instead.
+*/
+
+/*!
+ \fn int QByteArray::find(const char *c, int from = 0) const
+
+ Use indexOf() instead.
+*/
+
+/*!
+ \fn int QByteArray::find(const QByteArray &ba, int from = 0) const
+
+ Use indexOf() instead.
+*/
+
+/*!
+ \fn int QByteArray::findRev(char c, int from = -1) const
+
+ Use lastIndexOf() instead.
+*/
+
+/*!
+ \fn int QByteArray::findRev(const char *c, int from = -1) const
+
+ Use lastIndexOf() instead.
+*/
+
+/*!
+ \fn int QByteArray::findRev(const QByteArray &ba, int from = -1) const
+
+ Use lastIndexOf() instead.
+*/
+
+/*!
+ \fn int QByteArray::find(const QString &s, int from = 0) const
+
+ Use indexOf() instead.
+*/
+
+/*!
+ \fn int QByteArray::findRev(const QString &s, int from = -1) const
+
+ Use lastIndexOf() instead.
+*/
+
+/*!
+ \fn DataPtr &QByteArray::data_ptr()
+ \internal
+*/
+
+/*!
+ \typedef QByteArray::DataPtr
+ \internal
+*/
+
+QT_END_NAMESPACE
diff --git a/src/corelib/tools/qbytearray.h b/src/corelib/tools/qbytearray.h
new file mode 100644
index 0000000000..f6422fbe52
--- /dev/null
+++ b/src/corelib/tools/qbytearray.h
@@ -0,0 +1,589 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QBYTEARRAY_H
+#define QBYTEARRAY_H
+
+#include <QtCore/qglobal.h>
+#include <QtCore/qatomic.h>
+
+#include <string.h>
+#include <stdarg.h>
+
+#ifdef truncate
+#error qbytearray.h must be included before any header file that defines truncate
+#endif
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Core)
+
+/*****************************************************************************
+ 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);
+
+// 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, ...);
+
+#ifdef QT3_SUPPORT
+inline QT3_SUPPORT void *qmemmove(void *dst, const void *src, uint len)
+{ return memmove(dst, src, len); }
+inline QT3_SUPPORT uint cstrlen(const char *str)
+{ return uint(strlen(str)); }
+inline QT3_SUPPORT char *cstrcpy(char *dst, const char *src)
+{ return qstrcpy(dst,src); }
+inline QT3_SUPPORT int cstrcmp(const char *str1, const char *str2)
+{ return strcmp(str1,str2); }
+inline QT3_SUPPORT int cstrncmp(const char *str1, const char *str2, uint len)
+{ return strncmp(str1,str2,len); }
+#endif
+
+// qChecksum: Internet checksum
+
+Q_CORE_EXPORT quint16 qChecksum(const char *s, uint len);
+
+class QByteRef;
+class QString;
+class QDataStream;
+template <typename T> class QList;
+
+class Q_CORE_EXPORT QByteArray
+{
+public:
+ inline QByteArray();
+ QByteArray(const char *);
+ QByteArray(const char *, int size);
+ QByteArray(int size, char c);
+ inline QByteArray(const QByteArray &);
+ inline ~QByteArray();
+
+ QByteArray &operator=(const QByteArray &);
+ QByteArray &operator=(const char *str);
+
+ inline int size() const;
+ bool isEmpty() const;
+ void resize(int size);
+
+ QByteArray &fill(char c, int size = -1);
+
+ int capacity() const;
+ void reserve(int size);
+ void squeeze();
+
+#ifndef QT_NO_CAST_FROM_BYTEARRAY
+ operator const char *() const;
+ operator const void *() const;
+#endif
+ char *data();
+ const char *data() const;
+ inline const char *constData() const;
+ inline void detach();
+ bool isDetached() const;
+ void clear();
+
+#ifdef Q_COMPILER_MANGLES_RETURN_TYPE
+ const char at(int i) const;
+ const char operator[](int i) const;
+ const char operator[](uint i) const;
+#else
+ char at(int i) const;
+ char operator[](int i) const;
+ char operator[](uint i) const;
+#endif
+ QByteRef operator[](int i);
+ QByteRef operator[](uint i);
+
+ 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;
+
+ QBool contains(char c) const;
+ QBool contains(const char *a) const;
+ QBool contains(const QByteArray &a) const;
+ int count(char c) const;
+ int count(const char *a) const;
+ int count(const QByteArray &a) const;
+
+ QByteArray left(int len) const;
+ QByteArray right(int len) const;
+ QByteArray mid(int index, int len = -1) const;
+
+ 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;
+
+ void truncate(int pos);
+ void chop(int n);
+
+ QByteArray toLower() const;
+ QByteArray toUpper() const;
+
+ QByteArray trimmed() const;
+ QByteArray simplified() const;
+ QByteArray leftJustified(int width, char fill = ' ', bool truncate = false) const;
+ QByteArray rightJustified(int width, char fill = ' ', bool truncate = false) const;
+
+#ifdef QT3_SUPPORT
+ inline QT3_SUPPORT QByteArray leftJustify(uint width, char aFill = ' ', bool aTruncate = false) const
+ { return leftJustified(int(width), aFill, aTruncate); }
+ inline QT3_SUPPORT QByteArray rightJustify(uint width, char aFill = ' ', bool aTruncate = false) const
+ { return rightJustified(int(width), aFill, aTruncate); }
+#endif
+
+ QByteArray &prepend(char c);
+ QByteArray &prepend(const char *s);
+ QByteArray &prepend(const QByteArray &a);
+ QByteArray &append(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, const char *s);
+ 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 QByteArray &s);
+ QByteArray &replace(char before, const char *after);
+ QByteArray &replace(char before, const QByteArray &after);
+ 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);
+ QByteArray &replace(const QByteArray &before, const char *after);
+ QByteArray &replace(const char *before, const QByteArray &after);
+ QByteArray &replace(char before, char after);
+ QByteArray &operator+=(char c);
+ QByteArray &operator+=(const char *s);
+ QByteArray &operator+=(const QByteArray &a);
+
+ QList<QByteArray> split(char sep) const;
+
+ 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
+#ifndef QT_NO_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 = 0, int base = 10) const;
+ ushort toUShort(bool *ok = 0, int base = 10) const;
+ int toInt(bool *ok = 0, int base = 10) const;
+ uint toUInt(bool *ok = 0, int base = 10) const;
+ long toLong(bool *ok = 0, int base = 10) const;
+ ulong toULong(bool *ok = 0, int base = 10) const;
+ qlonglong toLongLong(bool *ok = 0, int base = 10) const;
+ qulonglong toULongLong(bool *ok = 0, int base = 10) const;
+ float toFloat(bool *ok = 0) const;
+ double toDouble(bool *ok = 0) const;
+ QByteArray toBase64() const;
+ QByteArray toHex() const;
+ QByteArray toPercentEncoding(const QByteArray &exclude = QByteArray(),
+ const QByteArray &include = QByteArray(),
+ char percent = '%') const;
+
+ QByteArray &setNum(short, int base = 10);
+ QByteArray &setNum(ushort, int base = 10);
+ QByteArray &setNum(int, int base = 10);
+ QByteArray &setNum(uint, int base = 10);
+ QByteArray &setNum(qlonglong, int base = 10);
+ QByteArray &setNum(qulonglong, int base = 10);
+ QByteArray &setNum(float, char f = 'g', int prec = 6);
+ QByteArray &setNum(double, char f = 'g', int prec = 6);
+
+ static QByteArray number(int, int base = 10);
+ static QByteArray number(uint, int base = 10);
+ static QByteArray number(qlonglong, int base = 10);
+ static QByteArray number(qulonglong, int base = 10);
+ static QByteArray number(double, char f = 'g', int prec = 6);
+ static QByteArray fromRawData(const char *, int size);
+ static QByteArray fromBase64(const QByteArray &base64);
+ static QByteArray fromHex(const QByteArray &hexEncoded);
+ static QByteArray fromPercentEncoding(const QByteArray &pctEncoded, char percent = '%');
+
+
+ typedef char *iterator;
+ typedef const char *const_iterator;
+ typedef iterator Iterator;
+ typedef const_iterator ConstIterator;
+ iterator begin();
+ const_iterator begin() const;
+ const_iterator constBegin() const;
+ iterator end();
+ const_iterator end() const;
+ const_iterator constEnd() const;
+
+ // stl compatibility
+ typedef const char & const_reference;
+ typedef char & reference;
+ void push_back(char c);
+ void push_back(const char *c);
+ void push_back(const QByteArray &a);
+ void push_front(char c);
+ void push_front(const char *c);
+ void push_front(const QByteArray &a);
+
+ inline int count() const { return d->size; }
+ int length() const { return d->size; }
+ bool isNull() const;
+
+ // compatibility
+#ifdef QT3_SUPPORT
+ QT3_SUPPORT_CONSTRUCTOR QByteArray(int size);
+ inline QT3_SUPPORT QByteArray& duplicate(const QByteArray& a) { *this = a; return *this; }
+ inline QT3_SUPPORT QByteArray& duplicate(const char *a, uint n)
+ { *this = QByteArray(a, n); return *this; }
+ inline QT3_SUPPORT QByteArray& setRawData(const char *a, uint n)
+ { *this = fromRawData(a, n); return *this; }
+ inline QT3_SUPPORT void resetRawData(const char *, uint) { clear(); }
+ inline QT3_SUPPORT QByteArray lower() const { return toLower(); }
+ inline QT3_SUPPORT QByteArray upper() const { return toUpper(); }
+ inline QT3_SUPPORT QByteArray stripWhiteSpace() const { return trimmed(); }
+ inline QT3_SUPPORT QByteArray simplifyWhiteSpace() const { return simplified(); }
+ inline QT3_SUPPORT int find(char c, int from = 0) const { return indexOf(c, from); }
+ inline QT3_SUPPORT int find(const char *c, int from = 0) const { return indexOf(c, from); }
+ inline QT3_SUPPORT int find(const QByteArray &ba, int from = 0) const { return indexOf(ba, from); }
+ inline QT3_SUPPORT int findRev(char c, int from = -1) const { return lastIndexOf(c, from); }
+ inline QT3_SUPPORT int findRev(const char *c, int from = -1) const { return lastIndexOf(c, from); }
+ inline QT3_SUPPORT int findRev(const QByteArray &ba, int from = -1) const { return lastIndexOf(ba, from); }
+#ifndef QT_NO_CAST_TO_ASCII
+ QT3_SUPPORT int find(const QString &s, int from = 0) const;
+ QT3_SUPPORT int findRev(const QString &s, int from = -1) const;
+#endif
+#endif
+
+private:
+ operator QNoImplicitBoolCast() const;
+ struct Data {
+ QBasicAtomicInt ref;
+ int alloc, size;
+ // ### Qt 5.0: We need to add the missing capacity bit
+ // (like other tool classes have), to maintain the
+ // reserved memory on resize.
+ char *data;
+ char array[1];
+ };
+ static Data shared_null;
+ static Data shared_empty;
+ Data *d;
+ QByteArray(Data *dd, int /*dummy*/, int /*dummy*/) : d(dd) {}
+ void realloc(int alloc);
+ void expand(int i);
+ QByteArray nulTerminated() const;
+
+ friend class QByteRef;
+ friend class QString;
+public:
+ typedef Data * DataPtr;
+ inline DataPtr &data_ptr() { return d; }
+};
+
+inline QByteArray::QByteArray(): d(&shared_null) { d->ref.ref(); }
+inline QByteArray::~QByteArray() { if (!d->ref.deref()) qFree(d); }
+inline int QByteArray::size() const
+{ return d->size; }
+
+#ifdef Q_COMPILER_MANGLES_RETURN_TYPE
+inline const char QByteArray::at(int i) const
+{ Q_ASSERT(i >= 0 && i < size()); return d->data[i]; }
+inline const char QByteArray::operator[](int i) const
+{ Q_ASSERT(i >= 0 && i < size()); return d->data[i]; }
+inline const char QByteArray::operator[](uint i) const
+{ Q_ASSERT(i < uint(size())); return d->data[i]; }
+#else
+inline char QByteArray::at(int i) const
+{ Q_ASSERT(i >= 0 && i < size()); return d->data[i]; }
+inline char QByteArray::operator[](int i) const
+{ Q_ASSERT(i >= 0 && i < size()); return d->data[i]; }
+inline char QByteArray::operator[](uint i) const
+{ Q_ASSERT(i < uint(size())); return d->data[i]; }
+#endif
+
+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 != 1 || d->data != d->array) realloc(d->size); }
+inline bool QByteArray::isDetached() const
+{ return d->ref == 1; }
+inline QByteArray::QByteArray(const QByteArray &a) : d(a.d)
+{ d->ref.ref(); }
+#ifdef QT3_SUPPORT
+inline QByteArray::QByteArray(int aSize) : d(&shared_null)
+{ d->ref.ref(); if (aSize > 0) fill('\0', aSize); }
+#endif
+
+inline int QByteArray::capacity() const
+{ return d->alloc; }
+
+inline void QByteArray::reserve(int asize)
+{ if (d->ref != 1 || asize > d->alloc) realloc(asize); }
+
+inline void QByteArray::squeeze()
+{ if (d->size < d->alloc) realloc(d->size); }
+
+class Q_CORE_EXPORT QByteRef {
+ QByteArray &a;
+ int i;
+ inline QByteRef(QByteArray &array, int idx)
+ : a(array),i(idx) {}
+ friend class QByteArray;
+public:
+#ifdef Q_COMPILER_MANGLES_RETURN_TYPE
+ inline operator const char() const
+ { return i < a.d->size ? a.d->data[i] : 0; }
+#else
+ inline operator char() const
+ { return i < a.d->size ? a.d->data[i] : 0; }
+#endif
+ inline QByteRef &operator=(char c)
+ { if (i >= a.d->size) a.expand(i); else a.detach();
+ a.d->data[i] = c; return *this; }
+ inline QByteRef &operator=(const QByteRef &c)
+ { if (i >= a.d->size) a.expand(i); else a.detach();
+ a.d->data[i] = c.a.d->data[c.i]; return *this; }
+ 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); return QByteRef(*this, i); }
+inline QByteRef QByteArray::operator[](uint i)
+{ return QByteRef(*this, i); }
+inline QByteArray::iterator QByteArray::begin()
+{ detach(); return d->data; }
+inline QByteArray::const_iterator QByteArray::begin() 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::constEnd() const
+{ return d->data + d->size; }
+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 QBool QByteArray::contains(const QByteArray &a) const
+{ return QBool(indexOf(a) != -1); }
+inline QBool QByteArray::contains(char c) const
+{ return QBool(indexOf(c) != -1); }
+inline bool operator==(const QByteArray &a1, const QByteArray &a2)
+{ return (a1.size() == a2.size()) && (memcmp(a1.constData(), a2.constData(), a1.size())==0); }
+inline bool operator==(const QByteArray &a1, const char *a2)
+{ return a2 ? qstrcmp(a1,a2) == 0 : a1.isEmpty(); }
+inline bool operator==(const char *a1, const QByteArray &a2)
+{ return a1 ? qstrcmp(a1,a2) == 0 : a2.isEmpty(); }
+inline bool operator!=(const QByteArray &a1, const QByteArray &a2)
+{ return !(a1==a2); }
+inline bool operator!=(const QByteArray &a1, const char *a2)
+{ return a2 ? qstrcmp(a1,a2) != 0 : !a1.isEmpty(); }
+inline bool operator!=(const char *a1, const QByteArray &a2)
+{ return a1 ? qstrcmp(a1,a2) != 0 : !a2.isEmpty(); }
+inline bool operator<(const QByteArray &a1, const QByteArray &a2)
+{ return qstrcmp(a1, a2) < 0; }
+ inline bool operator<(const QByteArray &a1, const char *a2)
+{ return qstrcmp(a1, a2) < 0; }
+inline bool operator<(const char *a1, const QByteArray &a2)
+{ return qstrcmp(a1, a2) < 0; }
+inline bool operator<=(const QByteArray &a1, const QByteArray &a2)
+{ return qstrcmp(a1, a2) <= 0; }
+inline bool operator<=(const QByteArray &a1, const char *a2)
+{ return qstrcmp(a1, a2) <= 0; }
+inline bool operator<=(const char *a1, const QByteArray &a2)
+{ return qstrcmp(a1, a2) <= 0; }
+inline bool operator>(const QByteArray &a1, const QByteArray &a2)
+{ return qstrcmp(a1, a2) > 0; }
+inline bool operator>(const QByteArray &a1, const char *a2)
+{ return qstrcmp(a1, a2) > 0; }
+inline bool operator>(const char *a1, const QByteArray &a2)
+{ return qstrcmp(a1, a2) > 0; }
+inline bool operator>=(const QByteArray &a1, const QByteArray &a2)
+{ return qstrcmp(a1, a2) >= 0; }
+inline bool operator>=(const QByteArray &a1, const char *a2)
+{ return qstrcmp(a1, a2) >= 0; }
+inline bool operator>=(const char *a1, const QByteArray &a2)
+{ return qstrcmp(a1, a2) >= 0; }
+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; }
+inline QBool QByteArray::contains(const char *c) const
+{ return QBool(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 setNum(qlonglong(n), base); }
+inline QByteArray &QByteArray::setNum(ushort n, int base)
+{ return setNum(qulonglong(n), base); }
+inline QByteArray &QByteArray::setNum(int n, int base)
+{ return setNum(qlonglong(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); }
+
+
+#ifndef QT_NO_DATASTREAM
+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_TYPEINFO(QByteArray, Q_MOVABLE_TYPE);
+Q_DECLARE_SHARED(QByteArray)
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QBYTEARRAY_H
diff --git a/src/corelib/tools/qbytearraymatcher.cpp b/src/corelib/tools/qbytearraymatcher.cpp
new file mode 100644
index 0000000000..cd4cf90775
--- /dev/null
+++ b/src/corelib/tools/qbytearraymatcher.cpp
@@ -0,0 +1,323 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $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;
+
+ register 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
+ \brief The QByteArrayMatcher class holds a sequence of bytes that
+ can be quickly matched in a byte array.
+
+ \ingroup tools
+ \ingroup text
+
+ 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(0)
+{
+ p.p = 0;
+ qMemSet(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(0)
+{
+ 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(0), 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(0)
+{
+ operator=(other);
+}
+
+/*!
+ Destroys the byte array matcher.
+*/
+QByteArrayMatcher::~QByteArrayMatcher()
+{
+}
+
+/*!
+ Assigns the \a other byte array matcher to this byte array matcher.
+*/
+QByteArrayMatcher &QByteArrayMatcher::operator=(const QByteArrayMatcher &other)
+{
+ q_pattern = other.q_pattern;
+ qMemCopy(p.q_skiptable, other.p.q_skiptable, sizeof(p.q_skiptable));
+ 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 -= (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;
+}
+
+QT_END_NAMESPACE
diff --git a/src/corelib/tools/qbytearraymatcher.h b/src/corelib/tools/qbytearraymatcher.h
new file mode 100644
index 0000000000..d7f2366211
--- /dev/null
+++ b/src/corelib/tools/qbytearraymatcher.h
@@ -0,0 +1,93 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QBYTEARRAYMATCHER_H
+#define QBYTEARRAYMATCHER_H
+
+#include <QtCore/qbytearray.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Core)
+
+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 { return q_pattern; }
+
+private:
+ QByteArrayMatcherPrivate *d;
+ QByteArray q_pattern;
+#ifdef Q_CC_RVCT
+// explicitely allow anonymous unions for RVCT to prevent compiler warnings
+#pragma anon_unions
+#endif
+ union {
+ uint dummy[256];
+ struct {
+ uchar q_skiptable[256];
+ const uchar *p;
+ int l;
+ } p;
+ };
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QBYTEARRAYMATCHER_H
diff --git a/src/corelib/tools/qcache.h b/src/corelib/tools/qcache.h
new file mode 100644
index 0000000000..38adac6f87
--- /dev/null
+++ b/src/corelib/tools/qcache.h
@@ -0,0 +1,216 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QCACHE_H
+#define QCACHE_H
+
+#include <QtCore/qhash.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Core)
+
+template <class Key, class T>
+class QCache
+{
+ struct Node {
+ inline Node() : keyPtr(0) {}
+ inline Node(T *data, int cost)
+ : keyPtr(0), t(data), c(cost), p(0), n(0) {}
+ const Key *keyPtr; T *t; int c; Node *p,*n;
+ };
+ Node *f, *l;
+ QHash<Key, Node> hash;
+ void *unused;
+ int mx, total;
+
+ inline void unlink(Node &n) {
+ if (n.p) n.p->n = n.n;
+ if (n.n) n.n->p = n.p;
+ if (l == &n) l = n.p;
+ if (f == &n) f = n.n;
+ total -= n.c;
+ delete n.t;
+ hash.remove(*n.keyPtr);
+ }
+ inline T *relink(const Key &key) {
+ typename QHash<Key, Node>::iterator i = hash.find(key);
+ if (typename QHash<Key, Node>::const_iterator(i) == hash.constEnd())
+ return 0;
+
+ Node &n = *i;
+ if (f != &n) {
+ if (n.p) n.p->n = n.n;
+ if (n.n) n.n->p = n.p;
+ if (l == &n) l = n.p;
+ n.p = 0;
+ n.n = f;
+ f->p = &n;
+ f = &n;
+ }
+ return n.t;
+ }
+
+ Q_DISABLE_COPY(QCache)
+
+public:
+ inline explicit QCache(int maxCost = 100);
+#ifdef QT3_SUPPORT
+ inline QT3_SUPPORT_CONSTRUCTOR QCache(int maxCost, int /* dummy */)
+ : f(0), l(0), mx(maxCost), total(0) {}
+#endif
+ inline ~QCache() { clear(); }
+
+ inline int maxCost() const { return mx; }
+ void setMaxCost(int m);
+ inline int totalCost() const { return total; }
+
+ inline int size() const { return hash.size(); }
+ inline int count() const { return hash.size(); }
+ inline bool isEmpty() const { return hash.isEmpty(); }
+ inline QList<Key> keys() const { return hash.keys(); }
+
+ void clear();
+
+ bool insert(const Key &key, T *object, int cost = 1);
+ T *object(const Key &key) const;
+ inline bool contains(const Key &key) const { return hash.contains(key); }
+ T *operator[](const Key &key) const;
+
+ bool remove(const Key &key);
+ T *take(const Key &key);
+
+private:
+ void trim(int m);
+
+#ifdef QT3_SUPPORT
+ inline QT3_SUPPORT T *find(const Key &key) const { return object(key); }
+#endif
+
+};
+
+template <class Key, class T>
+inline QCache<Key, T>::QCache(int amaxCost)
+ : f(0), l(0), mx(amaxCost), total(0) {}
+
+template <class Key, class T>
+inline void QCache<Key,T>::clear()
+{ while (f) { delete f->t; f = f->n; }
+ hash.clear(); l = 0; total = 0; }
+
+template <class Key, class T>
+inline void QCache<Key,T>::setMaxCost(int m)
+{ mx = m; trim(mx); }
+
+template <class Key, class T>
+inline T *QCache<Key,T>::object(const Key &key) const
+{ return const_cast<QCache<Key,T>*>(this)->relink(key); }
+
+template <class Key, class T>
+inline T *QCache<Key,T>::operator[](const Key &key) const
+{ return object(key); }
+
+template <class Key, class T>
+inline bool QCache<Key,T>::remove(const Key &key)
+{
+ typename QHash<Key, Node>::iterator i = hash.find(key);
+ if (typename QHash<Key, Node>::const_iterator(i) == hash.constEnd()) {
+ return false;
+ } else {
+ unlink(*i);
+ return true;
+ }
+}
+
+template <class Key, class T>
+inline T *QCache<Key,T>::take(const Key &key)
+{
+ typename QHash<Key, Node>::iterator i = hash.find(key);
+ if (i == hash.end())
+ return 0;
+
+ Node &n = *i;
+ T *t = n.t;
+ n.t = 0;
+ unlink(n);
+ return t;
+}
+
+template <class Key, class T>
+bool QCache<Key,T>::insert(const Key &akey, T *aobject, int acost)
+{
+ remove(akey);
+ if (acost > mx) {
+ delete aobject;
+ return false;
+ }
+ trim(mx - acost);
+ Node sn(aobject, acost);
+ typename QHash<Key, Node>::iterator i = hash.insert(akey, sn);
+ total += acost;
+ Node *n = &i.value();
+ n->keyPtr = &i.key();
+ if (f) f->p = n;
+ n->n = f;
+ f = n;
+ if (!l) l = f;
+ return true;
+}
+
+template <class Key, class T>
+void QCache<Key,T>::trim(int m)
+{
+ Node *n = l;
+ while (n && total > m) {
+ Node *u = n;
+ n = n->p;
+ if (qIsDetached(*u->t))
+ unlink(*u);
+ }
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QCACHE_H
diff --git a/src/corelib/tools/qchar.cpp b/src/corelib/tools/qchar.cpp
new file mode 100644
index 0000000000..a940cda70c
--- /dev/null
+++ b/src/corelib/tools/qchar.cpp
@@ -0,0 +1,1618 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $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 "qtextcodec.h"
+
+#include "qunicodetables_p.h"
+
+#include "qunicodetables.cpp"
+
+QT_BEGIN_NAMESPACE
+
+#define LAST_UNICODE_CHAR 0x10ffff
+
+#ifndef QT_NO_CODEC_FOR_C_STRINGS
+#ifdef QT_NO_TEXTCODEC
+#define QT_NO_CODEC_FOR_C_STRINGS
+#endif
+#endif
+
+#define FLAG(x) (1 << (x))
+
+/*! \class QLatin1Char
+ \brief The QLatin1Char class provides an 8-bit ASCII/Latin-1 character.
+
+ \ingroup text
+
+ This class is only useful to avoid the codec for C strings business
+ in the QChar(ch) constructor. You can avoid it by writing
+ QChar(ch, 0).
+
+ \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
+ \brief The QChar class provides a 16-bit Unicode character.
+
+ \ingroup text
+ \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 a \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. They all
+ return true if the character is a certain type of character;
+ otherwise they return false. These classification functions are
+ isNull() (returns 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.
+
+ QChar also provides direction(), which indicates the "natural"
+ writing direction of this character. The joining() function
+ indicates how the character joins with its neighbors (needed
+ mostly for Arabic) and finally hasMirrored(), which indicates
+ whether the character needs to be mirrored when it is printed in
+ its "unnatural" writing direction.
+
+ Composed Unicode characters (like \aring) 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 fromAscii() or fromLatin1(), or use QLatin1Char,
+ to construct a QChar from an 8-bit \c char, and you will need to
+ call toAscii() or toLatin1() to get the 8-bit value back.
+
+ \sa QString, Unicode, 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_Unassigned The value is not assigned to any character
+ in version 5.0 of Unicode.
+
+ \sa unicodeVersion()
+*/
+
+/*!
+ \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
+
+ \value NoCategory Qt cannot find an appropriate category for the character.
+
+ \omitvalue Punctuation_Dask
+
+ \sa category()
+*/
+
+/*!
+ \enum QChar::Direction
+
+ This enum type defines the Unicode direction 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 "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 DirL
+ \value DirLRE
+ \value DirLRO
+ \value DirNSM
+ \value DirON
+ \value DirPDF
+ \value DirR
+ \value DirRLE
+ \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
+
+ \omitvalue Single
+
+ \sa decomposition()
+*/
+
+/*!
+ \enum QChar::Joining
+
+ 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()
+*/
+
+/*!
+ \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 Nbsp Non-breaking space.
+ \value ReplacementCharacter
+ \value ObjectReplacementCharacter The character shown when a font has no glyph for a certain codepoint. The square character is normally used.
+ \value ByteOrderMark
+ \value ByteOrderSwapped
+ \value ParagraphSeparator
+ \value LineSeparator
+
+ \omitvalue null
+ \omitvalue replacement
+ \omitvalue byteOrderMark
+ \omitvalue byteOrderSwapped
+ \omitvalue nbsp
+*/
+
+/*!
+ \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.
+*/
+
+/*!
+ Constructs a QChar corresponding to ASCII/Latin-1 character \a
+ ch.
+*/
+QChar::QChar(char ch)
+{
+#ifndef QT_NO_CODEC_FOR_C_STRINGS
+ if (QTextCodec::codecForCStrings())
+ // #####
+ ucs = QTextCodec::codecForCStrings()->toUnicode(&ch, 1).at(0).unicode();
+ else
+#endif
+ ucs = uchar(ch);
+}
+
+/*!
+ Constructs a QChar corresponding to ASCII/Latin-1 character \a ch.
+*/
+QChar::QChar(uchar ch)
+{
+#ifndef QT_NO_CODEC_FOR_C_STRINGS
+ if (QTextCodec::codecForCStrings()) {
+ // #####
+ char c = char(ch);
+ ucs = QTextCodec::codecForCStrings()->toUnicode(&c, 1).at(0).unicode();
+ } else
+#endif
+ ucs = ch;
+}
+
+/*!
+ \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 true if the character is the Unicode character 0x0000
+ ('\\0'); otherwise returns 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()
+*/
+
+/*!
+ Returns true if the character is a printable character; otherwise
+ returns false. This is any character not of category Cc or Cn.
+
+ Note that this gives no indication of whether the character is
+ available in a particular font.
+*/
+bool QChar::isPrint() const
+{
+ const int test = FLAG(Other_Control) |
+ FLAG(Other_NotAssigned);
+ return !(FLAG(qGetProp(ucs)->category) & test);
+}
+
+/*!
+ Returns true if the character is a separator character
+ (Separator_* categories); otherwise returns false.
+*/
+bool QChar::isSpace() const
+{
+ if(ucs >= 9 && ucs <=13)
+ return true;
+ const int test = FLAG(Separator_Space) |
+ FLAG(Separator_Line) |
+ FLAG(Separator_Paragraph);
+ return FLAG(qGetProp(ucs)->category) & test;
+}
+
+/*!
+ Returns true if the character is a mark (Mark_* categories);
+ otherwise returns false.
+
+ See QChar::Category for more information regarding marks.
+*/
+bool QChar::isMark() const
+{
+ const int test = FLAG(Mark_NonSpacing) |
+ FLAG(Mark_SpacingCombining) |
+ FLAG(Mark_Enclosing);
+ return FLAG(qGetProp(ucs)->category) & test;
+}
+
+/*!
+ Returns true if the character is a punctuation mark (Punctuation_*
+ categories); otherwise returns false.
+*/
+bool QChar::isPunct() const
+{
+ 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(ucs)->category) & test;
+}
+
+/*!
+ Returns true if the character is a letter (Letter_* categories);
+ otherwise returns false.
+*/
+bool QChar::isLetter() const
+{
+ const int test = FLAG(Letter_Uppercase) |
+ FLAG(Letter_Lowercase) |
+ FLAG(Letter_Titlecase) |
+ FLAG(Letter_Modifier) |
+ FLAG(Letter_Other);
+ return FLAG(qGetProp(ucs)->category) & test;
+}
+
+/*!
+ Returns true if the character is a number (Number_* categories,
+ not just 0-9); otherwise returns false.
+
+ \sa isDigit()
+*/
+bool QChar::isNumber() const
+{
+ const int test = FLAG(Number_DecimalDigit) |
+ FLAG(Number_Letter) |
+ FLAG(Number_Other);
+ return FLAG(qGetProp(ucs)->category) & test;
+}
+
+/*!
+ Returns true if the character is a letter or number (Letter_* or
+ Number_* categories); otherwise returns false.
+*/
+bool QChar::isLetterOrNumber() const
+{
+ 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(ucs)->category) & test;
+}
+
+
+/*!
+ Returns true if the character is a decimal digit
+ (Number_DecimalDigit); otherwise returns false.
+*/
+bool QChar::isDigit() const
+{
+ return (qGetProp(ucs)->category == Number_DecimalDigit);
+}
+
+
+/*!
+ Returns true if the character is a symbol (Symbol_* categories);
+ otherwise returns false.
+*/
+bool QChar::isSymbol() const
+{
+ const int test = FLAG(Symbol_Math) |
+ FLAG(Symbol_Currency) |
+ FLAG(Symbol_Modifier) |
+ FLAG(Symbol_Other);
+ return FLAG(qGetProp(ucs)->category) & test;
+}
+
+/*!
+ \fn bool QChar::isHighSurrogate() const
+
+ Returns true if the QChar is the high part of a utf16 surrogate
+ (ie. if its code point is between 0xd800 and 0xdbff).
+*/
+
+/*!
+ \fn bool QChar::isLowSurrogate() const
+
+ Returns true if the QChar is the low part of a utf16 surrogate
+ (ie. if its code point is between 0xdc00 and 0xdfff).
+*/
+
+/*!
+ \fn static uint QChar::surrogateToUcs4(ushort high, ushort low)
+
+ Converts a UTF16 surrogate pair with the given \a high and \a low values
+ to its UCS-4 code point.
+*/
+
+/*!
+ \fn static uint QChar::surrogateToUcs4(QChar high, QChar low)
+
+ Converts a utf16 surrogate pair (\a high, \a low) to its ucs4 code
+ point.
+*/
+
+/*!
+ \fn static ushort QChar::highSurrogate(uint ucs4)
+
+ Returns the high surrogate value of a ucs4 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 value of a ucs4 code point.
+ The returned result is undefined if \a ucs4 is smaller than 0x10000.
+*/
+
+/*!
+ Returns the numeric value of the digit, or -1 if the character is
+ not a digit.
+*/
+int QChar::digitValue() const
+{
+ return qGetProp(ucs)->digitValue;
+}
+
+/*!
+ \overload
+ Returns the numeric value of the digit, specified by the UCS-2-encoded
+ character, \a ucs2, or -1 if the character is not a digit.
+*/
+int QChar::digitValue(ushort ucs2)
+{
+ return qGetProp(ucs2)->digitValue;
+}
+
+/*!
+ \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)
+{
+ if (ucs4 > LAST_UNICODE_CHAR)
+ return 0;
+ return qGetProp(ucs4)->digitValue;
+}
+
+/*!
+ Returns the character's category.
+*/
+QChar::Category QChar::category() const
+{
+ return (QChar::Category) qGetProp(ucs)->category;
+}
+
+/*!
+ \overload
+ \since 4.3
+ Returns the category of the UCS-4-encoded character specified by \a ucs4.
+ */
+QChar::Category QChar::category(uint ucs4)
+{
+ if (ucs4 > LAST_UNICODE_CHAR)
+ return QChar::NoCategory;
+ return (QChar::Category) qGetProp(ucs4)->category;
+}
+
+/*!
+ \overload
+ Returns the category of the UCS-2-encoded character specified by \a ucs2.
+ */
+QChar::Category QChar::category(ushort ucs2)
+{
+ return (QChar::Category) qGetProp(ucs2)->category;
+}
+
+
+/*!
+ Returns the character's direction.
+*/
+QChar::Direction QChar::direction() const
+{
+ return (QChar::Direction) qGetProp(ucs)->direction;
+}
+
+/*!
+\overload
+Returns the direction of the UCS-4-encoded character specified by \a ucs4.
+ */
+QChar::Direction QChar::direction(uint ucs4)
+{
+ if (ucs4 > LAST_UNICODE_CHAR)
+ return QChar::DirL;
+ return (QChar::Direction) qGetProp(ucs4)->direction;
+}
+
+/*!
+\overload
+Returns the direction of the UCS-2-encoded character specified by \a ucs2.
+ */
+QChar::Direction QChar::direction(ushort ucs2)
+{
+ return (QChar::Direction) qGetProp(ucs2)->direction;
+}
+
+/*!
+ Returns information about the joining properties of the character
+ (needed for certain languages such as Arabic).
+*/
+QChar::Joining QChar::joining() const
+{
+ return (QChar::Joining) qGetProp(ucs)->joining;
+}
+
+/*!
+\overload
+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)
+{
+ if (ucs4 > LAST_UNICODE_CHAR)
+ return QChar::OtherJoining;
+ return (QChar::Joining) qGetProp(ucs4)->joining;
+}
+
+/*!
+\overload
+Returns information about the joining properties of the UCS-2-encoded
+character specified by \a ucs2 (needed for certain languages such as
+Arabic).
+ */
+QChar::Joining QChar::joining(ushort ucs2)
+{
+ return (QChar::Joining) qGetProp(ucs2)->joining;
+}
+
+
+/*!
+ Returns true if the character should be reversed if the text
+ direction is reversed; otherwise returns false.
+
+ Same as (ch.mirroredChar() != ch).
+
+ \sa mirroredChar()
+*/
+bool QChar::hasMirrored() const
+{
+ return qGetProp(ucs)->mirrorDiff != 0;
+}
+
+/*!
+ \fn bool QChar::isLower() const
+
+ Returns true if the character is a lowercase letter, i.e.
+ category() is Letter_Lowercase.
+
+ \sa isUpper(), toLower(), toUpper()
+*/
+
+/*!
+ \fn bool QChar::isUpper() const
+
+ Returns true if the character is an uppercase letter, i.e.
+ category() is Letter_Uppercase.
+
+ \sa isLower(), toUpper(), toLower()
+*/
+
+/*!
+ \fn bool QChar::isTitleCase() const
+ \since 4.3
+
+ Returns true if the character is a titlecase letter, i.e.
+ category() is Letter_Titlecase.
+
+ \sa isLower(), toUpper(), toLower(), toTitleCase()
+*/
+
+/*!
+ Returns the mirrored character if this character is a mirrored
+ character; otherwise returns the character itself.
+
+ \sa hasMirrored()
+*/
+QChar QChar::mirroredChar() const
+{
+ return ucs + qGetProp(ucs)->mirrorDiff;
+}
+
+/*! \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)
+{
+ if (ucs4 > LAST_UNICODE_CHAR)
+ return ucs4;
+ return ucs4 + qGetProp(ucs4)->mirrorDiff;
+}
+
+/*!
+\overload
+Returns the mirrored character if the UCS-2-encoded character specified
+by \a ucs2 is a mirrored character; otherwise returns the character itself.
+
+\sa hasMirrored()
+ */
+ushort QChar::mirroredChar(ushort ucs2)
+{
+ return ucs2 + qGetProp(ucs2)->mirrorDiff;
+}
+
+
+enum {
+ Hangul_SBase = 0xac00,
+ Hangul_LBase = 0x1100,
+ Hangul_VBase = 0x1161,
+ Hangul_TBase = 0x11a7,
+ Hangul_SCount = 11172,
+ Hangul_LCount = 19,
+ Hangul_VCount = 21,
+ Hangul_TCount = 28,
+ Hangul_NCount = 21*28
+};
+
+// 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)
+{
+ *length = 0;
+ if (ucs4 > LAST_UNICODE_CHAR)
+ return 0;
+ if (ucs4 >= Hangul_SBase && ucs4 < Hangul_SBase + Hangul_SCount) {
+ int 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)
+ return 0;
+ const unsigned short *decomposition = uc_decomposition_map+index;
+ *tag = (*decomposition) & 0xff;
+ *length = (*decomposition) >> 8;
+ return decomposition+1;
+}
+
+/*!
+ Decomposes a character into its parts. Returns an empty string if
+ no decomposition exists.
+*/
+QString QChar::decomposition() const
+{
+ return decomposition(ucs);
+}
+
+/*!
+\overload
+Decomposes the UCS-4-encoded character specified by \a ucs4 into its
+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::fromUtf16(d, length);
+}
+
+/*!
+ Returns the tag defining the composition of the character. Returns
+ QChar::Single if no decomposition exists.
+*/
+QChar::Decomposition QChar::decompositionTag() const
+{
+ return decompositionTag(ucs);
+}
+
+/*!
+\overload
+Returns the tag defining the composition of the UCS-4-encoded character
+specified by \a ucs4. Returns QChar::Single if no decomposition exists.
+ */
+QChar::Decomposition QChar::decompositionTag(uint ucs4)
+{
+ if (ucs4 > LAST_UNICODE_CHAR)
+ return QChar::NoDecomposition;
+ const unsigned short index = GET_DECOMPOSITION_INDEX(ucs4);
+ if (index == 0xffff)
+ return QChar::NoDecomposition;
+ return (QChar::Decomposition)(uc_decomposition_map[index] & 0xff);
+}
+
+/*!
+ 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.
+*/
+unsigned char QChar::combiningClass() const
+{
+ return (unsigned char) qGetProp(ucs)->combiningClass;
+}
+
+/*! \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)
+{
+ if (ucs4 > LAST_UNICODE_CHAR)
+ return 0;
+ return (unsigned char) qGetProp(ucs4)->combiningClass;
+}
+
+/*! \overload
+Returns the combining class for the UCS-2-encoded character specified by
+\a ucs2, as defined in the Unicode standard.
+ */
+unsigned char QChar::combiningClass(ushort ucs2)
+{
+ return (unsigned char) qGetProp(ucs2)->combiningClass;
+}
+
+
+/*!
+ Returns the Unicode version that introduced this character.
+*/
+QChar::UnicodeVersion QChar::unicodeVersion() const
+{
+ return (QChar::UnicodeVersion) qGetProp(ucs)->unicodeVersion;
+}
+
+/*! \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)
+{
+ if (ucs4 > LAST_UNICODE_CHAR)
+ return QChar::Unicode_Unassigned;
+ return (QChar::UnicodeVersion) qGetProp(ucs4)->unicodeVersion;
+}
+
+/*! \overload
+Returns the Unicode version that introduced the character specified in
+its UCS-2-encoded form as \a ucs2.
+ */
+QChar::UnicodeVersion QChar::unicodeVersion(ushort ucs2)
+{
+ return (QChar::UnicodeVersion) qGetProp(ucs2)->unicodeVersion;
+}
+
+
+/*!
+ Returns the lowercase equivalent if the character is uppercase or titlecase;
+ otherwise returns the character itself.
+*/
+QChar QChar::toLower() const
+{
+ const QUnicodeTables::Properties *p = qGetProp(ucs);
+ if (!p->lowerCaseSpecial)
+ return ucs + p->lowerCaseDiff;
+ return ucs;
+}
+
+/*! \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)
+{
+ if (ucs4 > LAST_UNICODE_CHAR)
+ return ucs4;
+ const QUnicodeTables::Properties *p = qGetProp(ucs4);
+ if (!p->lowerCaseSpecial)
+ return ucs4 + p->lowerCaseDiff;
+ return ucs4;
+}
+
+/*! \overload
+Returns the lowercase equivalent of the UCS-2-encoded character specified
+by \a ucs2 if the character is uppercase or titlecase; otherwise returns
+the character itself.
+ */
+ushort QChar::toLower(ushort ucs2)
+{
+ const QUnicodeTables::Properties *p = qGetProp(ucs2);
+ if (!p->lowerCaseSpecial)
+ return ucs2 + p->lowerCaseDiff;
+ return ucs2;
+}
+
+/*!
+ Returns the uppercase equivalent if the character is lowercase or titlecase;
+ otherwise returns the character itself.
+*/
+QChar QChar::toUpper() const
+{
+ const QUnicodeTables::Properties *p = qGetProp(ucs);
+ if (!p->upperCaseSpecial)
+ return ucs + p->upperCaseDiff;
+ return ucs;
+}
+
+/*! \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)
+{
+ if (ucs4 > LAST_UNICODE_CHAR)
+ return ucs4;
+ const QUnicodeTables::Properties *p = qGetProp(ucs4);
+ if (!p->upperCaseSpecial)
+ return ucs4 + p->upperCaseDiff;
+ return ucs4;
+}
+
+/*! \overload
+Returns the uppercase equivalent of the UCS-2-encoded character specified
+by \a ucs2 if the character is lowercase or titlecase; otherwise returns
+the character itself.
+ */
+ushort QChar::toUpper(ushort ucs2)
+{
+ const QUnicodeTables::Properties *p = qGetProp(ucs2);
+ if (!p->upperCaseSpecial)
+ return ucs2 + p->upperCaseDiff;
+ return ucs2;
+}
+
+/*!
+ Returns the title case equivalent if the character is lowercase or uppercase;
+ otherwise returns the character itself.
+*/
+QChar QChar::toTitleCase() const
+{
+ const QUnicodeTables::Properties *p = qGetProp(ucs);
+ if (!p->titleCaseSpecial)
+ return ucs + p->titleCaseDiff;
+ return ucs;
+}
+
+/*!
+ \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)
+{
+ if (ucs4 > LAST_UNICODE_CHAR)
+ return ucs4;
+ const QUnicodeTables::Properties *p = qGetProp(ucs4);
+ if (!p->titleCaseSpecial)
+ return ucs4 + p->titleCaseDiff;
+ return ucs4;
+}
+
+/*!
+ \overload
+ Returns the title case equivalent of the UCS-2-encoded character specified
+ by \a ucs2 if the character is lowercase or uppercase; otherwise returns
+ the character itself.
+*/
+ushort QChar::toTitleCase(ushort ucs2)
+{
+ const QUnicodeTables::Properties *p = qGetProp(ucs2);
+ if (!p->titleCaseSpecial)
+ return ucs2 + p->titleCaseDiff;
+ return ucs2;
+}
+
+
+static inline uint foldCase(const ushort *ch, const ushort *start)
+{
+ uint c = *ch;
+ if (QChar(c).isLowSurrogate() && ch > start && QChar(*(ch - 1)).isHighSurrogate())
+ c = QChar::surrogateToUcs4(*(ch - 1), c);
+ return *ch + qGetProp(c)->caseFoldDiff;
+}
+
+static inline uint foldCase(uint ch, uint &last)
+{
+ uint c = ch;
+ if (QChar(c).isLowSurrogate() && QChar(last).isHighSurrogate())
+ c = QChar::surrogateToUcs4(last, c);
+ last = ch;
+ return ch + qGetProp(c)->caseFoldDiff;
+}
+
+static inline ushort foldCase(ushort ch)
+{
+ return ch + qGetProp(ch)->caseFoldDiff;
+}
+
+/*!
+ Returns the case folded equivalent of the character. For most Unicode characters this
+ is the same as toLowerCase().
+*/
+QChar QChar::toCaseFolded() const
+{
+ return ucs + qGetProp(ucs)->caseFoldDiff;
+}
+
+/*!
+ \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 toLowerCase().
+*/
+uint QChar::toCaseFolded(uint ucs4)
+{
+ if (ucs4 > LAST_UNICODE_CHAR)
+ return ucs4;
+ return ucs4 + qGetProp(ucs4)->caseFoldDiff;
+}
+
+/*!
+ \overload
+ Returns the case folded equivalent of the UCS-2-encoded character specified
+ by \a ucs2. For most Unicode characters this is the same as toLowerCase().
+*/
+ushort QChar::toCaseFolded(ushort ucs2)
+{
+ return ucs2 + qGetProp(ucs2)->caseFoldDiff;
+}
+
+
+/*!
+ \fn char QChar::latin1() const
+
+ Use toLatin1() instead.
+*/
+
+/*!
+ \fn char QChar::ascii() const
+
+ Use toAscii() instead.
+*/
+
+/*!
+ \fn char QChar::toLatin1() const
+
+ Returns the Latin-1 character equivalent to the QChar, or 0. This
+ is mainly useful for non-internationalized software.
+
+ \sa toAscii(), unicode(), QTextCodec::codecForCStrings()
+*/
+
+/*!
+ \fn char QChar::toAscii() const
+ Returns the character value of the QChar obtained using the current
+ codec used to read C strings, or 0 if the character is not representable
+ using this codec. The default codec handles Latin-1 encoded text,
+ but this can be changed to assist developers writing source code using
+ other encodings.
+
+ 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.
+
+ \sa toLatin1(), unicode(), QTextCodec::codecForCStrings()
+*/
+#ifdef Q_COMPILER_MANGLES_RETURN_TYPE
+const char QChar::toAscii() const
+#else
+char QChar::toAscii() const
+#endif
+{
+#ifndef QT_NO_CODEC_FOR_C_STRINGS
+ if (QTextCodec::codecForCStrings())
+ // #####
+ return QTextCodec::codecForCStrings()->fromUnicode(QString(*this)).at(0);
+#endif
+ return ucs > 0xff ? 0 : char(ucs);
+}
+
+/*!
+ \fn QChar QChar::fromLatin1(char c)
+
+ Converts the Latin-1 character \a c to its equivalent QChar. This
+ is mainly useful for non-internationalized software.
+
+ \sa fromAscii(), unicode(), QTextCodec::codecForCStrings()
+*/
+
+/*!
+ Converts the ASCII character \a c to its equivalent QChar. This
+ is mainly useful for non-internationalized software.
+
+ An alternative is to use QLatin1Char.
+
+ \sa fromLatin1(), unicode(), QTextCodec::codecForCStrings()
+*/
+QChar QChar::fromAscii(char c)
+{
+#ifndef QT_NO_CODEC_FOR_C_STRINGS
+ if (QTextCodec::codecForCStrings())
+ // #####
+ return QTextCodec::codecForCStrings()->toUnicode(&c, 1).at(0).unicode();
+#endif
+ return QChar(ushort((uchar)c));
+}
+
+#ifndef QT_NO_DATASTREAM
+/*!
+ \relates QChar
+
+ Writes the char \a chr to the stream \a out.
+
+ \sa {Format of the QDataStream operators}
+ */
+
+QDataStream &operator<<(QDataStream &out, const QChar &chr)
+{
+ out << quint16(chr.unicode());
+ return out;
+}
+
+
+/*!
+ \relates QChar
+
+ Reads a char from the stream \a in into char \a chr.
+
+ \sa {Format of the QDataStream operators}
+ */
+
+QDataStream &operator>>(QDataStream &in, QChar &chr)
+{
+ quint16 u;
+ in >> u;
+ chr.unicode() = ushort(u);
+ return in;
+}
+#endif
+
+/*!
+ \fn ushort & QChar::unicode()
+
+ Returns a reference to the numeric Unicode value of the QChar.
+*/
+
+/*!
+ \fn ushort QChar::unicode() const
+
+ \overload
+*/
+
+/*****************************************************************************
+ Documentation of QChar related functions
+ *****************************************************************************/
+
+/*!
+ \fn bool operator==(QChar c1, QChar c2)
+
+ \relates QChar
+
+ Returns true if \a c1 and \a c2 are the same Unicode character;
+ otherwise returns false.
+*/
+
+/*!
+ \fn int operator!=(QChar c1, QChar c2)
+
+ \relates QChar
+
+ Returns true if \a c1 and \a c2 are not the same Unicode
+ character; otherwise returns false.
+*/
+
+/*!
+ \fn int operator<=(QChar c1, QChar c2)
+
+ \relates QChar
+
+ Returns true if the numeric Unicode value of \a c1 is less than
+ or equal to that of \a c2; otherwise returns false.
+*/
+
+/*!
+ \fn int operator>=(QChar c1, QChar c2)
+
+ \relates QChar
+
+ Returns true if the numeric Unicode value of \a c1 is greater than
+ or equal to that of \a c2; otherwise returns false.
+*/
+
+/*!
+ \fn int operator<(QChar c1, QChar c2)
+
+ \relates QChar
+
+ Returns true if the numeric Unicode value of \a c1 is less than
+ that of \a c2; otherwise returns false.
+*/
+
+/*!
+ \fn int operator>(QChar c1, QChar c2)
+
+ \relates QChar
+
+ Returns true if the numeric Unicode value of \a c1 is greater than
+ that of \a c2; otherwise returns false.
+*/
+
+/*!
+ \fn bool QChar::mirrored() const
+
+ Use hasMirrored() instead.
+*/
+
+/*!
+ \fn QChar QChar::lower() const
+
+ Use toLower() instead.
+*/
+
+/*!
+ \fn QChar QChar::upper() const
+
+ Use toUpper() instead.
+*/
+
+/*!
+ \fn bool QChar::networkOrdered()
+
+ See if QSysInfo::ByteOrder == QSysInfo::BigEndian instead.
+*/
+
+
+// ---------------------------------------------------------------------------
+
+
+static QString decomposeHelper
+ (const QString &str, bool canonical, QChar::UnicodeVersion version)
+{
+ unsigned short buffer[3];
+
+ QString s = str;
+
+ const unsigned short *utf16 = s.utf16();
+ const unsigned short *uc = utf16 + s.length();
+ while (uc != utf16) {
+ 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;
+ int length;
+ int tag;
+ const unsigned short *d = decompositionHelper(ucs4, &length, &tag, buffer);
+ if (!d || (canonical && tag != QChar::Canonical))
+ continue;
+
+ s.replace(uc - utf16, ucs4 > 0x10000 ? 2 : 1, (const QChar *)d, length);
+ // since the insert invalidates the pointers and we do decomposition recursive
+ int pos = uc - utf16;
+ utf16 = s.utf16();
+ uc = utf16 + pos + length;
+ }
+
+ return s;
+}
+
+
+static ushort ligatureHelper(ushort u1, ushort u2)
+{
+ // hangul L-V pair
+ int LIndex = u1 - Hangul_LBase;
+ if (0 <= LIndex && LIndex < Hangul_LCount) {
+ int VIndex = u2 - Hangul_VBase;
+ if (0 <= VIndex && VIndex < Hangul_VCount)
+ return Hangul_SBase + (LIndex * Hangul_VCount + VIndex) * Hangul_TCount;
+ }
+
+ // hangul LV-T pair
+ int SIndex = u1 - Hangul_SBase;
+ if (0 <= SIndex && SIndex < Hangul_SCount && (SIndex % Hangul_TCount) == 0) {
+ int TIndex = u2 - Hangul_TBase;
+ if (0 <= TIndex && 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;
+ ++ligatures;
+ // ### use bsearch
+ for (uint i = 0; i < length; ++i)
+ if (ligatures[2*i] == u1)
+ return ligatures[2*i+1];
+ return 0;
+}
+
+static QString composeHelper(const QString &str)
+{
+ QString s = str;
+
+ if (s.length() < 2)
+ return s;
+
+ // the loop can partly ignore high Unicode as all ligatures are in the BMP
+ int starter = 0;
+ int lastCombining = 0;
+ int pos = 0;
+ while (pos < s.length()) {
+ uint uc = s.utf16()[pos];
+ if (QChar(uc).isHighSurrogate() && pos < s.length()-1) {
+ ushort low = s.utf16()[pos+1];
+ if (QChar(low).isLowSurrogate()) {
+ uc = QChar::surrogateToUcs4(uc, low);
+ ++pos;
+ }
+ }
+ int combining = QChar::combiningClass(uc);
+ if (starter == pos - 1 || combining > lastCombining) {
+ // allowed to form ligature with S
+ QChar ligature = ligatureHelper(s.utf16()[starter], uc);
+ if (ligature.unicode()) {
+ s[starter] = ligature;
+ s.remove(pos, 1);
+ continue;
+ }
+ }
+ if (!combining)
+ starter = pos;
+ lastCombining = combining;
+ ++pos;
+ }
+ return s;
+}
+
+
+static QString canonicalOrderHelper
+ (const QString &str, QChar::UnicodeVersion version)
+{
+ QString s = str;
+ const int l = s.length()-1;
+ int pos = 0;
+ while (pos < l) {
+ int p2 = pos+1;
+ uint u1 = s.at(pos).unicode();
+ if (QChar(u1).isHighSurrogate()) {
+ ushort low = s.at(pos+1).unicode();
+ if (QChar(low).isLowSurrogate()) {
+ p2++;
+ u1 = QChar::surrogateToUcs4(u1, low);
+ if (p2 >= l)
+ break;
+ }
+ }
+ uint u2 = s.at(p2).unicode();
+ if (QChar(u2).isHighSurrogate() && p2 < l-1) {
+ ushort low = s.at(p2+1).unicode();
+ if (QChar(low).isLowSurrogate()) {
+ p2++;
+ u2 = QChar::surrogateToUcs4(u2, low);
+ }
+ }
+
+ int c2 = QChar::combiningClass(u2);
+ if (QChar::unicodeVersion(u2) > version)
+ c2 = 0;
+
+ if (c2 == 0) {
+ pos = p2+1;
+ continue;
+ }
+ int c1 = QChar::combiningClass(u1);
+ if (QChar::unicodeVersion(u1) > version)
+ c1 = 0;
+
+ if (c1 > c2) {
+ QChar *uc = s.data();
+ int p = pos;
+ // exchange characters
+ if (u2 < 0x10000) {
+ uc[p++] = u2;
+ } else {
+ uc[p++] = QChar::highSurrogate(u2);
+ uc[p++] = QChar::lowSurrogate(u2);
+ }
+ if (u1 < 0x10000) {
+ uc[p++] = u1;
+ } else {
+ uc[p++] = QChar::highSurrogate(u1);
+ uc[p++] = QChar::lowSurrogate(u1);
+ }
+ if (pos > 0)
+ --pos;
+ if (pos > 0 && s.at(pos).isLowSurrogate())
+ --pos;
+ } else {
+ ++pos;
+ if (u1 > 0x10000)
+ ++pos;
+ }
+ }
+ return s;
+}
+
+int QT_FASTCALL QUnicodeTables::script(unsigned int uc)
+{
+ if (uc > 0xffff)
+ return Common;
+ int script = uc_scripts[uc >> 7];
+ if (script < ScriptSentinel)
+ return script;
+ script = (((script - ScriptSentinel) * UnicodeBlockSize) + UnicodeBlockCount);
+ script = uc_scripts[script + (uc & 0x7f)];
+ return script;
+}
+
+
+Q_CORE_EXPORT QUnicodeTables::LineBreakClass QT_FASTCALL QUnicodeTables::lineBreakClass(uint ucs4)
+{
+ return (QUnicodeTables::LineBreakClass) qGetProp(ucs4)->line_break_class;
+}
+
+
+QT_END_NAMESPACE
diff --git a/src/corelib/tools/qchar.h b/src/corelib/tools/qchar.h
new file mode 100644
index 0000000000..ccf7e87627
--- /dev/null
+++ b/src/corelib/tools/qchar.h
@@ -0,0 +1,397 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QCHAR_H
+#define QCHAR_H
+
+#include <QtCore/qglobal.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Core)
+
+class QString;
+
+struct QLatin1Char
+{
+public:
+ inline explicit QLatin1Char(char c) : ch(c) {}
+#ifdef Q_COMPILER_MANGLES_RETURN_TYPE
+ inline const char toLatin1() const { return ch; }
+ inline const ushort unicode() const { return ushort(uchar(ch)); }
+#else
+ inline char toLatin1() const { return ch; }
+ inline ushort unicode() const { return ushort(uchar(ch)); }
+#endif
+
+private:
+ char ch;
+};
+
+
+class Q_CORE_EXPORT QChar {
+public:
+ QChar();
+#ifndef QT_NO_CAST_FROM_ASCII
+ QT_ASCII_CAST_WARN_CONSTRUCTOR QChar(char c);
+ QT_ASCII_CAST_WARN_CONSTRUCTOR QChar(uchar c);
+#endif
+ QChar(QLatin1Char ch);
+ QChar(uchar c, uchar r);
+ inline QChar(ushort rc) : ucs(rc){}
+ QChar(short rc);
+ QChar(uint rc);
+ QChar(int rc);
+ enum SpecialCharacter {
+ Null = 0x0000,
+ Nbsp = 0x00a0,
+ ReplacementCharacter = 0xfffd,
+ ObjectReplacementCharacter = 0xfffc,
+ ByteOrderMark = 0xfeff,
+ ByteOrderSwapped = 0xfffe,
+#ifdef QT3_SUPPORT
+ null = Null,
+ replacement = ReplacementCharacter,
+ byteOrderMark = ByteOrderMark,
+ byteOrderSwapped = ByteOrderSwapped,
+ nbsp = Nbsp,
+#endif
+ ParagraphSeparator = 0x2029,
+ LineSeparator = 0x2028
+ };
+ QChar(SpecialCharacter sc);
+
+ // Unicode information
+
+ enum Category
+ {
+ NoCategory,
+
+ 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
+
+ Punctuation_Dask = Punctuation_Dash // oops
+ };
+
+ enum Direction
+ {
+ DirL, DirR, DirEN, DirES, DirET, DirAN, DirCS, DirB, DirS, DirWS, DirON,
+ DirLRE, DirLRO, DirAL, DirRLE, DirRLO, DirPDF, DirNSM, DirBN
+ };
+
+ enum Decomposition
+ {
+ NoDecomposition,
+ Canonical,
+ Font,
+ NoBreak,
+ Initial,
+ Medial,
+ Final,
+ Isolated,
+ Circle,
+ Super,
+ Sub,
+ Vertical,
+ Wide,
+ Narrow,
+ Small,
+ Square,
+ Compat,
+ Fraction
+
+#ifdef QT3_SUPPORT
+ , Single = NoDecomposition
+#endif
+ };
+
+ enum Joining
+ {
+ OtherJoining, Dual, Right, Center
+ };
+
+ 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
+ };
+ // ****** WHEN ADDING FUNCTIONS, CONSIDER ADDING TO QCharRef TOO
+
+ Category category() const;
+ Direction direction() const;
+ Joining joining() const;
+ bool hasMirrored() const;
+ unsigned char combiningClass() const;
+
+ QChar mirroredChar() const;
+ QString decomposition() const;
+ Decomposition decompositionTag() const;
+
+ int digitValue() const;
+ QChar toLower() const;
+ QChar toUpper() const;
+ QChar toTitleCase() const;
+ QChar toCaseFolded() const;
+
+ UnicodeVersion unicodeVersion() const;
+
+#ifdef Q_COMPILER_MANGLES_RETURN_TYPE
+ const char toAscii() const;
+ inline const char toLatin1() const;
+ inline const ushort unicode() const { return ucs; }
+#else
+ char toAscii() const;
+ inline char toLatin1() const;
+ inline ushort unicode() const { return ucs; }
+#endif
+#ifdef Q_NO_PACKED_REFERENCE
+ inline ushort &unicode() { return const_cast<ushort&>(ucs); }
+#else
+ inline ushort &unicode() { return ucs; }
+#endif
+
+ static QChar fromAscii(char c);
+ static QChar fromLatin1(char c);
+
+ inline bool isNull() const { return ucs == 0; }
+ bool isPrint() const;
+ bool isPunct() const;
+ bool isSpace() const;
+ bool isMark() const;
+ bool isLetter() const;
+ bool isNumber() const;
+ bool isLetterOrNumber() const;
+ bool isDigit() const;
+ bool isSymbol() const;
+ inline bool isLower() const { return category() == Letter_Lowercase; }
+ inline bool isUpper() const { return category() == Letter_Uppercase; }
+ inline bool isTitleCase() const { return category() == Letter_Titlecase; }
+
+ inline bool isHighSurrogate() const {
+ return ((ucs & 0xfc00) == 0xd800);
+ }
+ inline bool isLowSurrogate() const {
+ return ((ucs & 0xfc00) == 0xdc00);
+ }
+
+ inline uchar cell() const { return uchar(ucs & 0xff); }
+ inline uchar row() const { return uchar((ucs>>8)&0xff); }
+ inline void setCell(uchar cell);
+ inline void setRow(uchar row);
+
+ static inline uint surrogateToUcs4(ushort high, ushort low) {
+ return (uint(high)<<10) + low - 0x35fdc00;
+ }
+ static inline uint surrogateToUcs4(QChar high, QChar low) {
+ return (uint(high.ucs)<<10) + low.ucs - 0x35fdc00;
+ }
+ static inline ushort highSurrogate(uint ucs4) {
+ return (ucs4>>10) + 0xd7c0;
+ }
+ static inline ushort lowSurrogate(uint ucs4) {
+ return ucs4%0x400 + 0xdc00;
+ }
+
+ static Category QT_FASTCALL category(uint ucs4);
+ static Category QT_FASTCALL category(ushort ucs2);
+ static Direction QT_FASTCALL direction(uint ucs4);
+ static Direction QT_FASTCALL direction(ushort ucs2);
+ static Joining QT_FASTCALL joining(uint ucs4);
+ static Joining QT_FASTCALL joining(ushort ucs2);
+ static unsigned char QT_FASTCALL combiningClass(uint ucs4);
+ static unsigned char QT_FASTCALL combiningClass(ushort ucs2);
+
+ static uint QT_FASTCALL mirroredChar(uint ucs4);
+ static ushort QT_FASTCALL mirroredChar(ushort ucs2);
+ static Decomposition QT_FASTCALL decompositionTag(uint ucs4);
+
+ static int QT_FASTCALL digitValue(uint ucs4);
+ static int QT_FASTCALL digitValue(ushort ucs2);
+ static uint QT_FASTCALL toLower(uint ucs4);
+ static ushort QT_FASTCALL toLower(ushort ucs2);
+ static uint QT_FASTCALL toUpper(uint ucs4);
+ static ushort QT_FASTCALL toUpper(ushort ucs2);
+ static uint QT_FASTCALL toTitleCase(uint ucs4);
+ static ushort QT_FASTCALL toTitleCase(ushort ucs2);
+ static uint QT_FASTCALL toCaseFolded(uint ucs4);
+ static ushort QT_FASTCALL toCaseFolded(ushort ucs2);
+
+ static UnicodeVersion QT_FASTCALL unicodeVersion(uint ucs4);
+ static UnicodeVersion QT_FASTCALL unicodeVersion(ushort ucs2);
+
+ static QString QT_FASTCALL decomposition(uint ucs4);
+
+#ifdef QT3_SUPPORT
+ inline QT3_SUPPORT bool mirrored() const { return hasMirrored(); }
+ inline QT3_SUPPORT QChar lower() const { return toLower(); }
+ inline QT3_SUPPORT QChar upper() const { return toUpper(); }
+ static inline QT3_SUPPORT bool networkOrdered() {
+ return QSysInfo::ByteOrder == QSysInfo::BigEndian;
+ }
+#ifdef Q_COMPILER_MANGLES_RETURN_TYPE
+ inline QT3_SUPPORT const char latin1() const { return toLatin1(); }
+ inline QT3_SUPPORT const char ascii() const { return toAscii(); }
+#else
+ inline QT3_SUPPORT char latin1() const { return toLatin1(); }
+ inline QT3_SUPPORT char ascii() const { return toAscii(); }
+#endif
+#endif
+
+private:
+#ifdef QT_NO_CAST_FROM_ASCII
+ QChar(char c);
+ QChar(uchar c);
+#endif
+ ushort ucs;
+}
+#if (defined(__arm__) || defined(__ARMEL__))
+ Q_PACKED
+#endif
+ ;
+
+Q_DECLARE_TYPEINFO(QChar, Q_MOVABLE_TYPE);
+
+inline QChar::QChar() : ucs(0) {}
+
+#ifdef Q_COMPILER_MANGLES_RETURN_TYPE
+inline const char QChar::toLatin1() const { return ucs > 0xff ? '\0' : char(ucs); }
+#else
+inline char QChar::toLatin1() const { return ucs > 0xff ? '\0' : char(ucs); }
+#endif
+inline QChar QChar::fromLatin1(char c) { return QChar(ushort(uchar(c))); }
+
+inline QChar::QChar(uchar c, uchar r) : ucs((r << 8) | c){}
+inline QChar::QChar(short rc) : ucs(ushort(rc)){}
+inline QChar::QChar(uint rc) : ucs(ushort(rc & 0xffff)){}
+inline QChar::QChar(int rc) : ucs(ushort(rc & 0xffff)){}
+inline QChar::QChar(SpecialCharacter s) : ucs(ushort(s)) {}
+inline QChar::QChar(QLatin1Char ch) : ucs(ch.unicode()) {}
+
+inline void QChar::setCell(uchar acell)
+{ ucs = (ucs & 0xff00) + acell; }
+inline void QChar::setRow(uchar arow)
+{ ucs = (ushort(arow)<<8) + (ucs&0xff); }
+
+inline bool operator==(QChar c1, QChar c2) { return c1.unicode() == c2.unicode(); }
+inline bool operator!=(QChar c1, QChar c2) { return c1.unicode() != c2.unicode(); }
+inline bool operator<=(QChar c1, QChar c2) { return c1.unicode() <= c2.unicode(); }
+inline bool operator>=(QChar c1, QChar c2) { return c1.unicode() >= c2.unicode(); }
+inline bool operator<(QChar c1, QChar c2) { return c1.unicode() < c2.unicode(); }
+inline bool operator>(QChar c1, QChar c2) { return c1.unicode() > c2.unicode(); }
+
+#ifndef QT_NO_DATASTREAM
+Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QChar &);
+Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QChar &);
+#endif
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QCHAR_H
diff --git a/src/corelib/tools/qcontainerfwd.h b/src/corelib/tools/qcontainerfwd.h
new file mode 100644
index 0000000000..8af9557aaa
--- /dev/null
+++ b/src/corelib/tools/qcontainerfwd.h
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QCONTAINERFWD_H
+#define QCONTAINERFWD_H
+
+#include <QtCore/qglobal.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Core)
+
+template <class Key, class T> class QCache;
+template <class Key, class T> class QHash;
+template <class T> class QLinkedList;
+template <class T> class QList;
+template <class Key, class T> class QMap;
+template <class Key, class T> class QMultiHash;
+template <class Key, class T> class QMultiMap;
+template <class T1, class T2> struct QPair;
+template <class T> class QQueue;
+template <class T> class QSet;
+template <class T> class QStack;
+template<class T, int Prealloc = 256> class QVarLengthArray;
+template <class T> class QVector;
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QCONTAINERFWD_H
diff --git a/src/corelib/tools/qcryptographichash.cpp b/src/corelib/tools/qcryptographichash.cpp
new file mode 100644
index 0000000000..723262627b
--- /dev/null
+++ b/src/corelib/tools/qcryptographichash.cpp
@@ -0,0 +1,196 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qcryptographichash.h>
+
+#include "../../3rdparty/md5/md5.h"
+#include "../../3rdparty/md5/md5.cpp"
+#include "../../3rdparty/md4/md4.h"
+#include "../../3rdparty/md4/md4.cpp"
+#include "../../3rdparty/sha1/sha1.cpp"
+
+
+QT_BEGIN_NAMESPACE
+
+class QCryptographicHashPrivate
+{
+public:
+ QCryptographicHash::Algorithm method;
+ union {
+ MD5Context md5Context;
+ md4_context md4Context;
+ Sha1State sha1Context;
+ };
+ QByteArray result;
+};
+
+/*!
+ \class QCryptographicHash
+
+ \brief The QCryptographicHash class provides a way to generate cryptographic hashes.
+
+ \since 4.3
+
+ \ingroup tools
+ \reentrant
+
+ QCryptographicHash can be used to generate cryptographic hashes of binary or text data.
+
+ Currently MD4, MD5, and SHA1 are supported.
+*/
+
+/*!
+ \enum QCryptographicHash::Algorithm
+
+ \value Md4 Generate an MD4 hash sum
+ \value Md5 Generate an MD5 hash sum
+ \value Sha1 Generate an SHA1 hash sum
+*/
+
+/*!
+ Constructs an object that can be used to create a cryptographic hash from data using \a method.
+*/
+QCryptographicHash::QCryptographicHash(Algorithm method)
+ : d(new QCryptographicHashPrivate)
+{
+ d->method = method;
+ reset();
+}
+
+/*!
+ Destroys the object.
+*/
+QCryptographicHash::~QCryptographicHash()
+{
+ delete d;
+}
+
+/*!
+ Resets the object.
+*/
+void QCryptographicHash::reset()
+{
+ switch (d->method) {
+ case Md4:
+ md4_init(&d->md4Context);
+ break;
+ case Md5:
+ MD5Init(&d->md5Context);
+ break;
+ case Sha1:
+ sha1InitState(&d->sha1Context);
+ break;
+ }
+ d->result.clear();
+}
+
+/*!
+ Adds the first \a length chars of \a data to the cryptographic
+ hash.
+*/
+void QCryptographicHash::addData(const char *data, int length)
+{
+ switch (d->method) {
+ case Md4:
+ md4_update(&d->md4Context, (const unsigned char *)data, length);
+ break;
+ case Md5:
+ MD5Update(&d->md5Context, (const unsigned char *)data, length);
+ break;
+ case Sha1:
+ sha1Update(&d->sha1Context, (const unsigned char *)data, length);
+ break;
+ }
+ d->result.clear();
+}
+
+/*!
+ /overload
+*/
+void QCryptographicHash::addData(const QByteArray &data)
+{
+ addData(data.constData(), data.length());
+}
+
+/*!
+ Returns the final hash value.
+
+ \sa QByteArray::toHex()
+*/
+QByteArray QCryptographicHash::result() const
+{
+ if (!d->result.isEmpty())
+ return d->result;
+
+ switch (d->method) {
+ case Md4: {
+ md4_context copy = d->md4Context;
+ d->result.resize(MD4_RESULTLEN);
+ md4_final(&copy, (unsigned char *)d->result.data());
+ break;
+ }
+ case Md5: {
+ MD5Context copy = d->md5Context;
+ d->result.resize(16);
+ MD5Final(&copy, (unsigned char *)d->result.data());
+ break;
+ }
+ case Sha1: {
+ Sha1State copy = d->sha1Context;
+ d->result.resize(20);
+ sha1FinalizeState(&copy);
+ sha1ToHash(&copy, (unsigned char *)d->result.data());
+ }
+ }
+ return d->result;
+}
+
+/*!
+ Returns the hash of \a data using \a method.
+*/
+QByteArray QCryptographicHash::hash(const QByteArray &data, Algorithm method)
+{
+ QCryptographicHash hash(method);
+ hash.addData(data);
+ return hash.result();
+}
+
+QT_END_NAMESPACE
diff --git a/src/corelib/tools/qcryptographichash.h b/src/corelib/tools/qcryptographichash.h
new file mode 100644
index 0000000000..ab549e650c
--- /dev/null
+++ b/src/corelib/tools/qcryptographichash.h
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QCRYPTOGRAPHICSHASH_H
+#define QCRYPTOGRAPHICSHASH_H
+
+#include <QtCore/qbytearray.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Core)
+
+class QCryptographicHashPrivate;
+
+class Q_CORE_EXPORT QCryptographicHash
+{
+public:
+ enum Algorithm {
+ Md4,
+ Md5,
+ Sha1
+ };
+
+ QCryptographicHash(Algorithm method);
+ ~QCryptographicHash();
+
+ void reset();
+
+ void addData(const char *data, int length);
+ void addData(const QByteArray &data);
+
+ QByteArray result() const;
+
+ static QByteArray hash(const QByteArray &data, Algorithm method);
+private:
+ Q_DISABLE_COPY(QCryptographicHash)
+ QCryptographicHashPrivate *d;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/corelib/tools/qdatetime.cpp b/src/corelib/tools/qdatetime.cpp
new file mode 100644
index 0000000000..781514c811
--- /dev/null
+++ b/src/corelib/tools/qdatetime.cpp
@@ -0,0 +1,5506 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qplatformdefs.h"
+#include "private/qdatetime_p.h"
+
+#include "qdatastream.h"
+#include "qset.h"
+#include "qlocale.h"
+#include "qdatetime.h"
+#include "qregexp.h"
+#include "qdebug.h"
+#if defined(Q_OS_WIN32) || defined(Q_OS_WINCE)
+#include <windows.h>
+#endif
+#ifndef Q_WS_WIN
+#include <locale.h>
+#endif
+
+#include <time.h>
+#if defined(Q_OS_WINCE)
+#include "qfunctions_wince.h"
+#endif
+
+//#define QDATETIMEPARSER_DEBUG
+#if defined (QDATETIMEPARSER_DEBUG) && !defined(QT_NO_DEBUG_STREAM)
+# define QDTPDEBUG qDebug() << QString("%1:%2").arg(__FILE__).arg(__LINE__)
+# define QDTPDEBUGN qDebug
+#else
+# define QDTPDEBUG if (false) qDebug()
+# define QDTPDEBUGN if (false) qDebug
+#endif
+
+#if defined(Q_WS_MAC)
+#include <private/qcore_mac_p.h>
+#endif
+
+QT_BEGIN_NAMESPACE
+
+enum {
+ FIRST_YEAR = -4713,
+ FIRST_MONTH = 1,
+ FIRST_DAY = 2, // ### Qt 5: make FIRST_DAY = 1, by support jd == 0 as valid
+ SECS_PER_DAY = 86400,
+ MSECS_PER_DAY = 86400000,
+ SECS_PER_HOUR = 3600,
+ MSECS_PER_HOUR = 3600000,
+ SECS_PER_MIN = 60,
+ MSECS_PER_MIN = 60000
+};
+
+static inline QDate fixedDate(int y, int m, int d)
+{
+ QDate result(y, m, 1);
+ result.setDate(y, m, qMin(d, result.daysInMonth()));
+ return result;
+}
+
+static uint julianDayFromDate(int year, int month, int day)
+{
+ if (year < 0)
+ ++year;
+
+ if (year > 1582 || (year == 1582 && (month > 10 || (month == 10 && day >= 15)))) {
+ // Gregorian calendar starting from October 15, 1582
+ // Algorithm from Henry F. Fliegel and Thomas C. Van Flandern
+ return (1461 * (year + 4800 + (month - 14) / 12)) / 4
+ + (367 * (month - 2 - 12 * ((month - 14) / 12))) / 12
+ - (3 * ((year + 4900 + (month - 14) / 12) / 100)) / 4
+ + day - 32075;
+ } else if (year < 1582 || (year == 1582 && (month < 10 || (month == 10 && day <= 4)))) {
+ // Julian calendar until October 4, 1582
+ // Algorithm from Frequently Asked Questions about Calendars by Claus Toendering
+ int a = (14 - month) / 12;
+ return (153 * (month + (12 * a) - 3) + 2) / 5
+ + (1461 * (year + 4800 - a)) / 4
+ + day - 32083;
+ } else {
+ // the day following October 4, 1582 is October 15, 1582
+ return 0;
+ }
+}
+
+static void getDateFromJulianDay(uint julianDay, int *year, int *month, int *day)
+{
+ int y, m, d;
+
+ if (julianDay >= 2299161) {
+ // Gregorian calendar starting from October 15, 1582
+ // This algorithm is from Henry F. Fliegel and Thomas C. Van Flandern
+ qulonglong ell, n, i, j;
+ ell = qulonglong(julianDay) + 68569;
+ n = (4 * ell) / 146097;
+ ell = ell - (146097 * n + 3) / 4;
+ i = (4000 * (ell + 1)) / 1461001;
+ ell = ell - (1461 * i) / 4 + 31;
+ j = (80 * ell) / 2447;
+ d = ell - (2447 * j) / 80;
+ ell = j / 11;
+ m = j + 2 - (12 * ell);
+ y = 100 * (n - 49) + i + ell;
+ } else {
+ // Julian calendar until October 4, 1582
+ // Algorithm from Frequently Asked Questions about Calendars by Claus Toendering
+ julianDay += 32082;
+ int dd = (4 * julianDay + 3) / 1461;
+ int ee = julianDay - (1461 * dd) / 4;
+ int mm = ((5 * ee) + 2) / 153;
+ d = ee - (153 * mm + 2) / 5 + 1;
+ m = mm + 3 - 12 * (mm / 10);
+ y = dd - 4800 + (mm / 10);
+ if (y <= 0)
+ --y;
+ }
+ if (year)
+ *year = y;
+ if (month)
+ *month = m;
+ if (day)
+ *day = d;
+}
+
+
+static const char monthDays[] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+
+#ifndef QT_NO_TEXTDATE
+static const char * const qt_shortMonthNames[] = {
+ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
+#endif
+#ifndef QT_NO_DATESTRING
+static QString fmtDateTime(const QString& f, const QTime* dt = 0, const QDate* dd = 0);
+#endif
+
+/*****************************************************************************
+ QDate member functions
+ *****************************************************************************/
+
+/*!
+ \since 4.5
+
+ \enum QDate::MonthNameType
+
+ This enum describes the types of the string representation used
+ for the month name.
+
+ \value DateFormat This type of name can be used for date-to-string formatting.
+ \value StandaloneFormat This type is used when you need to enumerate months or weekdays.
+ Usually standalone names are represented in singular forms with
+ capitalized first letter.
+*/
+
+/*!
+ \class QDate
+ \reentrant
+ \brief The QDate class provides date functions.
+
+ \ingroup time
+ \mainclass
+
+ A QDate object contains a calendar date, i.e. year, month, and day
+ numbers, in the Gregorian calendar. (see \l{QDate G and J} {Use of
+ Gregorian and Julian Calendars} for dates prior to 15 October
+ 1582). It can read the current date from the system clock. It
+ provides functions for comparing dates, and for manipulating
+ dates. For example, it is possible to add and subtract days,
+ months, and years to dates.
+
+ A QDate object is typically created either by giving the year,
+ month, and day numbers explicitly. Note that QDate interprets two
+ digit years as is, i.e., years 0 - 99. A QDate can also be
+ constructed with the static function currentDate(), which creates
+ a QDate object containing the system clock's date. An explicit
+ date can also be set using setDate(). The fromString() function
+ returns a QDate given a string and a date format which is used to
+ interpret the date within the string.
+
+ The year(), month(), and day() functions provide access to the
+ year, month, and day numbers. Also, dayOfWeek() and dayOfYear()
+ functions are provided. The same information is provided in
+ textual format by the toString(), shortDayName(), longDayName(),
+ shortMonthName(), and longMonthName() functions.
+
+ QDate provides a full set of operators to compare two QDate
+ objects where smaller means earlier, and larger means later.
+
+ You can increment (or decrement) a date by a given number of days
+ using addDays(). Similarly you can use addMonths() and addYears().
+ The daysTo() function returns the number of days between two
+ dates.
+
+ The daysInMonth() and daysInYear() functions return how many days
+ there are in this date's month and year, respectively. The
+ isLeapYear() function indicates whether a date is in a leap year.
+
+ \section1
+
+ \target QDate G and J
+ \section2 Use of Gregorian and Julian Calendars
+
+ QDate uses the Gregorian calendar in all locales, beginning
+ on the date 15 October 1582. For dates up to and including 4
+ October 1582, the Julian calendar is used. This means there is a
+ 10-day gap in the internal calendar between the 4th and the 15th
+ of October 1582. When you use QDateTime for dates in that epoch,
+ the day after 4 October 1582 is 15 October 1582, and the dates in
+ the gap are invalid.
+
+ The Julian to Gregorian changeover date used here is the date when
+ the Gregorian calendar was first introduced, by Pope Gregory
+ XIII. That change was not universally accepted and some localities
+ only executed it at a later date (if at all). QDateTime
+ doesn't take any of these historical facts into account. If an
+ application must support a locale-specific dating system, it must
+ do so on its own, remembering to convert the dates using the
+ Julian day.
+
+ \section2 No Year 0
+
+ There is no year 0. Dates in that year are considered invalid. The
+ year -1 is the year "1 before Christ" or "1 before current era."
+ The day before 0001-01-01 is December 31st, 1 BCE.
+
+ \section2 Range of Valid Dates
+
+ The range of valid dates is from January 2nd, 4713 BCE, to
+ sometime in the year 11 million CE. The Julian Day returned by
+ QDate::toJulianDay() is a number in the contiguous range from 1 to
+ \e{overflow}, even across QDateTime's "date holes". It is suitable
+ for use in applications that must convert a QDateTime to a date in
+ another calendar system, e.g., Hebrew, Islamic or Chinese.
+
+ \sa QTime, QDateTime, QDateEdit, QDateTimeEdit, QCalendarWidget
+*/
+
+/*!
+ \fn QDate::QDate()
+
+ Constructs a null date. Null dates are invalid.
+
+ \sa isNull(), isValid()
+*/
+
+/*!
+ Constructs a date with year \a y, month \a m and day \a d.
+
+ If the specified date is invalid, the date is not set and
+ isValid() returns false. A date before 2 January 4713 B.C. is
+ considered invalid.
+
+ \warning Years 0 to 99 are interpreted as is, i.e., years
+ 0-99.
+
+ \sa isValid()
+*/
+
+QDate::QDate(int y, int m, int d)
+{
+ setDate(y, m, d);
+}
+
+
+/*!
+ \fn bool QDate::isNull() const
+
+ Returns true if the date is null; otherwise returns false. A null
+ date is invalid.
+
+ \note The behavior of this function is equivalent to isValid().
+
+ \sa isValid()
+*/
+
+
+/*!
+ Returns true if this date is valid; otherwise returns false.
+
+ \sa isNull()
+*/
+
+bool QDate::isValid() const
+{
+ return !isNull();
+}
+
+
+/*!
+ Returns the year of this date. Negative numbers indicate years
+ before 1 A.D. = 1 C.E., such that year -44 is 44 B.C.
+
+ \sa month(), day()
+*/
+
+int QDate::year() const
+{
+ int y;
+ getDateFromJulianDay(jd, &y, 0, 0);
+ return y;
+}
+
+/*!
+ Returns the number corresponding to the month of this date, using
+ the following convention:
+
+ \list
+ \i 1 = "January"
+ \i 2 = "February"
+ \i 3 = "March"
+ \i 4 = "April"
+ \i 5 = "May"
+ \i 6 = "June"
+ \i 7 = "July"
+ \i 8 = "August"
+ \i 9 = "September"
+ \i 10 = "October"
+ \i 11 = "November"
+ \i 12 = "December"
+ \endlist
+
+ \sa year(), day()
+*/
+
+int QDate::month() const
+{
+ int m;
+ getDateFromJulianDay(jd, 0, &m, 0);
+ return m;
+}
+
+/*!
+ Returns the day of the month (1 to 31) of this date.
+
+ \sa year(), month(), dayOfWeek()
+*/
+
+int QDate::day() const
+{
+ int d;
+ getDateFromJulianDay(jd, 0, 0, &d);
+ return d;
+}
+
+/*!
+ Returns the weekday (1 to 7) for this date.
+
+ \sa day(), dayOfYear(), Qt::DayOfWeek
+*/
+
+int QDate::dayOfWeek() const
+{
+ return (jd % 7) + 1;
+}
+
+/*!
+ Returns the day of the year (1 to 365 or 366 on leap years) for
+ this date.
+
+ \sa day(), dayOfWeek()
+*/
+
+int QDate::dayOfYear() const
+{
+ return jd - julianDayFromDate(year(), 1, 1) + 1;
+}
+
+/*!
+ Returns the number of days in the month (28 to 31) for this date.
+
+ \sa day(), daysInYear()
+*/
+
+int QDate::daysInMonth() const
+{
+ int y, m, d;
+ getDateFromJulianDay(jd, &y, &m, &d);
+ if (m == 2 && isLeapYear(y))
+ return 29;
+ else
+ return monthDays[m];
+}
+
+/*!
+ Returns the number of days in the year (365 or 366) for this date.
+
+ \sa day(), daysInMonth()
+*/
+
+int QDate::daysInYear() const
+{
+ int y, m, d;
+ getDateFromJulianDay(jd, &y, &m, &d);
+ return isLeapYear(y) ? 366 : 365;
+}
+
+/*!
+ Returns the week number (1 to 53), and stores the year in
+ *\a{yearNumber} unless \a yearNumber is null (the default).
+
+ Returns 0 if the date is invalid.
+
+ In accordance with ISO 8601, weeks start on Monday and the first
+ Thursday of a year is always in week 1 of that year. Most years
+ have 52 weeks, but some have 53.
+
+ *\a{yearNumber} is not always the same as year(). For example, 1
+ January 2000 has week number 52 in the year 1999, and 31 December
+ 2002 has week number 1 in the year 2003.
+
+ \legalese
+ Copyright (c) 1989 The Regents of the University of California.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms are permitted
+ provided that the above copyright notice and this paragraph are
+ duplicated in all such forms and that any documentation,
+ advertising materials, and other materials related to such
+ distribution and use acknowledge that the software was developed
+ by the University of California, Berkeley. The name of the
+ University may not be used to endorse or promote products derived
+ from this software without specific prior written permission.
+ THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+
+ \sa isValid()
+*/
+
+int QDate::weekNumber(int *yearNumber) const
+{
+ if (!isValid())
+ return 0;
+
+ int year = QDate::year();
+ int yday = dayOfYear() - 1;
+ int wday = dayOfWeek();
+ if (wday == 7)
+ wday = 0;
+ int w;
+
+ for (;;) {
+ int len;
+ int bot;
+ int top;
+
+ len = isLeapYear(year) ? 366 : 365;
+ /*
+ ** What yday (-3 ... 3) does
+ ** the ISO year begin on?
+ */
+ bot = ((yday + 11 - wday) % 7) - 3;
+ /*
+ ** What yday does the NEXT
+ ** ISO year begin on?
+ */
+ top = bot - (len % 7);
+ if (top < -3)
+ top += 7;
+ top += len;
+ if (yday >= top) {
+ ++year;
+ w = 1;
+ break;
+ }
+ if (yday >= bot) {
+ w = 1 + ((yday - bot) / 7);
+ break;
+ }
+ --year;
+ yday += isLeapYear(year) ? 366 : 365;
+ }
+ if (yearNumber != 0)
+ *yearNumber = year;
+ return w;
+}
+
+#ifndef QT_NO_TEXTDATE
+/*!
+ \since 4.5
+
+ Returns the short name of the \a month for the representation specified
+ by \a type.
+
+ The months are enumerated using the following convention:
+
+ \list
+ \i 1 = "Jan"
+ \i 2 = "Feb"
+ \i 3 = "Mar"
+ \i 4 = "Apr"
+ \i 5 = "May"
+ \i 6 = "Jun"
+ \i 7 = "Jul"
+ \i 8 = "Aug"
+ \i 9 = "Sep"
+ \i 10 = "Oct"
+ \i 11 = "Nov"
+ \i 12 = "Dec"
+ \endlist
+
+ The month names will be localized according to the system's locale
+ settings.
+
+ \sa toString(), longMonthName(), shortDayName(), longDayName()
+*/
+
+QString QDate::shortMonthName(int month, QDate::MonthNameType type)
+{
+ if (month < 1 || month > 12) {
+ month = 1;
+ }
+ switch (type) {
+ case QDate::DateFormat:
+ return QLocale::system().monthName(month, QLocale::ShortFormat);
+ case QDate::StandaloneFormat:
+ return QLocale::system().standaloneMonthName(month, QLocale::ShortFormat);
+ default:
+ break;
+ }
+ return QString();
+}
+
+/*!
+ Returns the short version of the name of the \a month. The
+ returned name is in normal type which can be used for date formatting.
+
+ \sa toString(), longMonthName(), shortDayName(), longDayName()
+ */
+
+QString QDate::shortMonthName(int month)
+{
+ return shortMonthName(month, QDate::DateFormat);
+}
+
+/*!
+ \since 4.5
+
+ Returns the long name of the \a month for the representation specified
+ by \a type.
+
+ The months are enumerated using the following convention:
+
+ \list
+ \i 1 = "January"
+ \i 2 = "February"
+ \i 3 = "March"
+ \i 4 = "April"
+ \i 5 = "May"
+ \i 6 = "June"
+ \i 7 = "July"
+ \i 8 = "August"
+ \i 9 = "September"
+ \i 10 = "October"
+ \i 11 = "November"
+ \i 12 = "December"
+ \endlist
+
+ The month names will be localized according to the system's locale
+ settings.
+
+ \sa toString(), shortMonthName(), shortDayName(), longDayName()
+*/
+
+QString QDate::longMonthName(int month, MonthNameType type)
+{
+ if (month < 1 || month > 12) {
+ month = 1;
+ }
+ switch (type) {
+ case QDate::DateFormat:
+ return QLocale::system().monthName(month, QLocale::LongFormat);
+ case QDate::StandaloneFormat:
+ return QLocale::system().standaloneMonthName(month, QLocale::LongFormat);
+ default:
+ break;
+ }
+ return QString();
+}
+
+/*!
+ Returns the long version of the name of the \a month. The
+ returned name is in normal type which can be used for date formatting.
+
+ \sa toString(), shortMonthName(), shortDayName(), longDayName()
+ */
+
+QString QDate::longMonthName(int month)
+{
+ if (month < 1 || month > 12) {
+ month = 1;
+ }
+ return QLocale::system().monthName(month, QLocale::LongFormat);
+}
+
+/*!
+ \since 4.5
+
+ Returns the short name of the \a weekday for the representation specified
+ by \a type.
+
+ The days are enumerated using the following convention:
+
+ \list
+ \i 1 = "Mon"
+ \i 2 = "Tue"
+ \i 3 = "Wed"
+ \i 4 = "Thu"
+ \i 5 = "Fri"
+ \i 6 = "Sat"
+ \i 7 = "Sun"
+ \endlist
+
+ The day names will be localized according to the system's locale
+ settings.
+
+ \sa toString(), shortMonthName(), longMonthName(), longDayName()
+*/
+
+QString QDate::shortDayName(int weekday, MonthNameType type)
+{
+ if (weekday < 1 || weekday > 7) {
+ weekday = 1;
+ }
+ switch (type) {
+ case QDate::DateFormat:
+ return QLocale::system().dayName(weekday, QLocale::ShortFormat);
+ case QDate::StandaloneFormat:
+ return QLocale::system().standaloneDayName(weekday, QLocale::ShortFormat);
+ default:
+ break;
+ }
+ return QString();
+}
+
+/*!
+ Returns the short version of the name of the \a weekday. The
+ returned name is in normal type which can be used for date formatting.
+
+ \sa toString(), longDayName(), shortMonthName(), longMonthName()
+ */
+
+QString QDate::shortDayName(int weekday)
+{
+ if (weekday < 1 || weekday > 7) {
+ weekday = 1;
+ }
+ return QLocale::system().dayName(weekday, QLocale::ShortFormat);
+}
+
+/*!
+ \since 4.5
+
+ Returns the long name of the \a weekday for the representation specified
+ by \a type.
+
+ The days are enumerated using the following convention:
+
+ \list
+ \i 1 = "Monday"
+ \i 2 = "Tuesday"
+ \i 3 = "Wednesday"
+ \i 4 = "Thursday"
+ \i 5 = "Friday"
+ \i 6 = "Saturday"
+ \i 7 = "Sunday"
+ \endlist
+
+ The day names will be localized according to the system's locale
+ settings.
+
+ \sa toString(), shortDayName(), shortMonthName(), longMonthName()
+*/
+
+QString QDate::longDayName(int weekday, MonthNameType type)
+{
+ if (weekday < 1 || weekday > 7) {
+ weekday = 1;
+ }
+ switch (type) {
+ case QDate::DateFormat:
+ return QLocale::system().dayName(weekday, QLocale::LongFormat);
+ case QDate::StandaloneFormat:
+ return QLocale::system().standaloneDayName(weekday, QLocale::LongFormat);
+ default:
+ break;
+ }
+ return QLocale::system().dayName(weekday, QLocale::LongFormat);
+}
+
+/*!
+ Returns the long version of the name of the \a weekday. The
+ returned name is in normal type which can be used for date formatting.
+
+ \sa toString(), shortDayName(), shortMonthName(), longMonthName()
+ */
+
+QString QDate::longDayName(int weekday)
+{
+ if (weekday < 1 || weekday > 7) {
+ weekday = 1;
+ }
+ return QLocale::system().dayName(weekday, QLocale::LongFormat);
+}
+#endif //QT_NO_TEXTDATE
+
+#ifndef QT_NO_DATESTRING
+
+/*!
+ \fn QString QDate::toString(Qt::DateFormat format) const
+
+ \overload
+
+ Returns the date as a string. The \a format parameter determines
+ the format of the string.
+
+ If the \a format is Qt::TextDate, the string is formatted in
+ the default way. QDate::shortDayName() and QDate::shortMonthName()
+ are used to generate the string, so the day and month names will
+ be localized names. An example of this formatting is
+ "Sat May 20 1995".
+
+ If the \a format is Qt::ISODate, the string format corresponds
+ to the ISO 8601 extended specification for representations of
+ dates and times, taking the form YYYY-MM-DD, where YYYY is the
+ year, MM is the month of the year (between 01 and 12), and DD is
+ the day of the month between 01 and 31.
+
+ If the \a format is Qt::SystemLocaleShortDate or
+ Qt::SystemLocaleLongDate, the string format depends on the locale
+ settings of the system. Identical to calling
+ QLocale::system().toString(date, QLocale::ShortFormat) or
+ QLocale::system().toString(date, QLocale::LongFormat).
+
+ If the \a format is Qt::DefaultLocaleShortDate or
+ Qt::DefaultLocaleLongDate, the string format depends on the
+ default application locale. This is the locale set with
+ QLocale::setDefault(), or the system locale if no default locale
+ has been set. Identical to calling QLocale().toString(date,
+ QLocale::ShortFormat) or QLocale().toString(date,
+ QLocale::LongFormat).
+
+ If the date is invalid, an empty string will be returned.
+
+ \warning The Qt::ISODate format is only valid for years in the
+ range 0 to 9999. This restriction may apply to locale-aware
+ formats as well, depending on the locale settings.
+
+ \sa shortDayName(), shortMonthName()
+*/
+QString QDate::toString(Qt::DateFormat f) const
+{
+ if (!isValid())
+ return QString();
+ int y, m, d;
+ getDateFromJulianDay(jd, &y, &m, &d);
+ switch (f) {
+ case Qt::SystemLocaleDate:
+ case Qt::SystemLocaleShortDate:
+ case Qt::SystemLocaleLongDate:
+ return QLocale::system().toString(*this, f == Qt::SystemLocaleLongDate ? QLocale::LongFormat
+ : QLocale::ShortFormat);
+ case Qt::LocaleDate:
+ case Qt::DefaultLocaleShortDate:
+ case Qt::DefaultLocaleLongDate:
+ return QLocale().toString(*this, f == Qt::DefaultLocaleLongDate ? QLocale::LongFormat
+ : QLocale::ShortFormat);
+ default:
+#ifndef QT_NO_TEXTDATE
+ case Qt::TextDate:
+ {
+ return QString::fromLatin1("%0 %1 %2 %3")
+ .arg(shortDayName(dayOfWeek()))
+ .arg(shortMonthName(m))
+ .arg(d)
+ .arg(y);
+ }
+#endif
+ case Qt::ISODate:
+ {
+ if (year() < 0 || year() > 9999)
+ return QString();
+ QString month(QString::number(m).rightJustified(2, QLatin1Char('0')));
+ QString day(QString::number(d).rightJustified(2, QLatin1Char('0')));
+ return QString::number(y) + QLatin1Char('-') + month + QLatin1Char('-') + day;
+ }
+ }
+}
+
+/*!
+ Returns the date as a string. The \a format parameter determines
+ the format of the result string.
+
+ These expressions may be used:
+
+ \table
+ \header \i Expression \i Output
+ \row \i d \i the day as number without a leading zero (1 to 31)
+ \row \i dd \i the day as number with a leading zero (01 to 31)
+ \row \i ddd
+ \i the abbreviated localized day name (e.g. 'Mon' to 'Sun').
+ Uses QDate::shortDayName().
+ \row \i dddd
+ \i the long localized day name (e.g. 'Monday' to 'Sunday').
+ Uses QDate::longDayName().
+ \row \i M \i the month as number without a leading zero (1 to 12)
+ \row \i MM \i the month as number with a leading zero (01 to 12)
+ \row \i MMM
+ \i the abbreviated localized month name (e.g. 'Jan' to 'Dec').
+ Uses QDate::shortMonthName().
+ \row \i MMMM
+ \i the long localized month name (e.g. 'January' to 'December').
+ Uses QDate::longMonthName().
+ \row \i yy \i the year as two digit number (00 to 99)
+ \row \i yyyy \i the year as four digit number. If the year is negative,
+ a minus sign is prepended in addition.
+ \endtable
+
+ All other input characters will be ignored. Any sequence of characters that
+ are enclosed in singlequotes will be treated as text and not be used as an
+ expression. Two consecutive singlequotes ("''") are replaced by a singlequote
+ in the output.
+
+ Example format strings (assuming that the QDate is the 20 July
+ 1969):
+
+ \table
+ \header \o Format \o Result
+ \row \o dd.MM.yyyy \o 20.07.1969
+ \row \o ddd MMMM d yy \o Sun July 20 69
+ \row \o 'The day is' dddd \o The day is Sunday
+ \endtable
+
+ If the datetime is invalid, an empty string will be returned.
+
+ \warning The Qt::ISODate format is only valid for years in the
+ range 0 to 9999. This restriction may apply to locale-aware
+ formats as well, depending on the locale settings.
+
+ \sa QDateTime::toString() QTime::toString()
+
+*/
+QString QDate::toString(const QString& format) const
+{
+ if (year() > 9999)
+ return QString();
+ return fmtDateTime(format, 0, this);
+}
+#endif //QT_NO_DATESTRING
+
+/*!
+ \obsolete
+
+ Sets the date's year \a y, month \a m, and day \a d.
+
+ If \a y is in the range 0 to 99, it is interpreted as 1900 to
+ 1999.
+
+ Use setDate() instead.
+*/
+
+bool QDate::setYMD(int y, int m, int d)
+{
+ if (uint(y) <= 99)
+ y += 1900;
+ return setDate(y, m, d);
+}
+
+/*!
+ \since 4.2
+
+ Sets the date's \a year, \a month, and \a day. Returns true if
+ the date is valid; otherwise returns false.
+
+ If the specified date is invalid, the QDate object is set to be
+ invalid. Any date before 2 January 4713 B.C. is considered
+ invalid.
+
+ \sa isValid()
+*/
+bool QDate::setDate(int year, int month, int day)
+{
+ if (!isValid(year, month, day)) {
+ jd = 0;
+ } else {
+ jd = julianDayFromDate(year, month, day);
+ }
+ return jd != 0;
+}
+
+/*!
+ \since 4.5
+
+ Extracts the date's year, month, and day, and assigns them to
+ *\a year, *\a month, and *\a day. The pointers may be null.
+
+ \sa year(), month(), day(), isValid()
+*/
+void QDate::getDate(int *year, int *month, int *day)
+{
+ getDateFromJulianDay(jd, year, month, day);
+}
+
+/*!
+ Returns a QDate object containing a date \a ndays later than the
+ date of this object (or earlier if \a ndays is negative).
+
+ \sa addMonths() addYears() daysTo()
+*/
+
+QDate QDate::addDays(int ndays) const
+{
+ QDate d;
+ // this is basically "d.jd = jd + ndays" with checks for integer overflow
+ if (ndays >= 0)
+ d.jd = (jd + ndays >= jd) ? jd + ndays : 0;
+ else
+ d.jd = (jd + ndays < jd) ? jd + ndays : 0;
+ return d;
+}
+
+/*!
+ Returns a QDate object containing a date \a nmonths later than the
+ date of this object (or earlier if \a nmonths is negative).
+
+ \note If the ending day/month combination does not exist in the
+ resulting month/year, this function will return a date that is the
+ latest valid date.
+
+ \warning QDate has a date hole around the days introducing the
+ Gregorian calendar (the days 5 to 14 October 1582, inclusive, do
+ not exist). If the calculation ends in one of those days, QDate
+ will return either October 4 or October 15.
+
+ \sa addDays() addYears()
+*/
+
+QDate QDate::addMonths(int nmonths) const
+{
+ if (!isValid())
+ return QDate();
+ if (!nmonths)
+ return *this;
+
+ int old_y, y, m, d;
+ getDateFromJulianDay(jd, &y, &m, &d);
+ old_y = y;
+
+ bool increasing = nmonths > 0;
+
+ while (nmonths != 0) {
+ if (nmonths < 0 && nmonths + 12 <= 0) {
+ y--;
+ nmonths+=12;
+ } else if (nmonths < 0) {
+ m+= nmonths;
+ nmonths = 0;
+ if (m <= 0) {
+ --y;
+ m += 12;
+ }
+ } else if (nmonths - 12 >= 0) {
+ y++;
+ nmonths -= 12;
+ } else if (m == 12) {
+ y++;
+ m = 0;
+ } else {
+ m += nmonths;
+ nmonths = 0;
+ if (m > 12) {
+ ++y;
+ m -= 12;
+ }
+ }
+ }
+
+ // was there a sign change?
+ if ((old_y > 0 && y <= 0) ||
+ (old_y < 0 && y >= 0))
+ // yes, adjust the date by +1 or -1 years
+ y += increasing ? +1 : -1;
+
+ // did we end up in the Gregorian/Julian conversion hole?
+ if (y == 1582 && m == 10 && d > 4 && d < 15)
+ d = increasing ? 15 : 4;
+
+ return fixedDate(y, m, d);
+}
+
+/*!
+ Returns a QDate object containing a date \a nyears later than the
+ date of this object (or earlier if \a nyears is negative).
+
+ \note If the ending day/month combination does not exist in the
+ resulting year (i.e., if the date was Feb 29 and the final year is
+ not a leap year), this function will return a date that is the
+ latest valid date (that is, Feb 28).
+
+ \sa addDays(), addMonths()
+*/
+
+QDate QDate::addYears(int nyears) const
+{
+ if (!isValid())
+ return QDate();
+
+ int y, m, d;
+ getDateFromJulianDay(jd, &y, &m, &d);
+
+ int old_y = y;
+ y += nyears;
+
+ // was there a sign change?
+ if ((old_y > 0 && y <= 0) ||
+ (old_y < 0 && y >= 0))
+ // yes, adjust the date by +1 or -1 years
+ y += nyears > 0 ? +1 : -1;
+
+ return fixedDate(y, m, d);
+}
+
+/*!
+ Returns the number of days from this date to \a d (which is
+ negative if \a d is earlier than this date).
+
+ Example:
+ \snippet doc/src/snippets/code/src_corelib_tools_qdatetime.cpp 0
+
+ \sa addDays()
+*/
+
+int QDate::daysTo(const QDate &d) const
+{
+ return d.jd - jd;
+}
+
+
+/*!
+ \fn bool QDate::operator==(const QDate &d) const
+
+ Returns true if this date is equal to \a d; otherwise returns
+ false.
+
+*/
+
+/*!
+ \fn bool QDate::operator!=(const QDate &d) const
+
+ Returns true if this date is different from \a d; otherwise
+ returns false.
+*/
+
+/*!
+ \fn bool QDate::operator<(const QDate &d) const
+
+ Returns true if this date is earlier than \a d; otherwise returns
+ false.
+*/
+
+/*!
+ \fn bool QDate::operator<=(const QDate &d) const
+
+ Returns true if this date is earlier than or equal to \a d;
+ otherwise returns false.
+*/
+
+/*!
+ \fn bool QDate::operator>(const QDate &d) const
+
+ Returns true if this date is later than \a d; otherwise returns
+ false.
+*/
+
+/*!
+ \fn bool QDate::operator>=(const QDate &d) const
+
+ Returns true if this date is later than or equal to \a d;
+ otherwise returns false.
+*/
+
+/*!
+ \overload
+ Returns the current date, as reported by the system clock.
+
+ \sa QTime::currentTime(), QDateTime::currentDateTime()
+*/
+
+QDate QDate::currentDate()
+{
+ QDate d;
+#if defined(Q_OS_WIN)
+ SYSTEMTIME st;
+ memset(&st, 0, sizeof(SYSTEMTIME));
+ GetLocalTime(&st);
+ d.jd = julianDayFromDate(st.wYear, st.wMonth, st.wDay);
+#else
+ // posix compliant system
+ time_t ltime;
+ time(&ltime);
+ tm *t = 0;
+
+#if !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS)
+ // use the reentrant version of localtime() where available
+ tzset();
+ tm res;
+ t = localtime_r(&ltime, &res);
+#else
+ t = localtime(&ltime);
+#endif // !QT_NO_THREAD && _POSIX_THREAD_SAFE_FUNCTIONS
+
+ d.jd = julianDayFromDate(t->tm_year + 1900, t->tm_mon + 1, t->tm_mday);
+#endif
+ return d;
+}
+
+#ifndef QT_NO_DATESTRING
+/*!
+ \fn QDate QDate::fromString(const QString &string, Qt::DateFormat format)
+
+ Returns the QDate represented by the \a string, using the
+ \a format given, or an invalid date if the string cannot be
+ parsed.
+
+ Note for Qt::TextDate: It is recommended that you use the
+ English short month names (e.g. "Jan"). Although localized month
+ names can also be used, they depend on the user's locale settings.
+*/
+QDate QDate::fromString(const QString& s, Qt::DateFormat f)
+{
+ if (s.isEmpty())
+ return QDate();
+
+ switch (f) {
+ case Qt::ISODate:
+ {
+ int year(s.mid(0, 4).toInt());
+ int month(s.mid(5, 2).toInt());
+ int day(s.mid(8, 2).toInt());
+ if (year && month && day)
+ return QDate(year, month, day);
+ }
+ break;
+ case Qt::SystemLocaleDate:
+ case Qt::SystemLocaleShortDate:
+ case Qt::SystemLocaleLongDate:
+ return fromString(s, QLocale::system().dateFormat(f == Qt::SystemLocaleLongDate ? QLocale::LongFormat
+ : QLocale::ShortFormat));
+ case Qt::LocaleDate:
+ case Qt::DefaultLocaleShortDate:
+ case Qt::DefaultLocaleLongDate:
+ return fromString(s, QLocale().dateFormat(f == Qt::DefaultLocaleLongDate ? QLocale::LongFormat
+ : QLocale::ShortFormat));
+ default:
+#ifndef QT_NO_TEXTDATE
+ case Qt::TextDate: {
+ QStringList parts = s.split(QLatin1Char(' '), QString::SkipEmptyParts);
+
+ if (parts.count() != 4) {
+ return QDate();
+ }
+
+ QString monthName = parts.at(1);
+ int month = -1;
+ // Assume that English monthnames are the default
+ for (int i = 0; i < 12; ++i) {
+ if (monthName == QLatin1String(qt_shortMonthNames[i])) {
+ month = i + 1;
+ break;
+ }
+ }
+ // If English names can't be found, search the localized ones
+ if (month == -1) {
+ for (int i = 1; i <= 12; ++i) {
+ if (monthName == QDate::shortMonthName(i)) {
+ month = i;
+ break;
+ }
+ }
+ }
+ if (month < 1 || month > 12) {
+ return QDate();
+ }
+
+ bool ok;
+ int day = parts.at(2).toInt(&ok);
+ if (!ok) {
+ return QDate();
+ }
+
+ int year = parts.at(3).toInt(&ok);
+ if (!ok) {
+ return QDate();
+ }
+
+ return QDate(year, month, day);
+ }
+#else
+ break;
+#endif
+ }
+ return QDate();
+}
+
+/*!
+ \fn QDate::fromString(const QString &string, const QString &format)
+
+ Returns the QDate represented by the \a string, using the \a
+ format given, or an invalid date if the string cannot be parsed.
+
+ These expressions may be used for the format:
+
+ \table
+ \header \i Expression \i Output
+ \row \i d \i The day as a number without a leading zero (1 to 31)
+ \row \i dd \i The day as a number with a leading zero (01 to 31)
+ \row \i ddd
+ \i The abbreviated localized day name (e.g. 'Mon' to 'Sun').
+ Uses QDate::shortDayName().
+ \row \i dddd
+ \i The long localized day name (e.g. 'Monday' to 'Sunday').
+ Uses QDate::longDayName().
+ \row \i M \i The month as a number without a leading zero (1 to 12)
+ \row \i MM \i The month as a number with a leading zero (01 to 12)
+ \row \i MMM
+ \i The abbreviated localized month name (e.g. 'Jan' to 'Dec').
+ Uses QDate::shortMonthName().
+ \row \i MMMM
+ \i The long localized month name (e.g. 'January' to 'December').
+ Uses QDate::longMonthName().
+ \row \i yy \i The year as two digit number (00 to 99)
+ \row \i yyyy \i The year as four digit number. If the year is negative,
+ a minus sign is prepended in addition.
+ \endtable
+
+ All other input characters will be treated as text. Any sequence
+ of characters that are enclosed in single quotes will also be
+ treated as text and will not be used as an expression. For example:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qdatetime.cpp 1
+
+ If the format is not satisfied, an invalid QDate is returned. The
+ expressions that don't expect leading zeroes (d, M) will be
+ greedy. This means that they will use two digits even if this
+ will put them outside the accepted range of values and leaves too
+ few digits for other sections. For example, the following format
+ string could have meant January 30 but the M will grab two
+ digits, resulting in an invalid date:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qdatetime.cpp 2
+
+ For any field that is not represented in the format the following
+ defaults are used:
+
+ \table
+ \header \i Field \i Default value
+ \row \i Year \i 1900
+ \row \i Month \i 1
+ \row \i Day \i 1
+ \endtable
+
+ The following examples demonstrate the default values:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qdatetime.cpp 3
+
+ \sa QDateTime::fromString(), QTime::fromString(), QDate::toString(),
+ QDateTime::toString(), QTime::toString()
+*/
+
+QDate QDate::fromString(const QString &string, const QString &format)
+{
+ QDate date;
+#ifndef QT_BOOTSTRAPPED
+ QDateTimeParser dt(QVariant::Date, QDateTimeParser::FromString);
+ if (dt.parseFormat(format))
+ dt.fromString(string, &date, 0);
+#else
+ Q_UNUSED(string);
+ Q_UNUSED(format);
+#endif
+ return date;
+}
+#endif // QT_NO_DATESTRING
+
+/*!
+ \overload
+
+ Returns true if the specified date (\a year, \a month, and \a
+ day) is valid; otherwise returns false.
+
+ Example:
+ \snippet doc/src/snippets/code/src_corelib_tools_qdatetime.cpp 4
+
+ \sa isNull(), setDate()
+*/
+
+bool QDate::isValid(int year, int month, int day)
+{
+ if (year < FIRST_YEAR
+ || (year == FIRST_YEAR &&
+ (month < FIRST_MONTH
+ || (month == FIRST_MONTH && day < FIRST_DAY)))
+ || year == 0) // there is no year 0 in the Julian calendar
+ return false;
+
+ // passage from Julian to Gregorian calendar
+ if (year == 1582 && month == 10 && day > 4 && day < 15)
+ return 0;
+
+ return (day > 0 && month > 0 && month <= 12) &&
+ (day <= monthDays[month] || (day == 29 && month == 2 && isLeapYear(year)));
+}
+
+/*!
+ \fn bool QDate::isLeapYear(int year)
+
+ Returns true if the specified \a year is a leap year; otherwise
+ returns false.
+*/
+
+bool QDate::isLeapYear(int y)
+{
+ if (y < 1582) {
+ return qAbs(y) % 4 == 0;
+ } else {
+ return (y % 4 == 0 && y % 100 != 0) || y % 400 == 0;
+ }
+}
+
+/*!
+ \internal
+
+ This function has a confusing name and shouldn't be part of the
+ API anyway, since we have toJulian() and fromJulian().
+ ### Qt 5: remove it
+*/
+uint QDate::gregorianToJulian(int y, int m, int d)
+{
+ return julianDayFromDate(y, m, d);
+}
+
+/*!
+ \internal
+
+ This function has a confusing name and shouldn't be part of the
+ API anyway, since we have toJulian() and fromJulian().
+ ### Qt 5: remove it
+*/
+void QDate::julianToGregorian(uint jd, int &y, int &m, int &d)
+{
+ getDateFromJulianDay(jd, &y, &m, &d);
+}
+
+/*! \fn static QDate QDate::fromJulianDay(int jd)
+
+ Converts the Julian day \a jd to a QDate.
+
+ \sa toJulianDay()
+*/
+
+/*! \fn int QDate::toJulianDay() const
+
+ Converts the date to a Julian day.
+
+ \sa fromJulianDay()
+*/
+
+/*****************************************************************************
+ QTime member functions
+ *****************************************************************************/
+
+/*!
+ \class QTime
+ \reentrant
+
+ \brief The QTime class provides clock time functions.
+
+ \ingroup time
+ \mainclass
+
+ A QTime object contains a clock time, i.e. the number of hours,
+ minutes, seconds, and milliseconds since midnight. It can read the
+ current time from the system clock and measure a span of elapsed
+ time. It provides functions for comparing times and for
+ manipulating a time by adding a number of milliseconds.
+
+ QTime uses the 24-hour clock format; it has no concept of AM/PM.
+ Unlike QDateTime, QTime knows nothing about time zones or
+ daylight savings time (DST).
+
+ A QTime object is typically created either by giving the number
+ of hours, minutes, seconds, and milliseconds explicitly, or by
+ using the static function currentTime(), which creates a QTime
+ object that contains the system's local time. Note that the
+ accuracy depends on the accuracy of the underlying operating
+ system; not all systems provide 1-millisecond accuracy.
+
+ The hour(), minute(), second(), and msec() functions provide
+ access to the number of hours, minutes, seconds, and milliseconds
+ of the time. The same information is provided in textual format by
+ the toString() function.
+
+ QTime provides a full set of operators to compare two QTime
+ objects. One time is considered smaller than another if it is
+ earlier than the other.
+
+ The time a given number of seconds or milliseconds later than a
+ given time can be found using the addSecs() or addMSecs()
+ functions. Correspondingly, the number of seconds or milliseconds
+ between two times can be found using secsTo() or msecsTo().
+
+ QTime can be used to measure a span of elapsed time using the
+ start(), restart(), and elapsed() functions.
+
+ \sa QDate, QDateTime
+*/
+
+/*!
+ \fn QTime::QTime()
+
+ Constructs a null time object. A null time can be a QTime(0, 0, 0, 0)
+ (i.e., midnight) object, except that isNull() returns true and isValid()
+ returns false.
+
+ \sa isNull(), isValid()
+*/
+
+/*!
+ Constructs a time with hour \a h, minute \a m, seconds \a s and
+ milliseconds \a ms.
+
+ \a h must be in the range 0 to 23, \a m and \a s must be in the
+ range 0 to 59, and \a ms must be in the range 0 to 999.
+
+ \sa isValid()
+*/
+
+QTime::QTime(int h, int m, int s, int ms)
+{
+ setHMS(h, m, s, ms);
+}
+
+
+/*!
+ \fn bool QTime::isNull() const
+
+ Returns true if the time is null (i.e., the QTime object was
+ constructed using the default constructor); otherwise returns
+ false. A null time is also an invalid time.
+
+ \sa isValid()
+*/
+
+/*!
+ Returns true if the time is valid; otherwise returns false. For example,
+ the time 23:30:55.746 is valid, but 24:12:30 is invalid.
+
+ \sa isNull()
+*/
+
+bool QTime::isValid() const
+{
+ return mds > NullTime && mds < MSECS_PER_DAY;
+}
+
+
+/*!
+ Returns the hour part (0 to 23) of the time.
+
+ \sa minute(), second(), msec()
+*/
+
+int QTime::hour() const
+{
+ return ds() / MSECS_PER_HOUR;
+}
+
+/*!
+ Returns the minute part (0 to 59) of the time.
+
+ \sa hour(), second(), msec()
+*/
+
+int QTime::minute() const
+{
+ return (ds() % MSECS_PER_HOUR) / MSECS_PER_MIN;
+}
+
+/*!
+ Returns the second part (0 to 59) of the time.
+
+ \sa hour(), minute(), msec()
+*/
+
+int QTime::second() const
+{
+ return (ds() / 1000)%SECS_PER_MIN;
+}
+
+/*!
+ Returns the millisecond part (0 to 999) of the time.
+
+ \sa hour(), minute(), second()
+*/
+
+int QTime::msec() const
+{
+ return ds() % 1000;
+}
+
+#ifndef QT_NO_DATESTRING
+/*!
+ \overload
+
+ Returns the time as a string. Milliseconds are not included. The
+ \a format parameter determines the format of the string.
+
+ If \a format is Qt::TextDate, the string format is HH:MM:SS; e.g. 1
+ second before midnight would be "23:59:59".
+
+ If \a format is Qt::ISODate, the string format corresponds to the
+ ISO 8601 extended specification for representations of dates,
+ which is also HH:MM:SS. (However, contrary to ISO 8601, dates
+ before 15 October 1582 are handled as Julian dates, not Gregorian
+ dates. See \l{QDate G and J} {Use of Gregorian and Julian
+ Calendars}. This might change in a future version of Qt.)
+
+ If the \a format is Qt::SystemLocaleShortDate or
+ Qt::SystemLocaleLongDate, the string format depends on the locale
+ settings of the system. Identical to calling
+ QLocale::system().toString(time, QLocale::ShortFormat) or
+ QLocale::system().toString(time, QLocale::LongFormat).
+
+ If the \a format is Qt::DefaultLocaleShortDate or
+ Qt::DefaultLocaleLongDate, the string format depends on the
+ default application locale. This is the locale set with
+ QLocale::setDefault(), or the system locale if no default locale
+ has been set. Identical to calling QLocale().toString(time,
+ QLocale::ShortFormat) or QLocale().toString(time,
+ QLocale::LongFormat).
+
+ If the time is invalid, an empty string will be returned.
+*/
+
+QString QTime::toString(Qt::DateFormat format) const
+{
+ if (!isValid())
+ return QString();
+
+ switch (format) {
+ case Qt::SystemLocaleDate:
+ case Qt::SystemLocaleShortDate:
+ case Qt::SystemLocaleLongDate:
+ return QLocale::system().toString(*this, format == Qt::SystemLocaleLongDate ? QLocale::LongFormat
+ : QLocale::ShortFormat);
+ case Qt::LocaleDate:
+ case Qt::DefaultLocaleShortDate:
+ case Qt::DefaultLocaleLongDate:
+ return QLocale().toString(*this, format == Qt::DefaultLocaleLongDate ? QLocale::LongFormat
+ : QLocale::ShortFormat);
+
+ default:
+ case Qt::ISODate:
+ case Qt::TextDate:
+ return QString::fromLatin1("%1:%2:%3")
+ .arg(hour(), 2, 10, QLatin1Char('0'))
+ .arg(minute(), 2, 10, QLatin1Char('0'))
+ .arg(second(), 2, 10, QLatin1Char('0'));
+ }
+}
+
+/*!
+ Returns the time as a string. The \a format parameter determines
+ the format of the result string.
+
+ These expressions may be used:
+
+ \table
+ \header \i Expression \i Output
+ \row \i h
+ \i the hour without a leading zero (0 to 23 or 1 to 12 if AM/PM display)
+ \row \i hh
+ \i the hour with a leading zero (00 to 23 or 01 to 12 if AM/PM display)
+ \row \i H
+ \i the hour without a leading zero (0 to 23, even with AM/PM display)
+ \row \i HH
+ \i the hour with a leading zero (00 to 23, even with AM/PM display)
+ \row \i m \i the minute without a leading zero (0 to 59)
+ \row \i mm \i the minute with a leading zero (00 to 59)
+ \row \i s \i the second without a leading zero (0 to 59)
+ \row \i ss \i the second with a leading zero (00 to 59)
+ \row \i z \i the milliseconds without leading zeroes (0 to 999)
+ \row \i zzz \i the milliseconds with leading zeroes (000 to 999)
+ \row \i AP or A
+ \i use AM/PM display. \e AP will be replaced by either "AM" or "PM".
+ \row \i ap or a
+ \i use am/pm display. \e ap will be replaced by either "am" or "pm".
+ \endtable
+
+ All other input characters will be ignored. Any sequence of characters that
+ are enclosed in singlequotes will be treated as text and not be used as an
+ expression. Two consecutive singlequotes ("''") are replaced by a singlequote
+ in the output.
+
+ Example format strings (assuming that the QTime is 14:13:09.042)
+
+ \table
+ \header \i Format \i Result
+ \row \i hh:mm:ss.zzz \i 14:13:09.042
+ \row \i h:m:s ap \i 2:13:9 pm
+ \row \i H:m:s a \i 14:13:9 pm
+ \endtable
+
+ If the datetime is invalid, an empty string will be returned.
+
+ \sa QDate::toString() QDateTime::toString()
+*/
+QString QTime::toString(const QString& format) const
+{
+ return fmtDateTime(format, this, 0);
+}
+#endif //QT_NO_DATESTRING
+/*!
+ Sets the time to hour \a h, minute \a m, seconds \a s and
+ milliseconds \a ms.
+
+ \a h must be in the range 0 to 23, \a m and \a s must be in the
+ range 0 to 59, and \a ms must be in the range 0 to 999.
+ Returns true if the set time is valid; otherwise returns false.
+
+ \sa isValid()
+*/
+
+bool QTime::setHMS(int h, int m, int s, int ms)
+{
+#if defined(Q_OS_WINCE)
+ startTick = NullTime;
+#endif
+ if (!isValid(h,m,s,ms)) {
+ mds = NullTime; // make this invalid
+ return false;
+ }
+ mds = (h*SECS_PER_HOUR + m*SECS_PER_MIN + s)*1000 + ms;
+ return true;
+}
+
+/*!
+ Returns a QTime object containing a time \a s seconds later
+ than the time of this object (or earlier if \a s is negative).
+
+ Note that the time will wrap if it passes midnight.
+
+ Example:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qdatetime.cpp 5
+
+ \sa addMSecs(), secsTo(), QDateTime::addSecs()
+*/
+
+QTime QTime::addSecs(int s) const
+{
+ return addMSecs(s * 1000);
+}
+
+/*!
+ Returns the number of seconds from this time to \a t.
+ If \a t is earlier than this time, the number of seconds returned
+ is negative.
+
+ Because QTime measures time within a day and there are 86400
+ seconds in a day, the result is always between -86400 and 86400.
+
+ secsTo() does not take into account any milliseconds.
+
+ \sa addSecs(), QDateTime::secsTo()
+*/
+
+int QTime::secsTo(const QTime &t) const
+{
+ return (t.ds() - ds()) / 1000;
+}
+
+/*!
+ Returns a QTime object containing a time \a ms milliseconds later
+ than the time of this object (or earlier if \a ms is negative).
+
+ Note that the time will wrap if it passes midnight. See addSecs()
+ for an example.
+
+ \sa addSecs(), msecsTo()
+*/
+
+QTime QTime::addMSecs(int ms) const
+{
+ QTime t;
+ if (ms < 0) {
+ // % not well-defined for -ve, but / is.
+ int negdays = (MSECS_PER_DAY - ms) / MSECS_PER_DAY;
+ t.mds = (ds() + ms + negdays * MSECS_PER_DAY) % MSECS_PER_DAY;
+ } else {
+ t.mds = (ds() + ms) % MSECS_PER_DAY;
+ }
+#if defined(Q_OS_WINCE)
+ if (startTick > NullTime)
+ t.startTick = (startTick + ms) % MSECS_PER_DAY;
+#endif
+ return t;
+}
+
+/*!
+ Returns the number of milliseconds from this time to \a t.
+ If \a t is earlier than this time, the number of milliseconds returned
+ is negative.
+
+ Because QTime measures time within a day and there are 86400
+ seconds in a day, the result is always between -86400000 and
+ 86400000 ms.
+
+ \sa secsTo(), addMSecs()
+*/
+
+int QTime::msecsTo(const QTime &t) const
+{
+#if defined(Q_OS_WINCE)
+ // GetLocalTime() for Windows CE has no milliseconds resolution
+ if (t.startTick > NullTime && startTick > NullTime)
+ return t.startTick - startTick;
+ else
+#endif
+ return t.ds() - ds();
+}
+
+
+/*!
+ \fn bool QTime::operator==(const QTime &t) const
+
+ Returns true if this time is equal to \a t; otherwise returns false.
+*/
+
+/*!
+ \fn bool QTime::operator!=(const QTime &t) const
+
+ Returns true if this time is different from \a t; otherwise returns false.
+*/
+
+/*!
+ \fn bool QTime::operator<(const QTime &t) const
+
+ Returns true if this time is earlier than \a t; otherwise returns false.
+*/
+
+/*!
+ \fn bool QTime::operator<=(const QTime &t) const
+
+ Returns true if this time is earlier than or equal to \a t;
+ otherwise returns false.
+*/
+
+/*!
+ \fn bool QTime::operator>(const QTime &t) const
+
+ Returns true if this time is later than \a t; otherwise returns false.
+*/
+
+/*!
+ \fn bool QTime::operator>=(const QTime &t) const
+
+ Returns true if this time is later than or equal to \a t;
+ otherwise returns false.
+*/
+
+/*!
+ \overload
+
+ Returns the current time as reported by the system clock.
+
+ Note that the accuracy depends on the accuracy of the underlying
+ operating system; not all systems provide 1-millisecond accuracy.
+*/
+
+QTime QTime::currentTime()
+{
+ QTime ct;
+
+#if defined(Q_OS_WIN)
+ SYSTEMTIME st;
+ memset(&st, 0, sizeof(SYSTEMTIME));
+ GetLocalTime(&st);
+ ct.mds = MSECS_PER_HOUR * st.wHour + MSECS_PER_MIN * st.wMinute + 1000 * st.wSecond
+ + st.wMilliseconds;
+#if defined(Q_OS_WINCE)
+ ct.startTick = GetTickCount() % MSECS_PER_DAY;
+#endif
+#elif defined(Q_OS_UNIX)
+ // posix compliant system
+ struct timeval tv;
+ gettimeofday(&tv, 0);
+ time_t ltime = tv.tv_sec;
+ tm *t = 0;
+
+#if !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS)
+ // use the reentrant version of localtime() where available
+ tzset();
+ tm res;
+ t = localtime_r(&ltime, &res);
+#else
+ t = localtime(&ltime);
+#endif
+
+ ct.mds = MSECS_PER_HOUR * t->tm_hour + MSECS_PER_MIN * t->tm_min + 1000 * t->tm_sec
+ + tv.tv_usec / 1000;
+#else
+ time_t ltime; // no millisecond resolution
+ ::time(&ltime);
+ tm *t = 0;
+ localtime(&ltime);
+ ct.mds = MSECS_PER_HOUR * t->tm_hour + MSECS_PER_MIN * t->tm_min + 1000 * t->tm_sec;
+#endif
+ return ct;
+}
+
+#ifndef QT_NO_DATESTRING
+/*!
+ \fn QTime QTime::fromString(const QString &string, Qt::DateFormat format)
+
+ Returns the time represented in the \a string as a QTime using the
+ \a format given, or an invalid time if this is not possible.
+
+ Note that fromString() uses a "C" locale encoded string to convert
+ milliseconds to a float value. If the default locale is not "C",
+ this may result in two conversion attempts (if the conversion
+ fails for the default locale). This should be considered an
+ implementation detail.
+*/
+QTime QTime::fromString(const QString& s, Qt::DateFormat f)
+{
+ if (s.isEmpty()) {
+ QTime t;
+ t.mds = NullTime;
+ return t;
+ }
+
+ switch (f) {
+ case Qt::SystemLocaleDate:
+ case Qt::SystemLocaleShortDate:
+ case Qt::SystemLocaleLongDate:
+ return fromString(s, QLocale::system().timeFormat(f == Qt::SystemLocaleLongDate ? QLocale::LongFormat
+ : QLocale::ShortFormat));
+ case Qt::LocaleDate:
+ case Qt::DefaultLocaleShortDate:
+ case Qt::DefaultLocaleLongDate:
+ return fromString(s, QLocale().timeFormat(f == Qt::DefaultLocaleLongDate ? QLocale::LongFormat
+ : QLocale::ShortFormat));
+ default:
+ {
+ bool ok = true;
+ const int hour(s.mid(0, 2).toInt(&ok));
+ if (!ok)
+ return QTime();
+ const int minute(s.mid(3, 2).toInt(&ok));
+ if (!ok)
+ return QTime();
+ const int second(s.mid(6, 2).toInt(&ok));
+ if (!ok)
+ return QTime();
+ const QString msec_s(QLatin1String("0.") + s.mid(9, 4));
+ const float msec(msec_s.toFloat(&ok));
+ if (!ok)
+ return QTime();
+ return QTime(hour, minute, second, qMin(qRound(msec * 1000.0), 999));
+ }
+ }
+}
+
+/*!
+ \fn QTime::fromString(const QString &string, const QString &format)
+
+ Returns the QTime represented by the \a string, using the \a
+ format given, or an invalid time if the string cannot be parsed.
+
+ These expressions may be used for the format:
+
+ \table
+ \header \i Expression \i Output
+ \row \i h
+ \i the hour without a leading zero (0 to 23 or 1 to 12 if AM/PM display)
+ \row \i hh
+ \i the hour with a leading zero (00 to 23 or 01 to 12 if AM/PM display)
+ \row \i m \i the minute without a leading zero (0 to 59)
+ \row \i mm \i the minute with a leading zero (00 to 59)
+ \row \i s \i the second without a leading zero (0 to 59)
+ \row \i ss \i the second with a leading zero (00 to 59)
+ \row \i z \i the milliseconds without leading zeroes (0 to 999)
+ \row \i zzz \i the milliseconds with leading zeroes (000 to 999)
+ \row \i AP
+ \i interpret as an AM/PM time. \e AP must be either "AM" or "PM".
+ \row \i ap
+ \i Interpret as an AM/PM time. \e ap must be either "am" or "pm".
+ \endtable
+
+ All other input characters will be treated as text. Any sequence
+ of characters that are enclosed in single quotes will also be
+ treated as text and not be used as an expression.
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qdatetime.cpp 6
+
+ If the format is not satisfied an invalid QTime is returned.
+ Expressions that do not expect leading zeroes to be given (h, m, s
+ and z) are greedy. This means that they will use two digits even if
+ this puts them outside the range of accepted values and leaves too
+ few digits for other sections. For example, the following string
+ could have meant 00:07:10, but the m will grab two digits, resulting
+ in an invalid time:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qdatetime.cpp 7
+
+ Any field that is not represented in the format will be set to zero.
+ For example:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qdatetime.cpp 8
+
+ \sa QDateTime::fromString() QDate::fromString() QDate::toString()
+ QDateTime::toString() QTime::toString()
+*/
+
+QTime QTime::fromString(const QString &string, const QString &format)
+{
+ QTime time;
+#ifndef QT_BOOTSTRAPPED
+ QDateTimeParser dt(QVariant::Time, QDateTimeParser::FromString);
+ if (dt.parseFormat(format))
+ dt.fromString(string, 0, &time);
+#else
+ Q_UNUSED(string);
+ Q_UNUSED(format);
+#endif
+ return time;
+}
+
+#endif // QT_NO_DATESTRING
+
+
+/*!
+ \overload
+
+ Returns true if the specified time is valid; otherwise returns
+ false.
+
+ The time is valid if \a h is in the range 0 to 23, \a m and
+ \a s are in the range 0 to 59, and \a ms is in the range 0 to 999.
+
+ Example:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qdatetime.cpp 9
+*/
+
+bool QTime::isValid(int h, int m, int s, int ms)
+{
+ return (uint)h < 24 && (uint)m < 60 && (uint)s < 60 && (uint)ms < 1000;
+}
+
+
+/*!
+ Sets this time to the current time. This is practical for timing:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qdatetime.cpp 10
+
+ \sa restart(), elapsed(), currentTime()
+*/
+
+void QTime::start()
+{
+ *this = currentTime();
+}
+
+/*!
+ Sets this time to the current time and returns the number of
+ milliseconds that have elapsed since the last time start() or
+ restart() was called.
+
+ This function is guaranteed to be atomic and is thus very handy
+ for repeated measurements. Call start() to start the first
+ measurement, and restart() for each later measurement.
+
+ Note that the counter wraps to zero 24 hours after the last call
+ to start() or restart().
+
+ \warning If the system's clock setting has been changed since the
+ last time start() or restart() was called, the result is
+ undefined. This can happen when daylight savings time is turned on
+ or off.
+
+ \sa start(), elapsed(), currentTime()
+*/
+
+int QTime::restart()
+{
+ QTime t = currentTime();
+ int n = msecsTo(t);
+ if (n < 0) // passed midnight
+ n += 86400*1000;
+ *this = t;
+ return n;
+}
+
+/*!
+ Returns the number of milliseconds that have elapsed since the
+ last time start() or restart() was called.
+
+ Note that the counter wraps to zero 24 hours after the last call
+ to start() or restart.
+
+ Note that the accuracy depends on the accuracy of the underlying
+ operating system; not all systems provide 1-millisecond accuracy.
+
+ \warning If the system's clock setting has been changed since the
+ last time start() or restart() was called, the result is
+ undefined. This can happen when daylight savings time is turned on
+ or off.
+
+ \sa start(), restart()
+*/
+
+int QTime::elapsed() const
+{
+ int n = msecsTo(currentTime());
+ if (n < 0) // passed midnight
+ n += 86400 * 1000;
+ return n;
+}
+
+
+/*****************************************************************************
+ QDateTime member functions
+ *****************************************************************************/
+
+/*!
+ \class QDateTime
+ \reentrant
+ \brief The QDateTime class provides date and time functions.
+
+ \ingroup time
+ \mainclass
+
+ A QDateTime object contains a calendar date and a clock time (a
+ "datetime"). It is a combination of the QDate and QTime classes.
+ It can read the current datetime from the system clock. It
+ provides functions for comparing datetimes and for manipulating a
+ datetime by adding a number of seconds, days, months, or years.
+
+ A QDateTime object is typically created either by giving a date
+ and time explicitly in the constructor, or by using the static
+ function currentDateTime() that returns a QDateTime object set
+ to the system clock's time. The date and time can be changed with
+ setDate() and setTime(). A datetime can also be set using the
+ setTime_t() function that takes a POSIX-standard "number of
+ seconds since 00:00:00 on January 1, 1970" value. The fromString()
+ function returns a QDateTime, given a string and a date format
+ used to interpret the date within the string.
+
+ The date() and time() functions provide access to the date and
+ time parts of the datetime. The same information is provided in
+ textual format by the toString() function.
+
+ QDateTime provides a full set of operators to compare two
+ QDateTime objects where smaller means earlier and larger means
+ later.
+
+ You can increment (or decrement) a datetime by a given number of
+ seconds using addSecs(), or days using addDays(). Similarly you can
+ use addMonths() and addYears(). The daysTo() function returns the
+ number of days between two datetimes, and secsTo() returns the
+ number of seconds between two datetimes.
+
+ QDateTime can store datetimes as \l{Qt::LocalTime}{local time} or
+ as \l{Qt::UTC}{UTC}. QDateTime::currentDateTime() returns a
+ QDateTime expressed as local time; use toUTC() to convert it to
+ UTC. You can also use timeSpec() to find out if a QDateTime
+ object stores a UTC time or a local time. Operations such as
+ addSecs() and secsTo() are aware of daylight saving time (DST).
+
+ \note QDateTime does not account for leap seconds.
+
+ \section1
+
+ \target QDateTime G and J
+ \section2 Use of Gregorian and Julian Calendars
+
+ QDate uses the Gregorian calendar in all locales, beginning
+ on the date 15 October 1582. For dates up to and including 4
+ October 1582, the Julian calendar is used. This means there is a
+ 10-day gap in the internal calendar between the 4th and the 15th
+ of October 1582. When you use QDateTime for dates in that epoch,
+ the day after 4 October 1582 is 15 October 1582, and the dates in
+ the gap are invalid.
+
+ The Julian to Gregorian changeover date used here is the date when
+ the Gregorian calendar was first introduced, by Pope Gregory
+ XIII. That change was not universally accepted and some localities
+ only executed it at a later date (if at all). QDateTime
+ doesn't take any of these historical facts into account. If an
+ application must support a locale-specific dating system, it must
+ do so on its own, remembering to convert the dates using the
+ Julian day.
+
+ \section2 No Year 0
+
+ There is no year 0. Dates in that year are considered invalid. The
+ year -1 is the year "1 before Christ" or "1 before current era."
+ The day before 0001-01-01 is December 31st, 1 BCE.
+
+ \section2 Range of Valid Dates
+
+ The range of valid dates is from January 2nd, 4713 BCE, to
+ sometime in the year 11 million CE. The Julian Day returned by
+ QDate::toJulianDay() is a number in the contiguous range from 1 to
+ \e{overflow}, even across QDateTime's "date holes". It is suitable
+ for use in applications that must convert a QDateTime to a date in
+ another calendar system, e.g., Hebrew, Islamic or Chinese.
+
+ The Gregorian calendar was introduced in different places around
+ the world on different dates. QDateTime uses QDate to store the
+ date, so it uses the Gregorian calendar for all locales, beginning
+ on the date 15 October 1582. For dates up to and including 4
+ October 1582, QDateTime uses the Julian calendar. This means
+ there is a 10-day gap in the QDateTime calendar between the 4th
+ and the 15th of October 1582. When you use QDateTime for dates in
+ that epoch, the day after 4 October 1582 is 15 October 1582, and
+ the dates in the gap are invalid.
+
+ \section2
+ Use of System Timezone
+
+ QDateTime uses the system's time zone information to determine the
+ offset of local time from UTC. If the system is not configured
+ correctly or not up-to-date, QDateTime will give wrong results as
+ well.
+
+ \section2 Daylight Savings Time (DST)
+
+ QDateTime takes into account the system's time zone information
+ when dealing with DST. On modern Unix systems, this means it
+ applies the correct historical DST data whenever possible. On
+ Windows and Windows CE, where the system doesn't support
+ historical DST data, historical accuracy is not maintained with
+ respect to DST.
+
+ The range of valid dates taking DST into account is 1970-01-01 to
+ the present, and rules are in place for handling DST correctly
+ until 2037-12-31, but these could change. For dates falling
+ outside that range, QDateTime makes a \e{best guess} using the
+ rules for year 1970 or 2037, but we can't guarantee accuracy. This
+ means QDateTime doesn't take into account changes in a locale's
+ time zone before 1970, even if the system's time zone database
+ supports that information.
+
+ \sa QDate QTime QDateTimeEdit
+*/
+
+/*!
+ Constructs a null datetime (i.e. null date and null time). A null
+ datetime is invalid, since the date is invalid.
+
+ \sa isValid()
+*/
+QDateTime::QDateTime()
+{
+ d = new QDateTimePrivate;
+}
+
+
+/*!
+ Constructs a datetime with the given \a date, a valid
+ time(00:00:00.000), and sets the timeSpec() to Qt::LocalTime.
+*/
+
+QDateTime::QDateTime(const QDate &date)
+{
+ d = new QDateTimePrivate;
+ d->date = date;
+ d->time = QTime(0, 0, 0);
+}
+
+/*!
+ Constructs a datetime with the given \a date and \a time, using
+ the time specification defined by \a spec.
+
+ If \a date is valid and \a time is not, the time will be set to midnight.
+*/
+
+QDateTime::QDateTime(const QDate &date, const QTime &time, Qt::TimeSpec spec)
+{
+ d = new QDateTimePrivate;
+ d->date = date;
+ d->time = date.isValid() && !time.isValid() ? QTime(0, 0, 0) : time;
+ d->spec = (spec == Qt::UTC) ? QDateTimePrivate::UTC : QDateTimePrivate::LocalUnknown;
+}
+
+/*!
+ Constructs a copy of the \a other datetime.
+*/
+
+QDateTime::QDateTime(const QDateTime &other)
+{
+ d = other.d;
+ d->ref.ref();
+}
+
+/*!
+ Destroys the datetime.
+*/
+QDateTime::~QDateTime()
+{
+ if (!d->ref.deref())
+ delete d;
+}
+
+/*!
+ Makes a copy of the \a other datetime and returns a reference to the
+ copy.
+*/
+
+QDateTime &QDateTime::operator=(const QDateTime &other)
+{
+ qAtomicAssign(d, other.d);
+ return *this;
+}
+
+/*!
+ Returns true if both the date and the time are null; otherwise
+ returns false. A null datetime is invalid.
+
+ \sa QDate::isNull(), QTime::isNull(), isValid()
+*/
+
+bool QDateTime::isNull() const
+{
+ return d->date.isNull() && d->time.isNull();
+}
+
+/*!
+ Returns true if both the date and the time are valid; otherwise
+ returns false.
+
+ \sa QDate::isValid(), QTime::isValid()
+*/
+
+bool QDateTime::isValid() const
+{
+ return d->date.isValid() && d->time.isValid();
+}
+
+/*!
+ Returns the date part of the datetime.
+
+ \sa setDate(), time(), timeSpec()
+*/
+
+QDate QDateTime::date() const
+{
+ return d->date;
+}
+
+/*!
+ Returns the time part of the datetime.
+
+ \sa setTime(), date(), timeSpec()
+*/
+
+QTime QDateTime::time() const
+{
+ return d->time;
+}
+
+/*!
+ Returns the time specification of the datetime.
+
+ \sa setTimeSpec(), date(), time(), Qt::TimeSpec
+*/
+
+Qt::TimeSpec QDateTime::timeSpec() const
+{
+ switch(d->spec)
+ {
+ case QDateTimePrivate::UTC:
+ return Qt::UTC;
+ case QDateTimePrivate::OffsetFromUTC:
+ return Qt::OffsetFromUTC;
+ default:
+ return Qt::LocalTime;
+ }
+}
+
+/*!
+ Sets the date part of this datetime to \a date.
+ If no time is set, it is set to midnight.
+
+ \sa date(), setTime(), setTimeSpec()
+*/
+
+void QDateTime::setDate(const QDate &date)
+{
+ detach();
+ d->date = date;
+ if (d->spec == QDateTimePrivate::LocalStandard
+ || d->spec == QDateTimePrivate::LocalDST)
+ d->spec = QDateTimePrivate::LocalUnknown;
+ if (date.isValid() && !d->time.isValid())
+ d->time = QTime(0, 0, 0);
+}
+
+/*!
+ Sets the time part of this datetime to \a time.
+
+ \sa time(), setDate(), setTimeSpec()
+*/
+
+void QDateTime::setTime(const QTime &time)
+{
+ detach();
+ if (d->spec == QDateTimePrivate::LocalStandard
+ || d->spec == QDateTimePrivate::LocalDST)
+ d->spec = QDateTimePrivate::LocalUnknown;
+ d->time = time;
+}
+
+/*!
+ Sets the time specification used in this datetime to \a spec.
+
+ \sa timeSpec(), setDate(), setTime(), Qt::TimeSpec
+*/
+
+void QDateTime::setTimeSpec(Qt::TimeSpec spec)
+{
+ detach();
+
+ switch(spec)
+ {
+ case Qt::UTC:
+ d->spec = QDateTimePrivate::UTC;
+ break;
+ case Qt::OffsetFromUTC:
+ d->spec = QDateTimePrivate::OffsetFromUTC;
+ break;
+ default:
+ d->spec = QDateTimePrivate::LocalUnknown;
+ break;
+ }
+}
+
+static uint toTime_tHelper(const QDate &utcDate, const QTime &utcTime)
+{
+ int days = QDate(1970, 1, 1).daysTo(utcDate);
+ int secs = QTime().secsTo(utcTime);
+ if (days < 0 || (days == 0 && secs < 0))
+ return uint(-1);
+
+ qlonglong retval = (qlonglong(days) * SECS_PER_DAY) + secs;
+ if (retval >= Q_INT64_C(0xFFFFFFFF))
+ return uint(-1);
+ return uint(retval);
+}
+
+/*!
+ Returns the datetime as the number of seconds that have passed
+ since 1970-01-01T00:00:00, Coordinated Universal Time (Qt::UTC).
+
+ On systems that do not support time zones, this function will
+ behave as if local time were Qt::UTC.
+
+ \sa setTime_t()
+*/
+
+uint QDateTime::toTime_t() const
+{
+ QDate utcDate;
+ QTime utcTime;
+ d->getUTC(utcDate, utcTime);
+
+ return toTime_tHelper(utcDate, utcTime);
+}
+
+/*!
+ \fn void QDateTime::setTime_t(uint seconds)
+
+ Sets the date and time given the number of \a seconds that have
+ passed since 1970-01-01T00:00:00, Coordinated Universal Time
+ (Qt::UTC). On systems that do not support time zones this function
+ will behave as if local time were Qt::UTC.
+
+ \sa toTime_t()
+*/
+
+void QDateTime::setTime_t(uint secsSince1Jan1970UTC)
+{
+ detach();
+
+ QDateTimePrivate::Spec oldSpec = d->spec;
+
+ d->date = QDate(1970, 1, 1).addDays(secsSince1Jan1970UTC / SECS_PER_DAY);
+ d->time = QTime().addSecs(secsSince1Jan1970UTC % SECS_PER_DAY);
+ d->spec = QDateTimePrivate::UTC;
+
+ if (oldSpec != QDateTimePrivate::UTC)
+ d->spec = d->getLocal(d->date, d->time);
+}
+
+#ifndef QT_NO_DATESTRING
+/*!
+ \fn QString QDateTime::toString(Qt::DateFormat format) const
+
+ \overload
+
+ Returns the datetime as a string in the \a format given.
+
+ If the \a format is Qt::TextDate, the string is formatted in
+ the default way. QDate::shortDayName(), QDate::shortMonthName(),
+ and QTime::toString() are used to generate the string, so the
+ day and month names will be localized names. An example of this
+ formatting is "Wed May 20 03:40:13 1998".
+
+ If the \a format is Qt::ISODate, the string format corresponds
+ to the ISO 8601 extended specification for representations of
+ dates and times, taking the form YYYY-MM-DDTHH:MM:SS.
+
+ If the \a format is Qt::SystemLocaleShortDate or
+ Qt::SystemLocaleLongDate, the string format depends on the locale
+ settings of the system. Identical to calling
+ QLocale::system().toString(datetime, QLocale::ShortFormat) or
+ QLocale::system().toString(datetime, QLocale::LongFormat).
+
+ If the \a format is Qt::DefaultLocaleShortDate or
+ Qt::DefaultLocaleLongDate, the string format depends on the
+ default application locale. This is the locale set with
+ QLocale::setDefault(), or the system locale if no default locale
+ has been set. Identical to calling QLocale().toString(datetime,
+ QLocale::ShortFormat) or QLocale().toString(datetime,
+ QLocale::LongFormat).
+
+ If the datetime is invalid, an empty string will be returned.
+
+ \warning The Qt::ISODate format is only valid for years in the
+ range 0 to 9999. This restriction may apply to locale-aware
+ formats as well, depending on the locale settings.
+
+ \sa QDate::toString() QTime::toString() Qt::DateFormat
+*/
+
+QString QDateTime::toString(Qt::DateFormat f) const
+{
+ QString buf;
+ if (!isValid())
+ return buf;
+
+ if (f == Qt::ISODate) {
+ buf = d->date.toString(Qt::ISODate);
+ if (buf.isEmpty())
+ return QString(); // failed to convert
+ buf += QLatin1Char('T');
+ buf += d->time.toString(Qt::ISODate);
+ }
+#ifndef QT_NO_TEXTDATE
+ else if (f == Qt::TextDate) {
+#ifndef Q_WS_WIN
+ buf = d->date.shortDayName(d->date.dayOfWeek());
+ buf += QLatin1Char(' ');
+ buf += d->date.shortMonthName(d->date.month());
+ buf += QLatin1Char(' ');
+ buf += QString::number(d->date.day());
+#else
+ QString winstr;
+ QT_WA({
+ TCHAR out[255];
+ GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_ILDATE, out, 255);
+ winstr = QString::fromUtf16((ushort*)out);
+ } , {
+ char out[255];
+ GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_ILDATE, (char*)&out, 255);
+ winstr = QString::fromLocal8Bit(out);
+ });
+ switch (winstr.toInt()) {
+ case 1:
+ buf = d->date.shortDayName(d->date.dayOfWeek());
+ buf += QLatin1Char(' ');
+ buf += QString::number(d->date.day());
+ buf += QLatin1String(". ");
+ buf += d->date.shortMonthName(d->date.month());
+ break;
+ default:
+ buf = d->date.shortDayName(d->date.dayOfWeek());
+ buf += QLatin1Char(' ');
+ buf += d->date.shortMonthName(d->date.month());
+ buf += QLatin1Char(' ');
+ buf += QString::number(d->date.day());
+ }
+#endif
+ buf += QLatin1Char(' ');
+ buf += d->time.toString();
+ buf += QLatin1Char(' ');
+ buf += QString::number(d->date.year());
+ }
+#endif
+ else {
+ buf = d->date.toString(f);
+ if (buf.isEmpty())
+ return QString(); // failed to convert
+ buf += QLatin1Char(' ');
+ buf += d->time.toString(f);
+ }
+
+ return buf;
+}
+
+/*!
+ Returns the datetime as a string. The \a format parameter
+ determines the format of the result string.
+
+ These expressions may be used for the date:
+
+ \table
+ \header \i Expression \i Output
+ \row \i d \i the day as number without a leading zero (1 to 31)
+ \row \i dd \i the day as number with a leading zero (01 to 31)
+ \row \i ddd
+ \i the abbreviated localized day name (e.g. 'Mon' to 'Sun').
+ Uses QDate::shortDayName().
+ \row \i dddd
+ \i the long localized day name (e.g. 'Monday' to 'Qt::Sunday').
+ Uses QDate::longDayName().
+ \row \i M \i the month as number without a leading zero (1-12)
+ \row \i MM \i the month as number with a leading zero (01-12)
+ \row \i MMM
+ \i the abbreviated localized month name (e.g. 'Jan' to 'Dec').
+ Uses QDate::shortMonthName().
+ \row \i MMMM
+ \i the long localized month name (e.g. 'January' to 'December').
+ Uses QDate::longMonthName().
+ \row \i yy \i the year as two digit number (00-99)
+ \row \i yyyy \i the year as four digit number
+ \endtable
+
+ These expressions may be used for the time:
+
+ \table
+ \header \i Expression \i Output
+ \row \i h
+ \i the hour without a leading zero (0 to 23 or 1 to 12 if AM/PM display)
+ \row \i hh
+ \i the hour with a leading zero (00 to 23 or 01 to 12 if AM/PM display)
+ \row \i m \i the minute without a leading zero (0 to 59)
+ \row \i mm \i the minute with a leading zero (00 to 59)
+ \row \i s \i the second without a leading zero (0 to 59)
+ \row \i ss \i the second with a leading zero (00 to 59)
+ \row \i z \i the milliseconds without leading zeroes (0 to 999)
+ \row \i zzz \i the milliseconds with leading zeroes (000 to 999)
+ \row \i AP
+ \i use AM/PM display. \e AP will be replaced by either "AM" or "PM".
+ \row \i ap
+ \i use am/pm display. \e ap will be replaced by either "am" or "pm".
+ \endtable
+
+ All other input characters will be ignored. Any sequence of characters that
+ are enclosed in singlequotes will be treated as text and not be used as an
+ expression. Two consecutive singlequotes ("''") are replaced by a singlequote
+ in the output.
+
+ Example format strings (assumed that the QDateTime is 21 May 2001
+ 14:13:09):
+
+ \table
+ \header \i Format \i Result
+ \row \i dd.MM.yyyy \i 21.05.2001
+ \row \i ddd MMMM d yy \i Tue May 21 01
+ \row \i hh:mm:ss.zzz \i 14:13:09.042
+ \row \i h:m:s ap \i 2:13:9 pm
+ \endtable
+
+ If the datetime is invalid, an empty string will be returned.
+
+ \sa QDate::toString() QTime::toString()
+*/
+QString QDateTime::toString(const QString& format) const
+{
+ return fmtDateTime(format, &d->time, &d->date);
+}
+#endif //QT_NO_DATESTRING
+
+/*!
+ Returns a QDateTime object containing a datetime \a ndays days
+ later than the datetime of this object (or earlier if \a ndays is
+ negative).
+
+ \sa daysTo(), addMonths(), addYears(), addSecs()
+*/
+
+QDateTime QDateTime::addDays(int ndays) const
+{
+ return QDateTime(d->date.addDays(ndays), d->time, timeSpec());
+}
+
+/*!
+ Returns a QDateTime object containing a datetime \a nmonths months
+ later than the datetime of this object (or earlier if \a nmonths
+ is negative).
+
+ \sa daysTo(), addDays(), addYears(), addSecs()
+*/
+
+QDateTime QDateTime::addMonths(int nmonths) const
+{
+ return QDateTime(d->date.addMonths(nmonths), d->time, timeSpec());
+}
+
+/*!
+ Returns a QDateTime object containing a datetime \a nyears years
+ later than the datetime of this object (or earlier if \a nyears is
+ negative).
+
+ \sa daysTo(), addDays(), addMonths(), addSecs()
+*/
+
+QDateTime QDateTime::addYears(int nyears) const
+{
+ return QDateTime(d->date.addYears(nyears), d->time, timeSpec());
+}
+
+QDateTime QDateTimePrivate::addMSecs(const QDateTime &dt, qint64 msecs)
+{
+ QDate utcDate;
+ QTime utcTime;
+ dt.d->getUTC(utcDate, utcTime);
+
+ addMSecs(utcDate, utcTime, msecs);
+
+ return QDateTime(utcDate, utcTime, Qt::UTC).toTimeSpec(dt.timeSpec());
+}
+
+/*!
+ Adds \a msecs to utcDate and \a utcTime as appropriate. It is assumed that
+ utcDate and utcTime are adjusted to UTC.
+
+ \since 4.5
+ \internal
+ */
+void QDateTimePrivate::addMSecs(QDate &utcDate, QTime &utcTime, qint64 msecs)
+{
+ uint dd = utcDate.jd;
+ int tt = utcTime.ds();
+ int sign = 1;
+ if (msecs < 0) {
+ msecs = -msecs;
+ sign = -1;
+ }
+ if (msecs >= int(MSECS_PER_DAY)) {
+ dd += sign * (msecs / MSECS_PER_DAY);
+ msecs %= MSECS_PER_DAY;
+ }
+
+ tt += sign * msecs;
+ if (tt < 0) {
+ tt = MSECS_PER_DAY - tt - 1;
+ dd -= tt / MSECS_PER_DAY;
+ tt = tt % MSECS_PER_DAY;
+ tt = MSECS_PER_DAY - tt - 1;
+ } else if (tt >= int(MSECS_PER_DAY)) {
+ dd += tt / MSECS_PER_DAY;
+ tt = tt % MSECS_PER_DAY;
+ }
+
+ utcDate.jd = dd;
+ utcTime.mds = tt;
+}
+
+/*!
+ Returns a QDateTime object containing a datetime \a s seconds
+ later than the datetime of this object (or earlier if \a s is
+ negative).
+
+ \sa addMSecs(), secsTo(), addDays(), addMonths(), addYears()
+*/
+
+QDateTime QDateTime::addSecs(int s) const
+{
+ return d->addMSecs(*this, qint64(s) * 1000);
+}
+
+/*!
+ Returns a QDateTime object containing a datetime \a msecs miliseconds
+ later than the datetime of this object (or earlier if \a msecs is
+ negative).
+
+ \sa addSecs(), secsTo(), addDays(), addMonths(), addYears()
+*/
+QDateTime QDateTime::addMSecs(qint64 msecs) const
+{
+ return d->addMSecs(*this, msecs);
+}
+
+/*!
+ Returns the number of days from this datetime to the \a other
+ datetime. If the \a other datetime is earlier than this datetime,
+ the value returned is negative.
+
+ \sa addDays(), secsTo()
+*/
+
+int QDateTime::daysTo(const QDateTime &other) const
+{
+ return d->date.daysTo(other.d->date);
+}
+
+/*!
+ Returns the number of seconds from this datetime to the \a other
+ datetime. If the \a other datetime is earlier than this datetime,
+ the value returned is negative.
+
+ Before performing the comparison, the two datetimes are converted
+ to Qt::UTC to ensure that the result is correct if one of the two
+ datetimes has daylight saving time (DST) and the other doesn't.
+
+ Example:
+ \snippet doc/src/snippets/code/src_corelib_tools_qdatetime.cpp 11
+
+ \sa addSecs(), daysTo(), QTime::secsTo()
+*/
+
+int QDateTime::secsTo(const QDateTime &other) const
+{
+ QDate date1, date2;
+ QTime time1, time2;
+
+ d->getUTC(date1, time1);
+ other.d->getUTC(date2, time2);
+
+ return (date1.daysTo(date2) * SECS_PER_DAY) + time1.secsTo(time2);
+}
+
+/*!
+ \fn QDateTime QDateTime::toTimeSpec(Qt::TimeSpec specification) const
+
+ Returns a copy of this datetime configured to use the given time
+ \a specification.
+
+ \sa timeSpec(), toUTC(), toLocalTime()
+*/
+
+QDateTime QDateTime::toTimeSpec(Qt::TimeSpec spec) const
+{
+ if ((d->spec == QDateTimePrivate::UTC) == (spec == Qt::UTC))
+ return *this;
+
+ QDateTime ret;
+ if (spec == Qt::UTC) {
+ d->getUTC(ret.d->date, ret.d->time);
+ ret.d->spec = QDateTimePrivate::UTC;
+ } else {
+ ret.d->spec = d->getLocal(ret.d->date, ret.d->time);
+ }
+ return ret;
+}
+
+/*!
+ Returns true if this datetime is equal to the \a other datetime;
+ otherwise returns false.
+
+ \sa operator!=()
+*/
+
+bool QDateTime::operator==(const QDateTime &other) const
+{
+ if (d->spec == other.d->spec && d->utcOffset == other.d->utcOffset)
+ return d->time == other.d->time && d->date == other.d->date;
+ else {
+ QDate date1, date2;
+ QTime time1, time2;
+
+ d->getUTC(date1, time1);
+ other.d->getUTC(date2, time2);
+ return time1 == time2 && date1 == date2;
+ }
+}
+
+/*!
+ \fn bool QDateTime::operator!=(const QDateTime &other) const
+
+ Returns true if this datetime is different from the \a other
+ datetime; otherwise returns false.
+
+ Two datetimes are different if either the date, the time, or the
+ time zone components are different.
+
+ \sa operator==()
+*/
+
+/*!
+ Returns true if this datetime is earlier than the \a other
+ datetime; otherwise returns false.
+*/
+
+bool QDateTime::operator<(const QDateTime &other) const
+{
+ if (d->spec == other.d->spec && d->spec != QDateTimePrivate::OffsetFromUTC) {
+ if (d->date != other.d->date)
+ return d->date < other.d->date;
+ return d->time < other.d->time;
+ } else {
+ QDate date1, date2;
+ QTime time1, time2;
+ d->getUTC(date1, time1);
+ other.d->getUTC(date2, time2);
+ if (date1 != date2)
+ return date1 < date2;
+ return time1 < time2;
+ }
+}
+
+/*!
+ \fn bool QDateTime::operator<=(const QDateTime &other) const
+
+ Returns true if this datetime is earlier than or equal to the
+ \a other datetime; otherwise returns false.
+*/
+
+/*!
+ \fn bool QDateTime::operator>(const QDateTime &other) const
+
+ Returns true if this datetime is later than the \a other datetime;
+ otherwise returns false.
+*/
+
+/*!
+ \fn bool QDateTime::operator>=(const QDateTime &other) const
+
+ Returns true if this datetime is later than or equal to the
+ \a other datetime; otherwise returns false.
+*/
+
+/*!
+ Returns the current datetime, as reported by the system clock, in
+ the local time zone.
+
+ \sa QDate::currentDate(), QTime::currentTime(), toTimeSpec()
+*/
+
+QDateTime QDateTime::currentDateTime()
+{
+#if defined(Q_OS_WIN)
+ QDate d;
+ QTime t;
+ SYSTEMTIME st;
+ memset(&st, 0, sizeof(SYSTEMTIME));
+ GetLocalTime(&st);
+ d.jd = julianDayFromDate(st.wYear, st.wMonth, st.wDay);
+ t.mds = MSECS_PER_HOUR * st.wHour + MSECS_PER_MIN * st.wMinute + 1000 * st.wSecond
+ + st.wMilliseconds;
+ return QDateTime(d, t);
+#else
+#if defined(Q_OS_UNIX)
+ // posix compliant system
+ // we have milliseconds
+ struct timeval tv;
+ gettimeofday(&tv, 0);
+ time_t ltime = tv.tv_sec;
+ tm *t = 0;
+
+#if !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS)
+ // use the reentrant version of localtime() where available
+ tzset();
+ tm res;
+ t = localtime_r(&ltime, &res);
+#else
+ t = localtime(&ltime);
+#endif
+
+ QDateTime dt;
+ dt.d->time.mds = MSECS_PER_HOUR * t->tm_hour + MSECS_PER_MIN * t->tm_min + 1000 * t->tm_sec
+ + tv.tv_usec / 1000;
+#else
+ time_t ltime; // no millisecond resolution
+ ::time(&ltime);
+ tm *t = 0;
+ localtime(&ltime);
+ dt.d->time.mds = MSECS_PER_HOUR * t->tm_hour + MSECS_PER_MIN * t->tm_min + 1000 * t->tm_sec;
+#endif // Q_OS_UNIX
+
+ dt.d->date.jd = julianDayFromDate(t->tm_year + 1900, t->tm_mon + 1, t->tm_mday);
+ dt.d->spec = t->tm_isdst > 0 ? QDateTimePrivate::LocalDST :
+ t->tm_isdst == 0 ? QDateTimePrivate::LocalStandard :
+ QDateTimePrivate::LocalUnknown;
+ return dt;
+#endif
+}
+
+/*!
+ \since 4.2
+
+ Returns a datetime whose date and time are the number of \a seconds
+ that have passed since 1970-01-01T00:00:00, Coordinated Universal
+ Time (Qt::UTC). On systems that do not support time zones, the time
+ will be set as if local time were Qt::UTC.
+
+ \sa toTime_t(), setTime_t()
+*/
+QDateTime QDateTime::fromTime_t(uint seconds)
+{
+ QDateTime d;
+ d.setTime_t(seconds);
+ return d;
+}
+
+/*!
+ \since 4.4
+ \internal
+
+ Sets the offset from UTC to \a seconds, and also sets timeSpec() to
+ Qt::OffsetFromUTC.
+
+ The maximum and minimum offset is 14 positive or negative hours. If
+ \a seconds is larger or smaller than that, the result is undefined.
+
+ 0 as offset is identical to UTC. Therefore, if \a seconds is 0, the
+ timeSpec() will be set to Qt::UTC. Hence the UTC offset always
+ relates to UTC, and can never relate to local time.
+
+ \sa isValid(), utcOffset()
+ */
+void QDateTime::setUtcOffset(int seconds)
+{
+ detach();
+
+ /* The motivation to also setting d->spec is to ensure that the QDateTime
+ * instance stay in well-defined states all the time, instead of that
+ * we instruct the user to ensure it. */
+ if(seconds == 0)
+ d->spec = QDateTimePrivate::UTC;
+ else
+ d->spec = QDateTimePrivate::OffsetFromUTC;
+
+ /* Even if seconds is 0 we assign it to utcOffset. */
+ d->utcOffset = seconds;
+}
+
+/*!
+ \since 4.4
+ \internal
+
+ Returns the UTC offset in seconds. If the timeSpec() isn't
+ Qt::OffsetFromUTC, 0 is returned. However, since 0 is a valid UTC
+ offset the return value of this function cannot be used to determine
+ whether a utcOffset() is used or is valid, timeSpec() must be
+ checked.
+
+ Likewise, if this QDateTime() is invalid or if timeSpec() isn't
+ Qt::OffsetFromUTC, 0 is returned.
+
+ The UTC offset only applies if the timeSpec() is Qt::OffsetFromUTC.
+
+ \sa isValid(), setUtcOffset()
+ */
+int QDateTime::utcOffset() const
+{
+ if(isValid() && d->spec == QDateTimePrivate::OffsetFromUTC)
+ return d->utcOffset;
+ else
+ return 0;
+}
+
+#ifndef QT_NO_DATESTRING
+
+static int fromShortMonthName(const QString &monthName)
+{
+ // Assume that English monthnames are the default
+ for (int i = 0; i < 12; ++i) {
+ if (monthName == QLatin1String(qt_shortMonthNames[i]))
+ return i + 1;
+ }
+ // If English names can't be found, search the localized ones
+ for (int i = 1; i <= 12; ++i) {
+ if (monthName == QDate::shortMonthName(i))
+ return i;
+ }
+ return -1;
+}
+
+/*!
+ \fn QDateTime QDateTime::fromString(const QString &string, Qt::DateFormat format)
+
+ Returns the QDateTime represented by the \a string, using the
+ \a format given, or an invalid datetime if this is not possible.
+
+ Note for Qt::TextDate: It is recommended that you use the
+ English short month names (e.g. "Jan"). Although localized month
+ names can also be used, they depend on the user's locale settings.
+*/
+QDateTime QDateTime::fromString(const QString& s, Qt::DateFormat f)
+{
+ if (s.isEmpty()) {
+ return QDateTime();
+ }
+
+ switch (f) {
+ case Qt::ISODate: {
+ QString tmp = s;
+ Qt::TimeSpec ts = Qt::LocalTime;
+ const QDate date = QDate::fromString(tmp.left(10), Qt::ISODate);
+ if (tmp.size() == 10)
+ return QDateTime(date);
+
+ // Recognize UTC specifications
+ if (tmp.endsWith(QLatin1Char('Z'))) {
+ ts = Qt::UTC;
+ tmp.chop(1);
+ }
+ return QDateTime(date, QTime::fromString(tmp.mid(11), Qt::ISODate), ts);
+ }
+ case Qt::SystemLocaleDate:
+ case Qt::SystemLocaleShortDate:
+ case Qt::SystemLocaleLongDate:
+ return fromString(s, QLocale::system().dateTimeFormat(f == Qt::SystemLocaleLongDate ? QLocale::LongFormat
+ : QLocale::ShortFormat));
+ case Qt::LocaleDate:
+ case Qt::DefaultLocaleShortDate:
+ case Qt::DefaultLocaleLongDate:
+ return fromString(s, QLocale().dateTimeFormat(f == Qt::DefaultLocaleLongDate ? QLocale::LongFormat
+ : QLocale::ShortFormat));
+#if !defined(QT_NO_TEXTDATE)
+ case Qt::TextDate: {
+ QStringList parts = s.split(QLatin1Char(' '), QString::SkipEmptyParts);
+
+ if ((parts.count() < 5) || (parts.count() > 6)) {
+ return QDateTime();
+ }
+
+ // Accept "Sun Dec 1 13:02:00 1974" and "Sun 1. Dec 13:02:00 1974"
+ int month = -1, day = -1;
+ bool ok;
+
+ month = fromShortMonthName(parts.at(1));
+ if (month != -1) {
+ day = parts.at(2).toInt(&ok);
+ if (!ok)
+ day = -1;
+ }
+
+ if (month == -1 || day == -1) {
+ // first variant failed, lets try the other
+ month = fromShortMonthName(parts.at(2));
+ if (month != -1) {
+ QString dayStr = parts.at(1);
+ if (dayStr.endsWith(QLatin1Char('.'))) {
+ dayStr.chop(1);
+ day = dayStr.toInt(&ok);
+ if (!ok)
+ day = -1;
+ } else {
+ day = -1;
+ }
+ }
+ }
+
+ if (month == -1 || day == -1) {
+ // both variants failed, give up
+ return QDateTime();
+ }
+
+ int year;
+ QStringList timeParts = parts.at(3).split(QLatin1Char(':'));
+ if ((timeParts.count() == 3) || (timeParts.count() == 2)) {
+ year = parts.at(4).toInt(&ok);
+ if (!ok)
+ return QDateTime();
+ } else {
+ timeParts = parts.at(4).split(QLatin1Char(':'));
+ if ((timeParts.count() != 3) && (timeParts.count() != 2))
+ return QDateTime();
+ year = parts.at(3).toInt(&ok);
+ if (!ok)
+ return QDateTime();
+ }
+
+ int hour = timeParts.at(0).toInt(&ok);
+ if (!ok) {
+ return QDateTime();
+ }
+
+ int minute = timeParts.at(1).toInt(&ok);
+ if (!ok) {
+ return QDateTime();
+ }
+
+ int second = (timeParts.count() > 2) ? timeParts.at(2).toInt(&ok) : 0;
+ if (!ok) {
+ return QDateTime();
+ }
+
+ QDate date(year, month, day);
+ QTime time(hour, minute, second);
+
+ if (parts.count() == 5)
+ return QDateTime(date, time, Qt::LocalTime);
+
+ QString tz = parts.at(5);
+ if (!tz.startsWith(QLatin1String("GMT"), Qt::CaseInsensitive))
+ return QDateTime();
+ int tzoffset = 0;
+ if (tz.length() > 3) {
+ QChar sign = tz.at(3);
+ if ((sign != QLatin1Char('+'))
+ && (sign != QLatin1Char('-'))) {
+ return QDateTime();
+ }
+ int tzhour = tz.mid(4, 2).toInt(&ok);
+ if (!ok)
+ return QDateTime();
+ int tzminute = tz.mid(6).toInt(&ok);
+ if (!ok)
+ return QDateTime();
+ tzoffset = (tzhour*60 + tzminute) * 60;
+ if (sign == QLatin1Char('-'))
+ tzoffset = -tzoffset;
+ }
+ return QDateTime(date, time, Qt::UTC).addSecs(-tzoffset).toLocalTime();
+ }
+#endif //QT_NO_TEXTDATE
+ }
+
+ return QDateTime();
+}
+
+/*!
+ \fn QDateTime::fromString(const QString &string, const QString &format)
+
+ Returns the QDateTime represented by the \a string, using the \a
+ format given, or an invalid datetime if the string cannot be parsed.
+
+ These expressions may be used for the date part of the format string:
+
+ \table
+ \header \i Expression \i Output
+ \row \i d \i the day as number without a leading zero (1 to 31)
+ \row \i dd \i the day as number with a leading zero (01 to 31)
+ \row \i ddd
+ \i the abbreviated localized day name (e.g. 'Mon' to 'Sun').
+ Uses QDate::shortDayName().
+ \row \i dddd
+ \i the long localized day name (e.g. 'Monday' to 'Sunday').
+ Uses QDate::longDayName().
+ \row \i M \i the month as number without a leading zero (1-12)
+ \row \i MM \i the month as number with a leading zero (01-12)
+ \row \i MMM
+ \i the abbreviated localized month name (e.g. 'Jan' to 'Dec').
+ Uses QDate::shortMonthName().
+ \row \i MMMM
+ \i the long localized month name (e.g. 'January' to 'December').
+ Uses QDate::longMonthName().
+ \row \i yy \i the year as two digit number (00-99)
+ \row \i yyyy \i the year as four digit number
+ \endtable
+
+ \note Unlike the other version of this function, day and month names must
+ be given in the user's local language. It is only possible to use the English
+ names if the user's language is English.
+
+ These expressions may be used for the time part of the format string:
+
+ \table
+ \header \i Expression \i Output
+ \row \i h
+ \i the hour without a leading zero (0 to 23 or 1 to 12 if AM/PM display)
+ \row \i hh
+ \i the hour with a leading zero (00 to 23 or 01 to 12 if AM/PM display)
+ \row \i H
+ \i the hour without a leading zero (0 to 23, even with AM/PM display)
+ \row \i HH
+ \i the hour with a leading zero (00 to 23, even with AM/PM display)
+ \row \i m \i the minute without a leading zero (0 to 59)
+ \row \i mm \i the minute with a leading zero (00 to 59)
+ \row \i s \i the second without a leading zero (0 to 59)
+ \row \i ss \i the second with a leading zero (00 to 59)
+ \row \i z \i the milliseconds without leading zeroes (0 to 999)
+ \row \i zzz \i the milliseconds with leading zeroes (000 to 999)
+ \row \i AP or A
+ \i interpret as an AM/PM time. \e AP must be either "AM" or "PM".
+ \row \i ap or a
+ \i Interpret as an AM/PM time. \e ap must be either "am" or "pm".
+ \endtable
+
+ All other input characters will be treated as text. Any sequence
+ of characters that are enclosed in singlequotes will also be
+ treated as text and not be used as an expression.
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qdatetime.cpp 12
+
+ If the format is not satisfied an invalid QDateTime is returned.
+ The expressions that don't have leading zeroes (d, M, h, m, s, z) will be
+ greedy. This means that they will use two digits even if this will
+ put them outside the range and/or leave too few digits for other
+ sections.
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qdatetime.cpp 13
+
+ This could have meant 1 January 00:30.00 but the M will grab
+ two digits.
+
+ For any field that is not represented in the format the following
+ defaults are used:
+
+ \table
+ \header \i Field \i Default value
+ \row \i Year \i 1900
+ \row \i Month \i 1 (January)
+ \row \i Day \i 1
+ \row \i Hour \i 0
+ \row \i Minute \i 0
+ \row \i Second \i 0
+ \endtable
+
+ For example:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qdatetime.cpp 14
+
+ \sa QDate::fromString() QTime::fromString() QDate::toString()
+ QDateTime::toString() QTime::toString()
+*/
+
+QDateTime QDateTime::fromString(const QString &string, const QString &format)
+{
+#ifndef QT_BOOTSTRAPPED
+ QTime time;
+ QDate date;
+
+ QDateTimeParser dt(QVariant::DateTime, QDateTimeParser::FromString);
+ 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 // QT_NO_DATESTRING
+/*!
+ \fn QDateTime QDateTime::toLocalTime() const
+
+ Returns a datetime containing the date and time information in
+ this datetime, but specified using the Qt::LocalTime definition.
+
+ \sa toTimeSpec()
+*/
+
+/*!
+ \fn QDateTime QDateTime::toUTC() const
+
+ Returns a datetime containing the date and time information in
+ this datetime, but specified using the Qt::UTC definition.
+
+ \sa toTimeSpec()
+*/
+
+/*! \internal
+ */
+void QDateTime::detach()
+{
+ qAtomicDetach(d);
+}
+
+/*****************************************************************************
+ Date/time stream functions
+ *****************************************************************************/
+
+#ifndef QT_NO_DATASTREAM
+/*!
+ \relates QDate
+
+ Writes the \a date to stream \a out.
+
+ \sa {Format of the QDataStream operators}
+*/
+
+QDataStream &operator<<(QDataStream &out, const QDate &date)
+{
+ return out << (quint32)(date.jd);
+}
+
+/*!
+ \relates QDate
+
+ Reads a date from stream \a in into the \a date.
+
+ \sa {Format of the QDataStream operators}
+*/
+
+QDataStream &operator>>(QDataStream &in, QDate &date)
+{
+ quint32 jd;
+ in >> jd;
+ date.jd = jd;
+ return in;
+}
+
+/*!
+ \relates QTime
+
+ Writes \a time to stream \a out.
+
+ \sa {Format of the QDataStream operators}
+*/
+
+QDataStream &operator<<(QDataStream &out, const QTime &time)
+{
+ return out << quint32(time.mds);
+}
+
+/*!
+ \relates QTime
+
+ Reads a time from stream \a in into the given \a time.
+
+ \sa {Format of the QDataStream operators}
+*/
+
+QDataStream &operator>>(QDataStream &in, QTime &time)
+{
+ quint32 ds;
+ in >> ds;
+ time.mds = int(ds);
+ return in;
+}
+
+/*!
+ \relates QDateTime
+
+ Writes \a dateTime to the \a out stream.
+
+ \sa {Format of the QDataStream operators}
+*/
+QDataStream &operator<<(QDataStream &out, const QDateTime &dateTime)
+{
+ out << dateTime.d->date << dateTime.d->time;
+ if (out.version() >= 7)
+ out << (qint8)dateTime.d->spec;
+ return out;
+}
+
+/*!
+ \relates QDateTime
+
+ Reads a datetime from the stream \a in into \a dateTime.
+
+ \sa {Format of the QDataStream operators}
+*/
+
+QDataStream &operator>>(QDataStream &in, QDateTime &dateTime)
+{
+ dateTime.detach();
+
+ qint8 ts = (qint8)QDateTimePrivate::LocalUnknown;
+ in >> dateTime.d->date >> dateTime.d->time;
+ if (in.version() >= 7)
+ in >> ts;
+ dateTime.d->spec = (QDateTimePrivate::Spec)ts;
+ return in;
+}
+#endif // QT_NO_DATASTREAM
+
+
+/*!
+ \fn QString QDate::monthName(int month)
+
+ Use shortMonthName() instead.
+*/
+
+/*!
+ \fn QString QDate::dayName(int weekday)
+
+ Use shortDayName() instead.
+*/
+
+/*!
+ \fn bool QDate::leapYear(int year)
+
+ Use isLeapYear() instead.
+*/
+
+/*!
+ \fn QDate QDate::currentDate(Qt::TimeSpec spec)
+
+ If \a spec is Qt::LocalTime, use the currentDate() overload that
+ takes no parameters instead; otherwise, use
+ QDateTime::currentDateTime().
+
+ \oldcode
+ QDate localDate = QDate::currentDate(Qt::LocalTime);
+ QDate utcDate = QDate::currentDate(Qt::UTC);
+ \newcode
+ QDate localDate = QDate::currentDate();
+ QDate utcDate = QDateTime::currentDateTime().toUTC().date();
+ \endcode
+
+ \sa QDateTime::toUTC()
+*/
+
+/*!
+ \fn QTime QTime::currentTime(Qt::TimeSpec specification)
+
+ Returns the current time for the given \a specification.
+
+ To replace uses of this function where the \a specification is Qt::LocalTime,
+ use the currentDate() overload that takes no parameters instead; otherwise,
+ use QDateTime::currentDateTime() and convert the result to a UTC measurement.
+
+ \oldcode
+ QTime localTime = QTime::currentTime(Qt::LocalTime);
+ QTime utcTime = QTime::currentTime(Qt::UTC);
+ \newcode
+ QTime localTime = QTime::currentTime();
+ QTime utcTime = QTimeTime::currentDateTime().toUTC().time();
+ \endcode
+
+ \sa QDateTime::toUTC()
+*/
+
+/*!
+ \fn void QDateTime::setTime_t(uint secsSince1Jan1970UTC, Qt::TimeSpec spec)
+
+ Use the single-argument overload of setTime_t() instead.
+*/
+
+/*!
+ \fn QDateTime QDateTime::currentDateTime(Qt::TimeSpec spec)
+
+ Use the currentDateTime() overload that takes no parameters
+ instead.
+*/
+
+// checks if there is an unqoted 'AP' or 'ap' in the string
+static bool hasUnquotedAP(const QString &f)
+{
+ const QLatin1Char quote('\'');
+ bool inquote = false;
+ const int max = f.size();
+ for (int i=0; i<max; ++i) {
+ if (f.at(i) == quote) {
+ inquote = !inquote;
+ } else if (!inquote && f.at(i).toUpper() == QLatin1Char('A')) {
+ return true;
+ }
+ }
+ return false;
+}
+
+#ifndef QT_NO_DATESTRING
+/*****************************************************************************
+ Some static function used by QDate, QTime and QDateTime
+*****************************************************************************/
+
+// Replaces tokens by their value. See QDateTime::toString() for a list of valid tokens
+static QString getFmtString(const QString& f, const QTime* dt = 0, const QDate* dd = 0, bool am_pm = false)
+{
+ if (f.isEmpty())
+ return QString();
+
+ QString buf = f;
+ int removed = 0;
+
+ if (dt) {
+ if (f.startsWith(QLatin1String("hh")) || f.startsWith(QLatin1String("HH"))) {
+ const bool hour12 = f.at(0) == QLatin1Char('h') && am_pm;
+ if (hour12 && dt->hour() > 12)
+ buf = QString::number(dt->hour() - 12).rightJustified(2, QLatin1Char('0'), true);
+ else if (hour12 && dt->hour() == 0)
+ buf = QLatin1String("12");
+ else
+ buf = QString::number(dt->hour()).rightJustified(2, QLatin1Char('0'), true);
+ removed = 2;
+ } else if (f.at(0) == QLatin1Char('h') || f.at(0) == QLatin1Char('H')) {
+ const bool hour12 = f.at(0) == QLatin1Char('h') && am_pm;
+ if (hour12 && dt->hour() > 12)
+ buf = QString::number(dt->hour() - 12);
+ else if (hour12 && dt->hour() == 0)
+ buf = QLatin1String("12");
+ else
+ buf = QString::number(dt->hour());
+ removed = 1;
+ } else if (f.startsWith(QLatin1String("mm"))) {
+ buf = QString::number(dt->minute()).rightJustified(2, QLatin1Char('0'), true);
+ removed = 2;
+ } else if (f.at(0) == (QLatin1Char('m'))) {
+ buf = QString::number(dt->minute());
+ removed = 1;
+ } else if (f.startsWith(QLatin1String("ss"))) {
+ buf = QString::number(dt->second()).rightJustified(2, QLatin1Char('0'), true);
+ removed = 2;
+ } else if (f.at(0) == QLatin1Char('s')) {
+ buf = QString::number(dt->second());
+ } else if (f.startsWith(QLatin1String("zzz"))) {
+ buf = QString::number(dt->msec()).rightJustified(3, QLatin1Char('0'), true);
+ removed = 3;
+ } else if (f.at(0) == QLatin1Char('z')) {
+ buf = QString::number(dt->msec());
+ removed = 1;
+ } else if (f.at(0).toUpper() == QLatin1Char('A')) {
+ const bool upper = f.at(0) == QLatin1Char('A');
+ buf = dt->hour() < 12 ? QLatin1String("am") : QLatin1String("pm");
+ if (upper)
+ buf = buf.toUpper();
+ if (f.size() > 1 && f.at(1).toUpper() == QLatin1Char('P') &&
+ f.at(0).isUpper() == f.at(1).isUpper()) {
+ removed = 2;
+ } else {
+ removed = 1;
+ }
+ }
+ }
+
+ if (dd) {
+ if (f.startsWith(QLatin1String("dddd"))) {
+ buf = dd->longDayName(dd->dayOfWeek());
+ removed = 4;
+ } else if (f.startsWith(QLatin1String("ddd"))) {
+ buf = dd->shortDayName(dd->dayOfWeek());
+ removed = 3;
+ } else if (f.startsWith(QLatin1String("dd"))) {
+ buf = QString::number(dd->day()).rightJustified(2, QLatin1Char('0'), true);
+ removed = 2;
+ } else if (f.at(0) == QLatin1Char('d')) {
+ buf = QString::number(dd->day());
+ removed = 1;
+ } else if (f.startsWith(QLatin1String("MMMM"))) {
+ buf = dd->longMonthName(dd->month());
+ removed = 4;
+ } else if (f.startsWith(QLatin1String("MMM"))) {
+ buf = dd->shortMonthName(dd->month());
+ removed = 3;
+ } else if (f.startsWith(QLatin1String("MM"))) {
+ buf = QString::number(dd->month()).rightJustified(2, QLatin1Char('0'), true);
+ removed = 2;
+ } else if (f.at(0) == QLatin1Char('M')) {
+ buf = QString::number(dd->month());
+ removed = 1;
+ } else if (f.startsWith(QLatin1String("yyyy"))) {
+ const int year = dd->year();
+ buf = QString::number(qAbs(year)).rightJustified(4, QLatin1Char('0'));
+ if(year > 0)
+ removed = 4;
+ else
+ {
+ buf.prepend(QLatin1Char('-'));
+ removed = 5;
+ }
+
+ } else if (f.startsWith(QLatin1String("yy"))) {
+ buf = QString::number(dd->year()).right(2).rightJustified(2, QLatin1Char('0'));
+ removed = 2;
+ }
+ }
+ if (removed == 0 || removed >= f.size()) {
+ return buf;
+ }
+
+ return buf + getFmtString(f.mid(removed), dt, dd, am_pm);
+}
+
+// Parses the format string and uses getFmtString to get the values for the tokens. Ret
+static QString fmtDateTime(const QString& f, const QTime* dt, const QDate* dd)
+{
+ const QLatin1Char quote('\'');
+ if (f.isEmpty())
+ return QString();
+ if (dt && !dt->isValid())
+ return QString();
+ if (dd && !dd->isValid())
+ return QString();
+
+ const bool ap = hasUnquotedAP(f);
+
+ QString buf;
+ QString frm;
+ QChar status(QLatin1Char('0'));
+
+ for (int i = 0; i < (int)f.length(); ++i) {
+ if (f.at(i) == quote) {
+ if (status == quote) {
+ if (i > 0 && f.at(i - 1) == quote)
+ buf += QLatin1Char('\'');
+ status = QLatin1Char('0');
+ } else {
+ if (!frm.isEmpty()) {
+ buf += getFmtString(frm, dt, dd, ap);
+ frm.clear();
+ }
+ status = quote;
+ }
+ } else if (status == quote) {
+ buf += f.at(i);
+ } else if (f.at(i) == status) {
+ if ((ap) && ((f.at(i) == QLatin1Char('P')) || (f.at(i) == QLatin1Char('p'))))
+ status = QLatin1Char('0');
+ frm += f.at(i);
+ } else {
+ buf += getFmtString(frm, dt, dd, ap);
+ frm.clear();
+ if ((f.at(i) == QLatin1Char('h')) || (f.at(i) == QLatin1Char('m'))
+ || (f.at(i) == QLatin1Char('H'))
+ || (f.at(i) == QLatin1Char('s')) || (f.at(i) == QLatin1Char('z'))) {
+ status = f.at(i);
+ frm += f.at(i);
+ } else if ((f.at(i) == QLatin1Char('d')) || (f.at(i) == QLatin1Char('M')) || (f.at(i) == QLatin1Char('y'))) {
+ status = f.at(i);
+ frm += f.at(i);
+ } else if ((ap) && (f.at(i) == QLatin1Char('A'))) {
+ status = QLatin1Char('P');
+ frm += f.at(i);
+ } else if((ap) && (f.at(i) == QLatin1Char('a'))) {
+ status = QLatin1Char('p');
+ frm += f.at(i);
+ } else {
+ buf += f.at(i);
+ status = QLatin1Char('0');
+ }
+ }
+ }
+
+ buf += getFmtString(frm, dt, dd, ap);
+
+ return buf;
+}
+#endif // QT_NO_DATESTRING
+
+#ifdef Q_OS_WIN
+static const int LowerYear = 1980;
+#else
+static const int LowerYear = 1970;
+#endif
+static const int UpperYear = 2037;
+
+static QDate adjustDate(QDate date)
+{
+ QDate lowerLimit(LowerYear, 1, 2);
+ QDate upperLimit(UpperYear, 12, 30);
+
+ if (date > lowerLimit && date < upperLimit)
+ return date;
+
+ int month = date.month();
+ int day = date.day();
+
+ // neither 1970 nor 2037 are leap years, so make sure date isn't Feb 29
+ if (month == 2 && day == 29)
+ --day;
+
+ if (date < lowerLimit)
+ date.setDate(LowerYear, month, day);
+ else
+ date.setDate(UpperYear, month, day);
+
+ return date;
+}
+
+static QDateTimePrivate::Spec utcToLocal(QDate &date, QTime &time)
+{
+ QDate fakeDate = adjustDate(date);
+
+ time_t secsSince1Jan1970UTC = toTime_tHelper(fakeDate, time);
+ tm *brokenDown = 0;
+
+#if defined(Q_OS_WINCE)
+ tm res;
+ FILETIME utcTime = time_tToFt(secsSince1Jan1970UTC);
+ FILETIME resultTime;
+ FileTimeToLocalFileTime(&utcTime , &resultTime);
+ SYSTEMTIME sysTime;
+ FileTimeToSystemTime(&resultTime , &sysTime);
+
+ res.tm_sec = sysTime.wSecond;
+ res.tm_min = sysTime.wMinute;
+ res.tm_hour = sysTime.wHour;
+ res.tm_mday = sysTime.wDay;
+ res.tm_mon = sysTime.wMonth - 1;
+ res.tm_year = sysTime.wYear - 1900;
+ brokenDown = &res;
+#elif !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS)
+ // use the reentrant version of localtime() where available
+ tzset();
+ tm res;
+ brokenDown = localtime_r(&secsSince1Jan1970UTC, &res);
+#elif defined(_MSC_VER) && _MSC_VER >= 1400
+ tm res;
+ if (!_localtime64_s(&res, &secsSince1Jan1970UTC))
+ brokenDown = &res;
+#else
+ brokenDown = localtime(&secsSince1Jan1970UTC);
+#endif
+ if (!brokenDown) {
+ date = QDate(1970, 1, 1);
+ time = QTime();
+ return QDateTimePrivate::LocalUnknown;
+ } else {
+ int deltaDays = fakeDate.daysTo(date);
+ date = QDate(brokenDown->tm_year + 1900, brokenDown->tm_mon + 1, brokenDown->tm_mday);
+ time = QTime(brokenDown->tm_hour, brokenDown->tm_min, brokenDown->tm_sec, time.msec());
+ date = date.addDays(deltaDays);
+ if (brokenDown->tm_isdst > 0)
+ return QDateTimePrivate::LocalDST;
+ else if (brokenDown->tm_isdst < 0)
+ return QDateTimePrivate::LocalUnknown;
+ else
+ return QDateTimePrivate::LocalStandard;
+ }
+}
+
+static void localToUtc(QDate &date, QTime &time, int isdst)
+{
+ if (!date.isValid())
+ return;
+
+ QDate fakeDate = adjustDate(date);
+
+ tm localTM;
+ localTM.tm_sec = time.second();
+ localTM.tm_min = time.minute();
+ localTM.tm_hour = time.hour();
+ localTM.tm_mday = fakeDate.day();
+ localTM.tm_mon = fakeDate.month() - 1;
+ localTM.tm_year = fakeDate.year() - 1900;
+ localTM.tm_isdst = (int)isdst;
+#if defined(Q_OS_WINCE)
+ time_t secsSince1Jan1970UTC = toTime_tHelper(fakeDate, time);
+#else
+#if defined(Q_OS_WIN)
+ _tzset();
+#endif
+ time_t secsSince1Jan1970UTC = mktime(&localTM);
+#endif
+ tm *brokenDown = 0;
+#if defined(Q_OS_WINCE)
+ tm res;
+ FILETIME localTime = time_tToFt(secsSince1Jan1970UTC);
+ SYSTEMTIME sysTime;
+ FileTimeToSystemTime(&localTime, &sysTime);
+ FILETIME resultTime;
+ LocalFileTimeToFileTime(&localTime , &resultTime);
+ FileTimeToSystemTime(&resultTime , &sysTime);
+ res.tm_sec = sysTime.wSecond;
+ res.tm_min = sysTime.wMinute;
+ res.tm_hour = sysTime.wHour;
+ res.tm_mday = sysTime.wDay;
+ res.tm_mon = sysTime.wMonth - 1;
+ res.tm_year = sysTime.wYear - 1900;
+ res.tm_isdst = (int)isdst;
+ brokenDown = &res;
+#elif !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS)
+ // use the reentrant version of gmtime() where available
+ tm res;
+ brokenDown = gmtime_r(&secsSince1Jan1970UTC, &res);
+#elif defined(_MSC_VER) && _MSC_VER >= 1400
+ tm res;
+ if (!_gmtime64_s(&res, &secsSince1Jan1970UTC))
+ brokenDown = &res;
+#else
+ brokenDown = gmtime(&secsSince1Jan1970UTC);
+#endif // !QT_NO_THREAD && _POSIX_THREAD_SAFE_FUNCTIONS
+ if (!brokenDown) {
+ date = QDate(1970, 1, 1);
+ time = QTime();
+ } else {
+ int deltaDays = fakeDate.daysTo(date);
+ date = QDate(brokenDown->tm_year + 1900, brokenDown->tm_mon + 1, brokenDown->tm_mday);
+ time = QTime(brokenDown->tm_hour, brokenDown->tm_min, brokenDown->tm_sec, time.msec());
+ date = date.addDays(deltaDays);
+ }
+}
+
+QDateTimePrivate::Spec QDateTimePrivate::getLocal(QDate &outDate, QTime &outTime) const
+{
+ outDate = date;
+ outTime = time;
+ if (spec == QDateTimePrivate::UTC)
+ return utcToLocal(outDate, outTime);
+ return spec;
+}
+
+void QDateTimePrivate::getUTC(QDate &outDate, QTime &outTime) const
+{
+ outDate = date;
+ outTime = time;
+ const bool isOffset = spec == QDateTimePrivate::OffsetFromUTC;
+
+ if (spec != QDateTimePrivate::UTC && !isOffset)
+ localToUtc(outDate, outTime, (int)spec);
+
+ if (isOffset)
+ addMSecs(outDate, outTime, -(qint64(utcOffset) * 1000));
+}
+
+#if !defined(QT_NO_DEBUG_STREAM) && !defined(QT_NO_DATESTRING)
+QDebug operator<<(QDebug dbg, const QDate &date)
+{
+ dbg.nospace() << "QDate(" << date.toString() << ")";
+ return dbg.space();
+}
+
+QDebug operator<<(QDebug dbg, const QTime &time)
+{
+ dbg.nospace() << "QTime(" << time.toString() << ")";
+ return dbg.space();
+}
+
+QDebug operator<<(QDebug dbg, const QDateTime &date)
+{
+ dbg.nospace() << "QDateTime(" << date.toString() << ")";
+ return dbg.space();
+}
+#endif
+
+#ifndef QT_BOOTSTRAPPED
+
+/*!
+ \internal
+ Gets the digit from a datetime. E.g.
+
+ QDateTime var(QDate(2004, 02, 02));
+ int digit = getDigit(var, Year);
+ // digit = 2004
+*/
+
+int QDateTimeParser::getDigit(const QDateTime &t, int index) const
+{
+ if (index < 0 || index >= sectionNodes.size()) {
+#ifndef QT_NO_DATESTRING
+ qWarning("QDateTimeParser::getDigit() Internal error (%s %d)",
+ qPrintable(t.toString()), index);
+#else
+ qWarning("QDateTimeParser::getDigit() Internal error (%d)", index);
+#endif
+ return -1;
+ }
+ const SectionNode &node = sectionNodes.at(index);
+ switch (node.type) {
+ case Hour24Section: case Hour12Section: return t.time().hour();
+ case MinuteSection: return t.time().minute();
+ case SecondSection: return t.time().second();
+ case MSecSection: return t.time().msec();
+ case YearSection2Digits:
+ case YearSection: return t.date().year();
+ case MonthSection: return t.date().month();
+ case DaySection: return t.date().day();
+ case DayOfWeekSection: return t.date().day();
+ case AmPmSection: return t.time().hour() > 11 ? 1 : 0;
+
+ default: break;
+ }
+
+#ifndef QT_NO_DATESTRING
+ qWarning("QDateTimeParser::getDigit() Internal error 2 (%s %d)",
+ qPrintable(t.toString()), index);
+#else
+ qWarning("QDateTimeParser::getDigit() Internal error 2 (%d)", index);
+#endif
+ return -1;
+}
+
+/*!
+ \internal
+ Sets a digit in a datetime. E.g.
+
+ QDateTime var(QDate(2004, 02, 02));
+ int digit = getDigit(var, Year);
+ // digit = 2004
+ setDigit(&var, Year, 2005);
+ digit = getDigit(var, Year);
+ // digit = 2005
+*/
+
+bool QDateTimeParser::setDigit(QDateTime &v, int index, int newVal) const
+{
+ if (index < 0 || index >= sectionNodes.size()) {
+#ifndef QT_NO_DATESTRING
+ qWarning("QDateTimeParser::setDigit() Internal error (%s %d %d)",
+ qPrintable(v.toString()), index, newVal);
+#else
+ qWarning("QDateTimeParser::setDigit() Internal error (%d %d)", index, newVal);
+#endif
+ return false;
+ }
+ const SectionNode &node = sectionNodes.at(index);
+
+ int year, month, day, hour, minute, second, msec;
+ year = v.date().year();
+ month = v.date().month();
+ day = v.date().day();
+ hour = v.time().hour();
+ minute = v.time().minute();
+ second = v.time().second();
+ msec = v.time().msec();
+
+ switch (node.type) {
+ case Hour24Section: case Hour12Section: hour = newVal; break;
+ case MinuteSection: minute = newVal; break;
+ case SecondSection: second = newVal; break;
+ case MSecSection: msec = newVal; break;
+ case YearSection2Digits:
+ case YearSection: year = newVal; break;
+ case MonthSection: month = newVal; break;
+ case DaySection:
+ case DayOfWeekSection:
+ if (newVal > 31) {
+ // have to keep legacy behavior. setting the
+ // date to 32 should return false. Setting it
+ // to 31 for february should return true
+ return false;
+ }
+ day = newVal;
+ break;
+ case AmPmSection: hour = (newVal == 0 ? hour % 12 : (hour % 12) + 12); break;
+ default:
+ qWarning("QDateTimeParser::setDigit() Internal error (%s)",
+ qPrintable(sectionName(node.type)));
+ break;
+ }
+
+ if (!(node.type & (DaySection|DayOfWeekSection))) {
+ if (day < cachedDay)
+ day = cachedDay;
+ const int max = QDate(year, month, 1).daysInMonth();
+ if (day > max) {
+ day = max;
+ }
+ }
+ if (QDate::isValid(year, month, day) && QTime::isValid(hour, minute, second, msec)) {
+ v = QDateTime(QDate(year, month, day), QTime(hour, minute, second, msec), spec);
+ return true;
+ }
+ return false;
+}
+
+
+
+/*!
+ \
+
+ Returns the absolute maximum for a section
+*/
+
+int QDateTimeParser::absoluteMax(int s, const QDateTime &cur) const
+{
+ const SectionNode &sn = sectionNode(s);
+ switch (sn.type) {
+ case Hour24Section:
+ case Hour12Section: return 23; // this is special-cased in
+ // parseSection. We want it to be
+ // 23 for the stepBy case.
+ case MinuteSection:
+ case SecondSection: return 59;
+ case MSecSection: return 999;
+ case YearSection2Digits:
+ case YearSection: return 9999; // sectionMaxSize will prevent
+ // people from typing in a larger
+ // number in count == 2 sections.
+ // stepBy() will work on real years anyway
+ case MonthSection: return 12;
+ case DaySection:
+ case DayOfWeekSection: return cur.isValid() ? cur.date().daysInMonth() : 31;
+ case AmPmSection: return 1;
+ default: break;
+ }
+ qWarning("QDateTimeParser::absoluteMax() Internal error (%s)",
+ qPrintable(sectionName(sn.type)));
+ return -1;
+}
+
+/*!
+ \internal
+
+ Returns the absolute minimum for a section
+*/
+
+int QDateTimeParser::absoluteMin(int s) const
+{
+ const SectionNode &sn = sectionNode(s);
+ switch (sn.type) {
+ case Hour24Section:
+ case Hour12Section:
+ case MinuteSection:
+ case SecondSection:
+ case MSecSection:
+ case YearSection2Digits:
+ case YearSection: return 0;
+ case MonthSection:
+ case DaySection:
+ case DayOfWeekSection: return 1;
+ case AmPmSection: return 0;
+ default: break;
+ }
+ qWarning("QDateTimeParser::absoluteMin() Internal error (%s, %0x)",
+ qPrintable(sectionName(sn.type)), sn.type);
+ return -1;
+}
+
+/*!
+ \internal
+
+ Returns the sectionNode for the Section \a s.
+*/
+
+const QDateTimeParser::SectionNode &QDateTimeParser::sectionNode(int sectionIndex) const
+{
+ if (sectionIndex < 0) {
+ switch (sectionIndex) {
+ case FirstSectionIndex:
+ return first;
+ case LastSectionIndex:
+ return last;
+ case NoSectionIndex:
+ return none;
+ }
+ } else if (sectionIndex < sectionNodes.size()) {
+ return sectionNodes.at(sectionIndex);
+ }
+
+ qWarning("QDateTimeParser::sectionNode() Internal error (%d)",
+ sectionIndex);
+ return none;
+}
+
+QDateTimeParser::Section QDateTimeParser::sectionType(int sectionIndex) const
+{
+ return sectionNode(sectionIndex).type;
+}
+
+
+/*!
+ \internal
+
+ Returns the starting position for section \a s.
+*/
+
+int QDateTimeParser::sectionPos(int sectionIndex) const
+{
+ return sectionPos(sectionNode(sectionIndex));
+}
+
+int QDateTimeParser::sectionPos(const SectionNode &sn) const
+{
+ switch (sn.type) {
+ case FirstSection: return 0;
+ case LastSection: return displayText().size() - 1;
+ default: break;
+ }
+ if (sn.pos == -1) {
+ qWarning("QDateTimeParser::sectionPos Internal error (%s)", qPrintable(sectionName(sn.type)));
+ return -1;
+ }
+ return sn.pos;
+}
+
+
+/*!
+ \internal helper function for parseFormat. removes quotes that are
+ not escaped and removes the escaping on those that are escaped
+
+*/
+
+static QString unquote(const QString &str)
+{
+ const QChar quote(QLatin1Char('\''));
+ const QChar slash(QLatin1Char('\\'));
+ const QChar zero(QLatin1Char('0'));
+ QString ret;
+ QChar status(zero);
+ const int max = str.size();
+ for (int i=0; i<max; ++i) {
+ if (str.at(i) == quote) {
+ if (status != quote) {
+ status = quote;
+ } else if (!ret.isEmpty() && str.at(i - 1) == slash) {
+ ret[ret.size() - 1] = quote;
+ } else {
+ status = zero;
+ }
+ } else {
+ ret += str.at(i);
+ }
+ }
+ return ret;
+}
+/*!
+ \internal
+
+ Parses the format \a newFormat. If successful, returns true and
+ sets up the format. Else keeps the old format and returns false.
+
+*/
+
+static inline int countRepeat(const QString &str, int index, int maxCount)
+{
+ int count = 1;
+ const QChar ch(str.at(index));
+ const int max = qMin(index + maxCount, str.size());
+ while (index + count < max && str.at(index + count) == ch) {
+ ++count;
+ }
+ return count;
+}
+
+static inline void appendSeparator(QStringList *list, const QString &string, int from, int size, int lastQuote)
+{
+ QString str(string.mid(from, size));
+ if (lastQuote >= from)
+ str = unquote(str);
+ list->append(str);
+}
+
+
+bool QDateTimeParser::parseFormat(const QString &newFormat)
+{
+ const QLatin1Char quote('\'');
+ const QLatin1Char slash('\\');
+ const QLatin1Char zero('0');
+ if (newFormat == displayFormat && !newFormat.isEmpty()) {
+ return true;
+ }
+
+ QDTPDEBUGN("parseFormat: %s", newFormat.toLatin1().constData());
+
+ QVector<SectionNode> newSectionNodes;
+ Sections newDisplay = 0;
+ QStringList newSeparators;
+ int i, index = 0;
+ int add = 0;
+ QChar status(zero);
+ const int max = newFormat.size();
+ int lastQuote = -1;
+ for (i = 0; i<max; ++i) {
+ if (newFormat.at(i) == quote) {
+ lastQuote = i;
+ ++add;
+ if (status != quote) {
+ status = quote;
+ } else if (newFormat.at(i - 1) != slash) {
+ status = zero;
+ }
+ } else if (status != quote) {
+ const char sect = newFormat.at(i).toLatin1();
+ switch (sect) {
+ case 'H':
+ case 'h':
+ if (parserType != QVariant::Date) {
+ const Section hour = (sect == 'h') ? Hour12Section : Hour24Section;
+ const SectionNode sn = { hour, i - add, countRepeat(newFormat, i, 2) };
+ newSectionNodes.append(sn);
+ appendSeparator(&newSeparators, newFormat, index, i - index, lastQuote);
+ i += sn.count - 1;
+ index = i + 1;
+ newDisplay |= hour;
+ }
+ break;
+ case 'm':
+ if (parserType != QVariant::Date) {
+ const SectionNode sn = { MinuteSection, i - add, countRepeat(newFormat, i, 2) };
+ newSectionNodes.append(sn);
+ appendSeparator(&newSeparators, newFormat, index, i - index, lastQuote);
+ i += sn.count - 1;
+ index = i + 1;
+ newDisplay |= MinuteSection;
+ }
+ break;
+ case 's':
+ if (parserType != QVariant::Date) {
+ const SectionNode sn = { SecondSection, i - add, countRepeat(newFormat, i, 2) };
+ newSectionNodes.append(sn);
+ appendSeparator(&newSeparators, newFormat, index, i - index, lastQuote);
+ i += sn.count - 1;
+ index = i + 1;
+ newDisplay |= SecondSection;
+ }
+ break;
+
+ case 'z':
+ if (parserType != QVariant::Date) {
+ const SectionNode sn = { MSecSection, i - add, countRepeat(newFormat, i, 3) < 3 ? 1 : 3 };
+ newSectionNodes.append(sn);
+ appendSeparator(&newSeparators, newFormat, index, i - index, lastQuote);
+ i += sn.count - 1;
+ index = i + 1;
+ newDisplay |= MSecSection;
+ }
+ break;
+ case 'A':
+ case 'a':
+ if (parserType != QVariant::Date) {
+ const bool cap = (sect == 'A');
+ const SectionNode sn = { AmPmSection, i - add, (cap ? 1 : 0) };
+ newSectionNodes.append(sn);
+ appendSeparator(&newSeparators, newFormat, index, i - index, lastQuote);
+ newDisplay |= AmPmSection;
+ if (i + 1 < newFormat.size()
+ && newFormat.at(i+1) == (cap ? QLatin1Char('P') : QLatin1Char('p'))) {
+ ++i;
+ }
+ index = i + 1;
+ }
+ break;
+ case 'y':
+ if (parserType != QVariant::Time) {
+ const int repeat = countRepeat(newFormat, i, 4);
+ if (repeat >= 2) {
+ const SectionNode sn = { repeat == 4 ? YearSection : YearSection2Digits,
+ i - add, repeat == 4 ? 4 : 2 };
+ newSectionNodes.append(sn);
+ appendSeparator(&newSeparators, newFormat, index, i - index, lastQuote);
+ i += sn.count - 1;
+ index = i + 1;
+ newDisplay |= sn.type;
+ }
+ }
+ break;
+ case 'M':
+ if (parserType != QVariant::Time) {
+ const SectionNode sn = { MonthSection, i - add, countRepeat(newFormat, i, 4) };
+ newSectionNodes.append(sn);
+ newSeparators.append(unquote(newFormat.mid(index, i - index)));
+ i += sn.count - 1;
+ index = i + 1;
+ newDisplay |= MonthSection;
+ }
+ break;
+ case 'd':
+ if (parserType != QVariant::Time) {
+ const int repeat = countRepeat(newFormat, i, 4);
+ const SectionNode sn = { repeat >= 3 ? DayOfWeekSection : DaySection, i - add, repeat };
+ newSectionNodes.append(sn);
+ appendSeparator(&newSeparators, newFormat, index, i - index, lastQuote);
+ i += sn.count - 1;
+ index = i + 1;
+ newDisplay |= sn.type;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+ if (newSectionNodes.isEmpty() && context == DateTimeEdit) {
+ return false;
+ }
+
+ if ((newDisplay & (AmPmSection|Hour12Section)) == Hour12Section) {
+ const int max = newSectionNodes.size();
+ for (int i=0; i<max; ++i) {
+ SectionNode &node = newSectionNodes[i];
+ if (node.type == Hour12Section)
+ node.type = Hour24Section;
+ }
+ }
+
+ if (index < newFormat.size()) {
+ appendSeparator(&newSeparators, newFormat, index, index - max, lastQuote);
+ } else {
+ newSeparators.append(QString());
+ }
+
+ displayFormat = newFormat;
+ separators = newSeparators;
+ sectionNodes = newSectionNodes;
+ display = newDisplay;
+ last.pos = -1;
+
+// for (int i=0; i<sectionNodes.size(); ++i) {
+// QDTPDEBUG << sectionName(sectionNodes.at(i).type) << sectionNodes.at(i).count;
+// }
+
+ QDTPDEBUG << newFormat << displayFormat;
+ QDTPDEBUGN("separators:\n'%s'", separators.join(QLatin1String("\n")).toLatin1().constData());
+
+ return true;
+}
+
+/*!
+ \internal
+
+ Returns the size of section \a s.
+*/
+
+int QDateTimeParser::sectionSize(int sectionIndex) const
+{
+ if (sectionIndex < 0)
+ return 0;
+
+ if (sectionIndex >= sectionNodes.size()) {
+ qWarning("QDateTimeParser::sectionSize Internal error (%d)", sectionIndex);
+ return -1;
+ }
+ if (sectionIndex == sectionNodes.size() - 1) {
+ return displayText().size() - sectionPos(sectionIndex) - separators.last().size();
+ } else {
+ return sectionPos(sectionIndex + 1) - sectionPos(sectionIndex)
+ - separators.at(sectionIndex + 1).size();
+ }
+}
+
+
+int QDateTimeParser::sectionMaxSize(Section s, int count) const
+{
+#ifndef QT_NO_TEXTDATE
+ int mcount = 12;
+#endif
+
+ switch (s) {
+ case FirstSection:
+ case NoSection:
+ case LastSection: return 0;
+
+ case AmPmSection: {
+ const int lowerMax = qMin(getAmPmText(AmText, LowerCase).size(),
+ getAmPmText(PmText, LowerCase).size());
+ const int upperMax = qMin(getAmPmText(AmText, UpperCase).size(),
+ getAmPmText(PmText, UpperCase).size());
+ return qMin(4, qMin(lowerMax, upperMax));
+ }
+
+ case Hour24Section:
+ case Hour12Section:
+ case MinuteSection:
+ case SecondSection:
+ case DaySection: return 2;
+ case DayOfWeekSection:
+#ifdef QT_NO_TEXTDATE
+ return 2;
+#else
+ mcount = 7;
+ // fall through
+#endif
+ case MonthSection:
+ if (count <= 2)
+ return 2;
+
+#ifdef QT_NO_TEXTDATE
+ return 2;
+#else
+ {
+ int ret = 0;
+ const QLocale l = locale();
+ for (int i=1; i<=mcount; ++i) {
+ const QString str = (s == MonthSection
+ ? l.monthName(i, count == 4 ? QLocale::LongFormat : QLocale::ShortFormat)
+ : l.dayName(i, count == 4 ? QLocale::LongFormat : QLocale::ShortFormat));
+ ret = qMax(str.size(), ret);
+ }
+ return ret;
+ }
+#endif
+ case MSecSection: return 3;
+ case YearSection: return 4;
+ case YearSection2Digits: return 2;
+
+ case CalendarPopupSection:
+ case Internal:
+ case TimeSectionMask:
+ case DateSectionMask:
+ qWarning("QDateTimeParser::sectionMaxSize: Invalid section %s",
+ sectionName(s).toLatin1().constData());
+ }
+ return -1;
+}
+
+
+int QDateTimeParser::sectionMaxSize(int index) const
+{
+ const SectionNode &sn = sectionNode(index);
+ return sectionMaxSize(sn.type, sn.count);
+}
+
+/*!
+ \internal
+
+ Returns the text of section \a s. This function operates on the
+ arg text rather than edit->text().
+*/
+
+
+QString QDateTimeParser::sectionText(const QString &text, int sectionIndex, int index) const
+{
+ const SectionNode &sn = sectionNode(sectionIndex);
+ switch (sn.type) {
+ case NoSectionIndex:
+ case FirstSectionIndex:
+ case LastSectionIndex:
+ return QString();
+ default: break;
+ }
+
+ return text.mid(index, sectionSize(sectionIndex));
+}
+
+QString QDateTimeParser::sectionText(int sectionIndex) const
+{
+ const SectionNode &sn = sectionNode(sectionIndex);
+ switch (sn.type) {
+ case NoSectionIndex:
+ case FirstSectionIndex:
+ case LastSectionIndex:
+ return QString();
+ default: break;
+ }
+
+ return displayText().mid(sn.pos, sectionSize(sectionIndex));
+}
+
+
+#ifndef QT_NO_TEXTDATE
+/*!
+ \internal:skipToNextSection
+
+ Parses the part of \a text that corresponds to \a s and returns
+ the value of that field. Sets *stateptr to the right state if
+ stateptr != 0.
+*/
+
+int QDateTimeParser::parseSection(const QDateTime &currentValue, int sectionIndex,
+ QString &text, int &cursorPosition, int index,
+ State &state, int *usedptr) const
+{
+ state = Invalid;
+ int num = 0;
+ const SectionNode &sn = sectionNode(sectionIndex);
+ if ((sn.type & Internal) == Internal) {
+ qWarning("QDateTimeParser::parseSection Internal error (%s %d)",
+ qPrintable(sectionName(sn.type)), sectionIndex);
+ return -1;
+ }
+
+ const int sectionmaxsize = sectionMaxSize(sectionIndex);
+ QString sectiontext = text.mid(index, sectionmaxsize);
+ int sectiontextSize = sectiontext.size();
+
+ QDTPDEBUG << "sectionValue for" << sectionName(sn.type)
+ << "with text" << text << "and st" << sectiontext
+ << text.mid(index, sectionmaxsize)
+ << index;
+
+ int used = 0;
+ switch (sn.type) {
+ case AmPmSection: {
+ const int ampm = findAmPm(sectiontext, sectionIndex, &used);
+ switch (ampm) {
+ case AM: // sectiontext == AM
+ case PM: // sectiontext == PM
+ num = ampm;
+ state = Acceptable;
+ break;
+ case PossibleAM: // sectiontext => AM
+ case PossiblePM: // sectiontext => PM
+ num = ampm - 2;
+ state = Intermediate;
+ break;
+ case PossibleBoth: // sectiontext => AM|PM
+ num = 0;
+ state = Intermediate;
+ break;
+ case Neither:
+ state = Invalid;
+ QDTPDEBUG << "invalid because findAmPm(" << sectiontext << ") returned -1";
+ break;
+ default:
+ QDTPDEBUGN("This should never happen (findAmPm returned %d)", ampm);
+ break;
+ }
+ if (state != Invalid) {
+ QString str = text;
+ text.replace(index, used, sectiontext.left(used));
+ }
+ break; }
+ case MonthSection:
+ case DayOfWeekSection:
+ if (sn.count >= 3) {
+ if (sn.type == MonthSection) {
+ int min = 1;
+ const QDate minDate = getMinimum().date();
+ if (currentValue.date().year() == minDate.year()) {
+ min = minDate.month();
+ }
+ num = findMonth(sectiontext.toLower(), min, sectionIndex, &sectiontext, &used);
+ } else {
+ num = findDay(sectiontext.toLower(), 1, sectionIndex, &sectiontext, &used);
+ }
+
+ if (num != -1) {
+ state = (used == sectiontext.size() ? Acceptable : Intermediate);
+ QString str = text;
+ text.replace(index, used, sectiontext.left(used));
+ } else {
+ state = Intermediate;
+ }
+ break; }
+ // fall through
+ case DaySection:
+ case YearSection:
+ case YearSection2Digits:
+ case Hour12Section:
+ case Hour24Section:
+ case MinuteSection:
+ case SecondSection:
+ case MSecSection: {
+ if (sectiontextSize == 0) {
+ num = 0;
+ used = 0;
+ state = Intermediate;
+ } else {
+ const int absMax = absoluteMax(sectionIndex);
+ QLocale loc;
+ bool ok = true;
+ int last = -1;
+ used = -1;
+
+ QString digitsStr(sectiontext);
+ for (int i = 0; i < sectiontextSize; ++i) {
+ if (digitsStr.at(i).isSpace()) {
+ sectiontextSize = i;
+ break;
+ }
+ }
+
+ const int max = qMin(sectionmaxsize, sectiontextSize);
+ for (int digits = max; digits >= 1; --digits) {
+ digitsStr.truncate(digits);
+ int tmp = (int)loc.toUInt(digitsStr, &ok, 10);
+ if (ok && sn.type == Hour12Section) {
+ if (tmp > 12) {
+ tmp = -1;
+ ok = false;
+ } else if (tmp == 12) {
+ tmp = 0;
+ }
+ }
+ if (ok && tmp <= absMax) {
+ QDTPDEBUG << sectiontext.left(digits) << tmp << digits;
+ last = tmp;
+ used = digits;
+ break;
+ }
+ }
+
+ if (last == -1) {
+ QChar first(sectiontext.at(0));
+ if (separators.at(sectionIndex + 1).startsWith(first)) {
+ used = 0;
+ state = Intermediate;
+ } else {
+ state = Invalid;
+ QDTPDEBUG << "invalid because" << sectiontext << "can't become a uint" << last << ok;
+ }
+ } else {
+ num += last;
+ const FieldInfo fi = fieldInfo(sectionIndex);
+ const bool done = (used == sectionmaxsize);
+ if (!done && fi & Fraction) { // typing 2 in a zzz field should be .200, not .002
+ for (int i=used; i<sectionmaxsize; ++i) {
+ num *= 10;
+ }
+ }
+ const int absMin = absoluteMin(sectionIndex);
+ if (num < absMin) {
+ state = done ? Invalid : Intermediate;
+ if (done)
+ QDTPDEBUG << "invalid because" << num << "is less than absoluteMin" << absMin;
+ } else if (num > absMax) {
+ state = Intermediate;
+ } else if (!done && (fi & (FixedWidth|Numeric)) == (FixedWidth|Numeric)) {
+ if (skipToNextSection(sectionIndex, currentValue, digitsStr)) {
+ state = Acceptable;
+ const int missingZeroes = sectionmaxsize - digitsStr.size();
+ text.insert(index, QString().fill(QLatin1Char('0'), missingZeroes));
+ used = sectionmaxsize;
+ cursorPosition += missingZeroes;
+ } else {
+ state = Intermediate;;
+ }
+ } else {
+ state = Acceptable;
+ }
+ }
+ }
+ break; }
+ default:
+ qWarning("QDateTimeParser::parseSection Internal error (%s %d)",
+ qPrintable(sectionName(sn.type)), sectionIndex);
+ return -1;
+ }
+
+ if (usedptr)
+ *usedptr = used;
+
+ return (state != Invalid ? num : -1);
+}
+#endif // QT_NO_TEXTDATE
+
+#ifndef QT_NO_DATESTRING
+/*!
+ \internal
+*/
+
+QDateTimeParser::StateNode QDateTimeParser::parse(QString &input, int &cursorPosition,
+ const QDateTime &currentValue, bool fixup) const
+{
+ const QDateTime minimum = getMinimum();
+ const QDateTime maximum = getMaximum();
+
+ State state = Acceptable;
+
+ QDateTime newCurrentValue;
+ int pos = 0;
+ bool conflicts = false;
+ const int sectionNodesCount = sectionNodes.size();
+
+ QDTPDEBUG << "parse" << input;
+ {
+ int year, month, day, hour12, hour, minute, second, msec, ampm, dayofweek, year2digits;
+ getDateFromJulianDay(currentValue.date().toJulianDay(), &year, &month, &day);
+ year2digits = year % 100;
+ hour = currentValue.time().hour();
+ hour12 = -1;
+ minute = currentValue.time().minute();
+ second = currentValue.time().second();
+ msec = currentValue.time().msec();
+ dayofweek = currentValue.date().dayOfWeek();
+
+ ampm = -1;
+ Sections isSet = NoSection;
+ int num;
+ State tmpstate;
+
+ for (int index=0; state != Invalid && index<sectionNodesCount; ++index) {
+ if (QStringRef(&input, pos, separators.at(index).size()) != separators.at(index)) {
+ QDTPDEBUG << "invalid because" << input.mid(pos, separators.at(index).size())
+ << "!=" << separators.at(index)
+ << index << pos << currentSectionIndex;
+ state = Invalid;
+ goto end;
+ }
+ pos += separators.at(index).size();
+ sectionNodes[index].pos = pos;
+ int *current = 0;
+ const SectionNode sn = sectionNodes.at(index);
+ int used;
+
+ num = parseSection(currentValue, index, input, cursorPosition, pos, tmpstate, &used);
+ QDTPDEBUG << "sectionValue" << sectionName(sectionType(index)) << input
+ << "pos" << pos << "used" << used << stateName(tmpstate);
+ if (fixup && tmpstate == Intermediate && used < sn.count) {
+ const FieldInfo fi = fieldInfo(index);
+ if ((fi & (Numeric|FixedWidth)) == (Numeric|FixedWidth)) {
+ const QString newText = QString(QLatin1String("%1")).arg(num, sn.count, 10, QLatin1Char('0'));
+ input.replace(pos, used, newText);
+ used = sn.count;
+ }
+ }
+ pos += qMax(0, used);
+
+ state = qMin<State>(state, tmpstate);
+ if (state == Intermediate && context == FromString) {
+ state = Invalid;
+ break;
+ }
+
+ QDTPDEBUG << index << sectionName(sectionType(index)) << "is set to"
+ << pos << "state is" << stateName(state);
+
+
+ if (state != Invalid) {
+ switch (sn.type) {
+ case Hour24Section: current = &hour; break;
+ case Hour12Section: current = &hour12; break;
+ case MinuteSection: current = &minute; break;
+ case SecondSection: current = &second; break;
+ case MSecSection: current = &msec; break;
+ case YearSection: current = &year; break;
+ case YearSection2Digits: current = &year2digits; break;
+ case MonthSection: current = &month; break;
+ case DayOfWeekSection: current = &dayofweek; break;
+ case DaySection: current = &day; num = qMax<int>(1, num); break;
+ case AmPmSection: current = &ampm; break;
+ default:
+ qWarning("QDateTimeParser::parse Internal error (%s)",
+ qPrintable(sectionName(sn.type)));
+ break;
+ }
+ if (!current) {
+ qWarning("QDateTimeParser::parse Internal error 2");
+ return StateNode();
+ }
+ if (isSet & sn.type && *current != num) {
+ QDTPDEBUG << "CONFLICT " << sectionName(sn.type) << *current << num;
+ conflicts = true;
+ if (index != currentSectionIndex || num == -1) {
+ continue;
+ }
+ }
+ if (num != -1)
+ *current = num;
+ isSet |= sn.type;
+ }
+ }
+
+ if (state != Invalid && QStringRef(&input, pos, input.size() - pos) != separators.last()) {
+ QDTPDEBUG << "invalid because" << input.mid(pos)
+ << "!=" << separators.last() << pos;
+ state = Invalid;
+ }
+
+ if (state != Invalid) {
+ if (parserType != QVariant::Time) {
+ if (year % 100 != year2digits) {
+ switch (isSet & (YearSection2Digits|YearSection)) {
+ case YearSection2Digits:
+ year = (year / 100) * 100;
+ year += year2digits;
+ break;
+ case ((uint)YearSection2Digits|(uint)YearSection): {
+ conflicts = true;
+ const SectionNode &sn = sectionNode(currentSectionIndex);
+ if (sn.type == YearSection2Digits) {
+ year = (year / 100) * 100;
+ year += year2digits;
+ }
+ break; }
+ default:
+ break;
+ }
+ }
+
+ const QDate date(year, month, day);
+ const int diff = dayofweek - date.dayOfWeek();
+ if (diff != 0 && state == Acceptable && isSet & DayOfWeekSection) {
+ conflicts = isSet & DaySection;
+ const SectionNode &sn = sectionNode(currentSectionIndex);
+ if (sn.type == DayOfWeekSection || currentSectionIndex == -1) {
+ // dayofweek should be preferred
+ day += diff;
+ if (day <= 0) {
+ day += 7;
+ } else if (day > date.daysInMonth()) {
+ day -= 7;
+ }
+ QDTPDEBUG << year << month << day << dayofweek
+ << diff << QDate(year, month, day).dayOfWeek();
+ }
+ }
+ bool needfixday = false;
+ if (sectionType(currentSectionIndex) & (DaySection|DayOfWeekSection)) {
+ cachedDay = day;
+ } else if (cachedDay > day) {
+ day = cachedDay;
+ needfixday = true;
+ }
+
+ if (!QDate::isValid(year, month, day)) {
+ if (day < 32) {
+ cachedDay = day;
+ }
+ if (day > 28 && QDate::isValid(year, month, 1)) {
+ needfixday = true;
+ }
+ }
+ if (needfixday) {
+ if (context == FromString) {
+ state = Invalid;
+ goto end;
+ }
+ if (state == Acceptable && fixday) {
+ day = qMin<int>(day, QDate(year, month, 1).daysInMonth());
+
+ const QLocale loc = locale();
+ for (int i=0; i<sectionNodesCount; ++i) {
+ if (sectionType(i) & (DaySection|DayOfWeekSection)) {
+ input.replace(sectionPos(i), sectionSize(i), loc.toString(day));
+ }
+ }
+ } else {
+ state = qMin(Intermediate, state);
+ }
+ }
+ }
+
+ if (parserType != QVariant::Date) {
+ if (isSet & Hour12Section) {
+ const bool hasHour = isSet & Hour24Section;
+ if (ampm == -1) {
+ if (hasHour) {
+ ampm = (hour < 12 ? 0 : 1);
+ } else {
+ ampm = 0; // no way to tell if this is am or pm so I assume am
+ }
+ }
+ hour12 = (ampm == 0 ? hour12 % 12 : (hour12 % 12) + 12);
+ if (!hasHour) {
+ hour = hour12;
+ } else if (hour != hour12) {
+ conflicts = true;
+ }
+ } else if (ampm != -1) {
+ if (!(isSet & (Hour24Section))) {
+ hour = (12 * ampm); // special case. Only ap section
+ } else if ((ampm == 0) != (hour < 12)) {
+ conflicts = true;
+ }
+ }
+
+ }
+
+ newCurrentValue = QDateTime(QDate(year, month, day), QTime(hour, minute, second, msec), spec);
+ QDTPDEBUG << year << month << day << hour << minute << second << msec;
+ }
+ QDTPDEBUGN("'%s' => '%s'(%s)", input.toLatin1().constData(),
+ newCurrentValue.toString(QLatin1String("yyyy/MM/dd hh:mm:ss.zzz")).toLatin1().constData(),
+ stateName(state).toLatin1().constData());
+ }
+end:
+ if (newCurrentValue.isValid()) {
+ if (context != FromString && state != Invalid && newCurrentValue < minimum) {
+ const QLatin1Char space(' ');
+ if (newCurrentValue >= minimum)
+ qWarning("QDateTimeParser::parse Internal error 3 (%s %s)",
+ qPrintable(newCurrentValue.toString()), qPrintable(minimum.toString()));
+
+ bool done = false;
+ state = Invalid;
+ for (int i=0; i<sectionNodesCount && !done; ++i) {
+ const SectionNode &sn = sectionNodes.at(i);
+ QString t = sectionText(input, i, sn.pos).toLower();
+ if ((t.size() < sectionMaxSize(i) && (((int)fieldInfo(i) & (FixedWidth|Numeric)) != Numeric))
+ || t.contains(space)) {
+ switch (sn.type) {
+ case AmPmSection:
+ switch (findAmPm(t, i)) {
+ case AM:
+ case PM:
+ state = Acceptable;
+ done = true;
+ break;
+ case Neither:
+ state = Invalid;
+ done = true;
+ break;
+ case PossibleAM:
+ case PossiblePM:
+ case PossibleBoth: {
+ const QDateTime copy(newCurrentValue.addSecs(12 * 60 * 60));
+ if (copy >= minimum && copy <= maximum) {
+ state = Intermediate;
+ done = true;
+ }
+ break; }
+ }
+ case MonthSection:
+ if (sn.count >= 3) {
+ int tmp = newCurrentValue.date().month();
+ // I know the first possible month makes the date too early
+ while ((tmp = findMonth(t, tmp + 1, i)) != -1) {
+ const QDateTime copy(newCurrentValue.addMonths(tmp - newCurrentValue.date().month()));
+ if (copy >= minimum && copy <= maximum)
+ break; // break out of while
+ }
+ if (tmp == -1) {
+ break;
+ }
+ state = Intermediate;
+ done = true;
+ break;
+ }
+ // fallthrough
+ default: {
+ int toMin;
+ int toMax;
+
+ if (sn.type & TimeSectionMask) {
+ if (newCurrentValue.daysTo(minimum) != 0) {
+ break;
+ }
+ toMin = newCurrentValue.time().msecsTo(minimum.time());
+ if (newCurrentValue.daysTo(maximum) > 0) {
+ toMax = -1; // can't get to max
+ } else {
+ toMax = newCurrentValue.time().msecsTo(maximum.time());
+ }
+ } else {
+ toMin = newCurrentValue.daysTo(minimum);
+ toMax = newCurrentValue.daysTo(maximum);
+ }
+ const int maxChange = QDateTimeParser::maxChange(i);
+ if (toMin > maxChange) {
+ QDTPDEBUG << "invalid because toMin > maxChange" << toMin
+ << maxChange << t << newCurrentValue << minimum;
+ state = Invalid;
+ done = true;
+ break;
+ } else if (toMax > maxChange) {
+ toMax = -1; // can't get to max
+ }
+
+ const int min = getDigit(minimum, i);
+ if (min == -1) {
+ qWarning("QDateTimeParser::parse Internal error 4 (%s)",
+ qPrintable(sectionName(sn.type)));
+ state = Invalid;
+ done = true;
+ break;
+ }
+
+ int max = toMax != -1 ? getDigit(maximum, i) : absoluteMax(i, newCurrentValue);
+ int pos = cursorPosition - sn.pos;
+ if (pos < 0 || pos >= t.size())
+ pos = -1;
+ if (!potentialValue(t.simplified(), min, max, i, newCurrentValue, pos)) {
+ QDTPDEBUG << "invalid because potentialValue(" << t.simplified() << min << max
+ << sectionName(sn.type) << "returned" << toMax << toMin << pos;
+ state = Invalid;
+ done = true;
+ break;
+ }
+ state = Intermediate;
+ done = true;
+ break; }
+ }
+ }
+ }
+ } else {
+ if (context == FromString) {
+ // optimization
+ Q_ASSERT(getMaximum().date().toJulianDay() == 4642999);
+ if (newCurrentValue.date().toJulianDay() > 4642999)
+ state = Invalid;
+ } else {
+ if (newCurrentValue > getMaximum())
+ state = Invalid;
+ }
+
+ QDTPDEBUG << "not checking intermediate because newCurrentValue is" << newCurrentValue << getMinimum() << getMaximum();
+ }
+ }
+ StateNode node;
+ node.input = input;
+ node.state = state;
+ node.conflicts = conflicts;
+ node.value = newCurrentValue.toTimeSpec(spec);
+ text = input;
+ return node;
+}
+#endif // QT_NO_DATESTRING
+
+#ifndef QT_NO_TEXTDATE
+/*!
+ \internal finds the first possible monthname that \a str1 can
+ match. Starting from \a index; str should already by lowered
+*/
+
+int QDateTimeParser::findMonth(const QString &str1, int startMonth, int sectionIndex,
+ QString *usedMonth, int *used) const
+{
+ int bestMatch = -1;
+ int bestCount = 0;
+ if (!str1.isEmpty()) {
+ const SectionNode &sn = sectionNode(sectionIndex);
+ if (sn.type != MonthSection) {
+ qWarning("QDateTimeParser::findMonth Internal error");
+ return -1;
+ }
+
+ QLocale::FormatType type = sn.count == 3 ? QLocale::ShortFormat : QLocale::LongFormat;
+ QLocale l = locale();
+
+ for (int month=startMonth; month<=12; ++month) {
+ QString str2 = l.monthName(month, type).toLower();
+
+ if (str1.startsWith(str2)) {
+ if (used) {
+ QDTPDEBUG << "used is set to" << str2.size();
+ *used = str2.size();
+ }
+ if (usedMonth)
+ *usedMonth = l.monthName(month, type);
+
+ return month;
+ }
+ if (context == FromString)
+ continue;
+
+ const int limit = qMin(str1.size(), str2.size());
+
+ QDTPDEBUG << "limit is" << limit << str1 << str2;
+ bool equal = true;
+ for (int i=0; i<limit; ++i) {
+ if (str1.at(i) != str2.at(i)) {
+ equal = false;
+ if (i > bestCount) {
+ bestCount = i;
+ bestMatch = month;
+ }
+ break;
+ }
+ }
+ if (equal) {
+ if (used)
+ *used = limit;
+ if (usedMonth)
+ *usedMonth = l.monthName(month, type);
+ return month;
+ }
+ }
+ if (usedMonth && bestMatch != -1)
+ *usedMonth = l.monthName(bestMatch, type);
+ }
+ if (used) {
+ QDTPDEBUG << "used is set to" << bestCount;
+ *used = bestCount;
+ }
+ return bestMatch;
+}
+
+int QDateTimeParser::findDay(const QString &str1, int startDay, int sectionIndex, QString *usedDay, int *used) const
+{
+ int bestMatch = -1;
+ int bestCount = 0;
+ if (!str1.isEmpty()) {
+ const SectionNode &sn = sectionNode(sectionIndex);
+ if (!(sn.type & (DaySection|DayOfWeekSection))) {
+ qWarning("QDateTimeParser::findDay Internal error");
+ return -1;
+ }
+ const QLocale l = locale();
+ for (int day=startDay; day<=7; ++day) {
+ const QString str2 = l.dayName(day, sn.count == 4 ? QLocale::LongFormat : QLocale::ShortFormat);
+
+ if (str1.startsWith(str2.toLower())) {
+ if (used)
+ *used = str2.size();
+ if (usedDay) {
+ *usedDay = str2;
+ }
+ return day;
+ }
+ if (context == FromString)
+ continue;
+
+ const int limit = qMin(str1.size(), str2.size());
+ bool found = true;
+ for (int i=0; i<limit; ++i) {
+ if (str1.at(i) != str2.at(i) && !str1.at(i).isSpace()) {
+ if (i > bestCount) {
+ bestCount = i;
+ bestMatch = day;
+ }
+ found = false;
+ break;
+ }
+
+ }
+ if (found) {
+ if (used)
+ *used = limit;
+ if (usedDay)
+ *usedDay = str2;
+
+ return day;
+ }
+ }
+ if (usedDay && bestMatch != -1) {
+ *usedDay = l.dayName(bestMatch, sn.count == 4 ? QLocale::LongFormat : QLocale::ShortFormat);
+ }
+ }
+ if (used)
+ *used = bestCount;
+
+ return bestMatch;
+}
+#endif // QT_NO_TEXTDATE
+
+/*!
+ \internal
+
+ returns
+ 0 if str == QDateTimeEdit::tr("AM")
+ 1 if str == QDateTimeEdit::tr("PM")
+ 2 if str can become QDateTimeEdit::tr("AM")
+ 3 if str can become QDateTimeEdit::tr("PM")
+ 4 if str can become QDateTimeEdit::tr("PM") and can become QDateTimeEdit::tr("AM")
+ -1 can't become anything sensible
+
+*/
+
+int QDateTimeParser::findAmPm(QString &str, int index, int *used) const
+{
+ const SectionNode &s = sectionNode(index);
+ if (s.type != AmPmSection) {
+ qWarning("QDateTimeParser::findAmPm Internal error");
+ return -1;
+ }
+ if (used)
+ *used = str.size();
+ if (str.trimmed().isEmpty()) {
+ return PossibleBoth;
+ }
+ const QLatin1Char space(' ');
+ int size = sectionMaxSize(index);
+
+ enum {
+ amindex = 0,
+ pmindex = 1
+ };
+ QString ampm[2];
+ ampm[amindex] = getAmPmText(AmText, s.count == 1 ? UpperCase : LowerCase);
+ ampm[pmindex] = getAmPmText(PmText, s.count == 1 ? UpperCase : LowerCase);
+ for (int i=0; i<2; ++i)
+ ampm[i].truncate(size);
+
+ QDTPDEBUG << "findAmPm" << str << ampm[0] << ampm[1];
+
+ if (str.indexOf(ampm[amindex], 0, Qt::CaseInsensitive) == 0) {
+ str = ampm[amindex];
+ return AM;
+ } else if (str.indexOf(ampm[pmindex], 0, Qt::CaseInsensitive) == 0) {
+ str = ampm[pmindex];
+ return PM;
+ } else if (context == FromString || (str.count(space) == 0 && str.size() >= size)) {
+ return Neither;
+ }
+ size = qMin(size, str.size());
+
+ bool broken[2] = {false, false};
+ for (int i=0; i<size; ++i) {
+ if (str.at(i) != space) {
+ for (int j=0; j<2; ++j) {
+ if (!broken[j]) {
+ int index = ampm[j].indexOf(str.at(i));
+ QDTPDEBUG << "looking for" << str.at(i)
+ << "in" << ampm[j] << "and got" << index;
+ if (index == -1) {
+ if (str.at(i).category() == QChar::Letter_Uppercase) {
+ index = ampm[j].indexOf(str.at(i).toLower());
+ QDTPDEBUG << "trying with" << str.at(i).toLower()
+ << "in" << ampm[j] << "and got" << index;
+ } else if (str.at(i).category() == QChar::Letter_Lowercase) {
+ index = ampm[j].indexOf(str.at(i).toUpper());
+ QDTPDEBUG << "trying with" << str.at(i).toUpper()
+ << "in" << ampm[j] << "and got" << index;
+ }
+ if (index == -1) {
+ broken[j] = true;
+ if (broken[amindex] && broken[pmindex]) {
+ QDTPDEBUG << str << "didn't make it";
+ return Neither;
+ }
+ continue;
+ } else {
+ str[i] = ampm[j].at(index); // fix case
+ }
+ }
+ ampm[j].remove(index, 1);
+ }
+ }
+ }
+ }
+ if (!broken[pmindex] && !broken[amindex])
+ return PossibleBoth;
+ return (!broken[amindex] ? PossibleAM : PossiblePM);
+}
+
+/*!
+ \internal
+ Max number of units that can be changed by this section.
+*/
+
+int QDateTimeParser::maxChange(int index) const
+{
+ const SectionNode &sn = sectionNode(index);
+ switch (sn.type) {
+ // Time. unit is msec
+ case MSecSection: return 999;
+ case SecondSection: return 59 * 1000;
+ case MinuteSection: return 59 * 60 * 1000;
+ case Hour24Section: case Hour12Section: return 59 * 60 * 60 * 1000;
+
+ // Date. unit is day
+ case DayOfWeekSection: return 7;
+ case DaySection: return 30;
+ case MonthSection: return 365 - 31;
+ case YearSection: return 9999 * 365;
+ case YearSection2Digits: return 100 * 365;
+ default:
+ qWarning("QDateTimeParser::maxChange() Internal error (%s)",
+ qPrintable(sectionName(sectionType(index))));
+ }
+
+ return -1;
+}
+
+QDateTimeParser::FieldInfo QDateTimeParser::fieldInfo(int index) const
+{
+ FieldInfo ret = 0;
+ const SectionNode &sn = sectionNode(index);
+ const Section s = sn.type;
+ switch (s) {
+ case MSecSection:
+ ret |= Fraction;
+ // fallthrough
+ case SecondSection:
+ case MinuteSection:
+ case Hour24Section:
+ case Hour12Section:
+ case YearSection:
+ case YearSection2Digits:
+ ret |= Numeric;
+ if (s != YearSection) {
+ ret |= AllowPartial;
+ }
+ if (sn.count != 1) {
+ ret |= FixedWidth;
+ }
+ break;
+ case MonthSection:
+ case DaySection:
+ switch (sn.count) {
+ case 2:
+ ret |= FixedWidth;
+ // fallthrough
+ case 1:
+ ret |= (Numeric|AllowPartial);
+ break;
+ }
+ break;
+ case DayOfWeekSection:
+ if (sn.count == 3)
+ ret |= FixedWidth;
+ break;
+ case AmPmSection:
+ ret |= FixedWidth;
+ break;
+ default:
+ qWarning("QDateTimeParser::fieldInfo Internal error 2 (%d %s %d)",
+ index, qPrintable(sectionName(sn.type)), sn.count);
+ break;
+ }
+ return ret;
+}
+
+/*!
+ \internal Get a number that str can become which is between min
+ and max or -1 if this is not possible.
+*/
+
+
+QString QDateTimeParser::sectionFormat(int index) const
+{
+ const SectionNode &sn = sectionNode(index);
+ return sectionFormat(sn.type, sn.count);
+}
+
+QString QDateTimeParser::sectionFormat(Section s, int count) const
+{
+ QChar fillChar;
+ switch (s) {
+ case AmPmSection: return count == 1 ? QLatin1String("AP") : QLatin1String("ap");
+ case MSecSection: fillChar = QLatin1Char('z'); break;
+ case SecondSection: fillChar = QLatin1Char('s'); break;
+ case MinuteSection: fillChar = QLatin1Char('m'); break;
+ case Hour24Section: fillChar = QLatin1Char('H'); break;
+ case Hour12Section: fillChar = QLatin1Char('h'); break;
+ case DayOfWeekSection:
+ case DaySection: fillChar = QLatin1Char('d'); break;
+ case MonthSection: fillChar = QLatin1Char('M'); break;
+ case YearSection2Digits:
+ case YearSection: fillChar = QLatin1Char('y'); break;
+ default:
+ qWarning("QDateTimeParser::sectionFormat Internal error (%s)",
+ qPrintable(sectionName(s)));
+ return QString();
+ }
+ if (fillChar.isNull()) {
+ qWarning("QDateTimeParser::sectionFormat Internal error 2");
+ return QString();
+ }
+
+ QString str;
+ str.fill(fillChar, count);
+ return str;
+}
+
+
+/*! \internal Returns true if str can be modified to represent a
+ number that is within min and max.
+*/
+
+bool QDateTimeParser::potentialValue(const QString &str, int min, int max, int index,
+ const QDateTime &currentValue, int insert) const
+{
+ if (str.isEmpty()) {
+ return true;
+ }
+ const int size = sectionMaxSize(index);
+ int val = (int)locale().toUInt(str);
+ const SectionNode &sn = sectionNode(index);
+ if (sn.type == YearSection2Digits) {
+ val += currentValue.date().year() - (currentValue.date().year() % 100);
+ }
+ if (val >= min && val <= max && str.size() == size) {
+ return true;
+ } else if (val > max) {
+ return false;
+ } else if (str.size() == size && val < min) {
+ return false;
+ }
+
+ const int len = size - str.size();
+ for (int i=0; i<len; ++i) {
+ for (int j=0; j<10; ++j) {
+ if (potentialValue(str + QLatin1Char('0' + j), min, max, index, currentValue, insert)) {
+ return true;
+ } else if (insert >= 0) {
+ QString tmp = str;
+ tmp.insert(insert, QLatin1Char('0' + j));
+ if (potentialValue(tmp, min, max, index, currentValue, insert))
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+bool QDateTimeParser::skipToNextSection(int index, const QDateTime &current, const QString &text) const
+{
+ Q_ASSERT(current >= getMinimum() && current <= getMaximum());
+
+ const SectionNode &node = sectionNode(index);
+ Q_ASSERT(text.size() < sectionMaxSize(index));
+
+ const QDateTime maximum = getMaximum();
+ const QDateTime minimum = getMinimum();
+ QDateTime tmp = current;
+ int min = absoluteMin(index);
+ setDigit(tmp, index, min);
+ if (tmp < minimum) {
+ min = getDigit(minimum, index);
+ }
+
+ int max = absoluteMax(index, current);
+ setDigit(tmp, index, max);
+ if (tmp > maximum) {
+ max = getDigit(maximum, index);
+ }
+ int pos = cursorPosition() - node.pos;
+ if (pos < 0 || pos >= text.size())
+ pos = -1;
+
+ const bool potential = potentialValue(text, min, max, index, current, pos);
+ return !potential;
+
+ /* If the value potentially can become another valid entry we
+ * don't want to skip to the next. E.g. In a M field (month
+ * without leading 0 if you type 1 we don't want to autoskip but
+ * if you type 3 we do
+ */
+}
+
+/*!
+ \internal
+ For debugging. Returns the name of the section \a s.
+*/
+
+QString QDateTimeParser::sectionName(int s) const
+{
+ switch (s) {
+ case QDateTimeParser::AmPmSection: return QLatin1String("AmPmSection");
+ case QDateTimeParser::DaySection: return QLatin1String("DaySection");
+ case QDateTimeParser::DayOfWeekSection: return QLatin1String("DayOfWeekSection");
+ case QDateTimeParser::Hour24Section: return QLatin1String("Hour24Section");
+ case QDateTimeParser::Hour12Section: return QLatin1String("Hour12Section");
+ case QDateTimeParser::MSecSection: return QLatin1String("MSecSection");
+ case QDateTimeParser::MinuteSection: return QLatin1String("MinuteSection");
+ case QDateTimeParser::MonthSection: return QLatin1String("MonthSection");
+ case QDateTimeParser::SecondSection: return QLatin1String("SecondSection");
+ case QDateTimeParser::YearSection: return QLatin1String("YearSection");
+ case QDateTimeParser::YearSection2Digits: return QLatin1String("YearSection2Digits");
+ case QDateTimeParser::NoSection: return QLatin1String("NoSection");
+ case QDateTimeParser::FirstSection: return QLatin1String("FirstSection");
+ case QDateTimeParser::LastSection: return QLatin1String("LastSection");
+ default: return QLatin1String("Unknown section ") + QString::number(s);
+ }
+}
+
+/*!
+ \internal
+ For debugging. Returns the name of the state \a s.
+*/
+
+QString QDateTimeParser::stateName(int s) const
+{
+ switch (s) {
+ case Invalid: return QLatin1String("Invalid");
+ case Intermediate: return QLatin1String("Intermediate");
+ case Acceptable: return QLatin1String("Acceptable");
+ default: return QLatin1String("Unknown state ") + QString::number(s);
+ }
+}
+
+#ifndef QT_NO_DATESTRING
+bool QDateTimeParser::fromString(const QString &t, QDate *date, QTime *time) const
+{
+ QDateTime val(QDate(1900, 1, 1), QDATETIMEEDIT_TIME_MIN);
+ QString text = t;
+ int copy = -1;
+ const StateNode tmp = parse(text, copy, val, false);
+ if (tmp.state != Acceptable || tmp.conflicts) {
+ return false;
+ }
+ if (time) {
+ const QTime t = tmp.value.time();
+ if (!t.isValid()) {
+ return false;
+ }
+ *time = t;
+ }
+
+ if (date) {
+ const QDate d = tmp.value.date();
+ if (!d.isValid()) {
+ return false;
+ }
+ *date = d;
+ }
+ return true;
+}
+#endif // QT_NO_DATESTRING
+
+QDateTime QDateTimeParser::getMinimum() const
+{
+ return QDateTime(QDATETIMEEDIT_DATE_MIN, QDATETIMEEDIT_TIME_MIN, spec);
+}
+
+QDateTime QDateTimeParser::getMaximum() const
+{
+ return QDateTime(QDATETIMEEDIT_DATE_MAX, QDATETIMEEDIT_TIME_MAX, spec);
+}
+
+QString QDateTimeParser::getAmPmText(AmPm ap, Case cs) const
+{
+ if (ap == AmText) {
+ return (cs == UpperCase ? QLatin1String("AM") : QLatin1String("am"));
+ } else {
+ return (cs == UpperCase ? QLatin1String("PM") : QLatin1String("pm"));
+ }
+}
+
+/*
+ \internal
+
+ I give arg2 preference because arg1 is always a QDateTime.
+*/
+
+bool operator==(const QDateTimeParser::SectionNode &s1, const QDateTimeParser::SectionNode &s2)
+{
+ return (s1.type == s2.type) && (s1.pos == s2.pos) && (s1.count == s2.count);
+}
+
+
+#endif // QT_BOOTSTRAPPED
+
+QT_END_NAMESPACE
diff --git a/src/corelib/tools/qdatetime.h b/src/corelib/tools/qdatetime.h
new file mode 100644
index 0000000000..327829798e
--- /dev/null
+++ b/src/corelib/tools/qdatetime.h
@@ -0,0 +1,333 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDATETIME_H
+#define QDATETIME_H
+
+#include <QtCore/qstring.h>
+#include <QtCore/qnamespace.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Core)
+
+class Q_CORE_EXPORT QDate
+{
+public:
+ enum MonthNameType {
+ DateFormat = 0,
+ StandaloneFormat
+ };
+public:
+ QDate() { jd = 0; }
+ QDate(int y, int m, int d);
+
+ bool isNull() const { return jd == 0; }
+ bool isValid() const;
+
+ int year() const;
+ int month() const;
+ int day() const;
+ int dayOfWeek() const;
+ int dayOfYear() const;
+ int daysInMonth() const;
+ int daysInYear() const;
+ int weekNumber(int *yearNum = 0) const;
+
+#ifndef QT_NO_TEXTDATE
+#ifdef QT3_SUPPORT
+ static QT3_SUPPORT QString monthName(int month) { return shortMonthName(month); }
+ static QT3_SUPPORT QString dayName(int weekday) { return shortDayName(weekday); }
+#endif
+ // ### Qt 5: merge these functions.
+ static QString shortMonthName(int month);
+ static QString shortMonthName(int month, MonthNameType type);
+ static QString shortDayName(int weekday);
+ static QString shortDayName(int weekday, MonthNameType type);
+ static QString longMonthName(int month);
+ static QString longMonthName(int month, MonthNameType type);
+ static QString longDayName(int weekday);
+ static QString longDayName(int weekday, MonthNameType type);
+#endif // QT_NO_TEXTDATE
+#ifndef QT_NO_DATESTRING
+ QString toString(Qt::DateFormat f = Qt::TextDate) const;
+ QString toString(const QString &format) const;
+#endif
+ bool setYMD(int y, int m, int d);
+ bool setDate(int year, int month, int day);
+
+ void getDate(int *year, int *month, int *day);
+
+ QDate addDays(int days) const;
+ QDate addMonths(int months) const;
+ QDate addYears(int years) const;
+ int daysTo(const QDate &) const;
+
+ bool operator==(const QDate &other) const { return jd == other.jd; }
+ bool operator!=(const QDate &other) const { return jd != other.jd; }
+ bool operator<(const QDate &other) const { return jd < other.jd; }
+ bool operator<=(const QDate &other) const { return jd <= other.jd; }
+ bool operator>(const QDate &other) const { return jd > other.jd; }
+ bool operator>=(const QDate &other) const { return jd >= other.jd; }
+
+ static QDate currentDate();
+#ifndef QT_NO_DATESTRING
+ static QDate fromString(const QString &s, Qt::DateFormat f = Qt::TextDate);
+ static QDate fromString(const QString &s, const QString &format);
+#endif
+ static bool isValid(int y, int m, int d);
+ static bool isLeapYear(int year);
+#ifdef QT3_SUPPORT
+ inline static QT3_SUPPORT bool leapYear(int year) { return isLeapYear(year); }
+#endif
+
+ // ### Qt 5: remove these two functions
+ static uint gregorianToJulian(int y, int m, int d);
+ static void julianToGregorian(uint jd, int &y, int &m, int &d);
+
+#ifdef QT3_SUPPORT
+ static QT3_SUPPORT QDate currentDate(Qt::TimeSpec spec);
+#endif
+
+ static inline QDate fromJulianDay(int jd) { QDate d; d.jd = jd; return d; }
+ inline int toJulianDay() const { return jd; }
+
+private:
+ uint jd;
+
+ friend class QDateTime;
+ friend class QDateTimePrivate;
+#ifndef QT_NO_DATASTREAM
+ friend Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QDate &);
+ friend Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QDate &);
+#endif
+};
+Q_DECLARE_TYPEINFO(QDate, Q_MOVABLE_TYPE);
+
+class Q_CORE_EXPORT QTime
+{
+public:
+ QTime(): mds(NullTime)
+#if defined(Q_OS_WINCE)
+ , startTick(NullTime)
+#endif
+ {}
+ QTime(int h, int m, int s = 0, int ms = 0);
+
+ bool isNull() const { return mds == NullTime; }
+ bool isValid() const;
+
+ int hour() const;
+ int minute() const;
+ int second() const;
+ int msec() const;
+#ifndef QT_NO_DATESTRING
+ QString toString(Qt::DateFormat f = Qt::TextDate) const;
+ QString toString(const QString &format) const;
+#endif
+ bool setHMS(int h, int m, int s, int ms = 0);
+
+ QTime addSecs(int secs) const;
+ int secsTo(const QTime &) const;
+ QTime addMSecs(int ms) const;
+ int msecsTo(const QTime &) const;
+
+ bool operator==(const QTime &other) const { return mds == other.mds; }
+ bool operator!=(const QTime &other) const { return mds != other.mds; }
+ bool operator<(const QTime &other) const { return mds < other.mds; }
+ bool operator<=(const QTime &other) const { return mds <= other.mds; }
+ bool operator>(const QTime &other) const { return mds > other.mds; }
+ bool operator>=(const QTime &other) const { return mds >= other.mds; }
+
+ static QTime currentTime();
+#ifndef QT_NO_DATESTRING
+ static QTime fromString(const QString &s, Qt::DateFormat f = Qt::TextDate);
+ static QTime fromString(const QString &s, const QString &format);
+#endif
+ static bool isValid(int h, int m, int s, int ms = 0);
+
+#ifdef QT3_SUPPORT
+ static QT3_SUPPORT QTime currentTime(Qt::TimeSpec spec);
+#endif
+
+ void start();
+ int restart();
+ int elapsed() const;
+private:
+ enum TimeFlag { NullTime = -1 };
+ inline int ds() const { return mds == -1 ? 0 : mds; }
+ int mds;
+#if defined(Q_OS_WINCE)
+ int startTick;
+#endif
+
+ friend class QDateTime;
+ friend class QDateTimePrivate;
+#ifndef QT_NO_DATASTREAM
+ friend Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QTime &);
+ friend Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QTime &);
+#endif
+};
+Q_DECLARE_TYPEINFO(QTime, Q_MOVABLE_TYPE);
+
+class QDateTimePrivate;
+
+class Q_CORE_EXPORT QDateTime
+{
+public:
+ QDateTime();
+ explicit QDateTime(const QDate &);
+ QDateTime(const QDate &, const QTime &, Qt::TimeSpec spec = Qt::LocalTime);
+ QDateTime(const QDateTime &other);
+ ~QDateTime();
+
+ QDateTime &operator=(const QDateTime &other);
+
+ bool isNull() const;
+ bool isValid() const;
+
+ QDate date() const;
+ QTime time() const;
+ Qt::TimeSpec timeSpec() const;
+ uint toTime_t() const;
+ void setDate(const QDate &date);
+ void setTime(const QTime &time);
+ void setTimeSpec(Qt::TimeSpec spec);
+ void setTime_t(uint secsSince1Jan1970UTC);
+#ifndef QT_NO_DATESTRING
+ QString toString(Qt::DateFormat f = Qt::TextDate) const;
+ QString toString(const QString &format) const;
+#endif
+ QDateTime addDays(int days) const;
+ QDateTime addMonths(int months) const;
+ QDateTime addYears(int years) const;
+ QDateTime addSecs(int secs) const;
+ QDateTime addMSecs(qint64 msecs) const;
+ QDateTime toTimeSpec(Qt::TimeSpec spec) const;
+ inline QDateTime toLocalTime() const { return toTimeSpec(Qt::LocalTime); }
+ inline QDateTime toUTC() const { return toTimeSpec(Qt::UTC); }
+ int daysTo(const QDateTime &) const;
+ int secsTo(const QDateTime &) const;
+
+ bool operator==(const QDateTime &other) const;
+ inline bool operator!=(const QDateTime &other) const { return !(*this == other); }
+ bool operator<(const QDateTime &other) const;
+ inline bool operator<=(const QDateTime &other) const { return !(other < *this); }
+ inline bool operator>(const QDateTime &other) const { return other < *this; }
+ inline bool operator>=(const QDateTime &other) const { return !(*this < other); }
+
+ void setUtcOffset(int seconds);
+ int utcOffset() const;
+
+ static QDateTime currentDateTime();
+#ifndef QT_NO_DATESTRING
+ static QDateTime fromString(const QString &s, Qt::DateFormat f = Qt::TextDate);
+ static QDateTime fromString(const QString &s, const QString &format);
+#endif
+ static QDateTime fromTime_t(uint secsSince1Jan1970UTC);
+
+#ifdef QT3_SUPPORT
+ inline QT3_SUPPORT void setTime_t(uint secsSince1Jan1970UTC, Qt::TimeSpec spec) {
+ setTime_t(secsSince1Jan1970UTC);
+ if (spec == Qt::UTC)
+ *this = toUTC();
+ }
+ static inline QT3_SUPPORT QDateTime currentDateTime(Qt::TimeSpec spec) {
+ if (spec == Qt::LocalTime)
+ return currentDateTime();
+ else
+ return currentDateTime().toUTC();
+ }
+
+#endif
+
+private:
+ friend class QDateTimePrivate;
+ void detach();
+ QDateTimePrivate *d;
+
+#ifndef QT_NO_DATASTREAM
+ friend Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QDateTime &);
+ friend Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QDateTime &);
+#endif
+};
+Q_DECLARE_TYPEINFO(QDateTime, Q_MOVABLE_TYPE);
+
+#ifdef QT3_SUPPORT
+inline QDate QDate::currentDate(Qt::TimeSpec spec)
+{
+ if (spec == Qt::LocalTime)
+ return currentDate();
+ else
+ return QDateTime::currentDateTime().toUTC().date();
+}
+
+inline QTime QTime::currentTime(Qt::TimeSpec spec)
+{
+ if (spec == Qt::LocalTime)
+ return currentTime();
+ else
+ return QDateTime::currentDateTime().toUTC().time();
+}
+#endif
+
+#ifndef QT_NO_DATASTREAM
+Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QDate &);
+Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QDate &);
+Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QTime &);
+Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QTime &);
+Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QDateTime &);
+Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QDateTime &);
+#endif // QT_NO_DATASTREAM
+
+#if !defined(QT_NO_DEBUG_STREAM) && !defined(QT_NO_DATESTRING)
+Q_CORE_EXPORT QDebug operator<<(QDebug, const QDate &);
+Q_CORE_EXPORT QDebug operator<<(QDebug, const QTime &);
+Q_CORE_EXPORT QDebug operator<<(QDebug, const QDateTime &);
+#endif
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QDATETIME_H
diff --git a/src/corelib/tools/qdatetime_p.h b/src/corelib/tools/qdatetime_p.h
new file mode 100644
index 0000000000..b2fb58df0f
--- /dev/null
+++ b/src/corelib/tools/qdatetime_p.h
@@ -0,0 +1,285 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDATETIME_P_H
+#define QDATETIME_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 "qplatformdefs.h"
+#include "QtCore/qatomic.h"
+#include "QtCore/qdatetime.h"
+#include "QtCore/qstringlist.h"
+#include "QtCore/qlocale.h"
+#ifndef QT_BOOTSTRAPPED
+# include "QtCore/qvariant.h"
+#endif
+#include "QtCore/qvector.h"
+
+
+#define QDATETIMEEDIT_TIME_MIN QTime(0, 0, 0, 0)
+#define QDATETIMEEDIT_TIME_MAX QTime(23, 59, 59, 999)
+#define QDATETIMEEDIT_DATE_MIN QDate(100, 1, 1)
+#define QDATETIMEEDIT_COMPAT_DATE_MIN QDate(1752, 9, 14)
+#define QDATETIMEEDIT_DATE_MAX QDate(7999, 12, 31)
+#define QDATETIMEEDIT_DATETIME_MIN QDateTime(QDATETIMEEDIT_DATE_MIN, QDATETIMEEDIT_TIME_MIN)
+#define QDATETIMEEDIT_COMPAT_DATETIME_MIN QDateTime(QDATETIMEEDIT_COMPAT_DATE_MIN, QDATETIMEEDIT_TIME_MIN)
+#define QDATETIMEEDIT_DATETIME_MAX QDateTime(QDATETIMEEDIT_DATE_MAX, QDATETIMEEDIT_TIME_MAX)
+#define QDATETIMEEDIT_DATE_INITIAL QDate(2000, 1, 1)
+
+QT_BEGIN_NAMESPACE
+
+class QDateTimePrivate
+{
+public:
+ enum Spec { LocalUnknown = -1, LocalStandard = 0, LocalDST = 1, UTC = 2, OffsetFromUTC = 3};
+
+ QDateTimePrivate() : ref(1), spec(LocalUnknown), utcOffset(0) {}
+ QDateTimePrivate(const QDateTimePrivate &other)
+ : ref(1), date(other.date), time(other.time), spec(other.spec), utcOffset(other.utcOffset)
+ {}
+
+ QAtomicInt ref;
+ QDate date;
+ QTime time;
+ Spec spec;
+ /*!
+ \internal
+ \since 4.4
+
+ The offset in seconds. Applies only when timeSpec() is OffsetFromUTC.
+ */
+ int utcOffset;
+
+ Spec getLocal(QDate &outDate, QTime &outTime) const;
+ void getUTC(QDate &outDate, QTime &outTime) const;
+ static QDateTime addMSecs(const QDateTime &dt, qint64 msecs);
+ static void addMSecs(QDate &utcDate, QTime &utcTime, qint64 msecs);
+};
+
+#ifndef QT_BOOTSTRAPPED
+
+class Q_CORE_EXPORT QDateTimeParser
+{
+public:
+ enum Context {
+ FromString,
+ DateTimeEdit
+ };
+ QDateTimeParser(QVariant::Type t, Context ctx)
+ : currentSectionIndex(-1), display(0), cachedDay(-1), parserType(t),
+ fixday(false), spec(Qt::LocalTime), context(ctx)
+ {
+ defaultLocale = QLocale::system();
+ first.type = FirstSection;
+ first.pos = -1;
+ first.count = -1;
+ last.type = FirstSection;
+ last.pos = -1;
+ last.count = -1;
+ none.type = NoSection;
+ none.pos = -1;
+ none.count = -1;
+ }
+ virtual ~QDateTimeParser() {}
+ enum {
+ Neither = -1,
+ AM = 0,
+ PM = 1,
+ PossibleAM = 2,
+ PossiblePM = 3,
+ PossibleBoth = 4
+ };
+
+ enum {
+ NoSectionIndex = -1,
+ FirstSectionIndex = -2,
+ LastSectionIndex = -3,
+ CalendarPopupIndex = -4
+ };
+
+ enum Section {
+ NoSection = 0x00000,
+ AmPmSection = 0x00001,
+ MSecSection = 0x00002,
+ SecondSection = 0x00004,
+ MinuteSection = 0x00008,
+ Hour12Section = 0x00010,
+ Hour24Section = 0x00020,
+ TimeSectionMask = (AmPmSection|MSecSection|SecondSection|MinuteSection|Hour12Section|Hour24Section),
+ Internal = 0x10000,
+ DaySection = 0x00100,
+ MonthSection = 0x00200,
+ YearSection = 0x00400,
+ YearSection2Digits = 0x00800,
+ DayOfWeekSection = 0x01000,
+ DateSectionMask = (DaySection|MonthSection|YearSection|YearSection2Digits|DayOfWeekSection),
+ FirstSection = 0x02000|Internal,
+ LastSection = 0x04000|Internal,
+ CalendarPopupSection = 0x08000|Internal
+ }; // duplicated from qdatetimeedit.h
+ Q_DECLARE_FLAGS(Sections, Section)
+
+ struct SectionNode {
+ Section type;
+ mutable int pos;
+ int count;
+ };
+
+ enum State { // duplicated from QValidator
+ Invalid,
+ Intermediate,
+ Acceptable
+ };
+
+ struct StateNode {
+ StateNode() : state(Invalid), conflicts(false) {}
+ QString input;
+ State state;
+ bool conflicts;
+ QDateTime value;
+ };
+
+ enum AmPm {
+ AmText,
+ PmText
+ };
+
+ enum Case {
+ UpperCase,
+ LowerCase
+ };
+
+#ifndef QT_NO_DATESTRING
+ StateNode parse(QString &input, int &cursorPosition, const QDateTime &currentValue, bool fixup) const;
+#endif
+ int sectionMaxSize(int index) const;
+ int sectionSize(int index) const;
+ int sectionMaxSize(Section s, int count) const;
+ int sectionPos(int index) const;
+ int sectionPos(const SectionNode &sn) const;
+
+ const SectionNode &sectionNode(int index) const;
+ Section sectionType(int index) const;
+ QString sectionText(int sectionIndex) const;
+ QString sectionText(const QString &text, int sectionIndex, int index) const;
+ int getDigit(const QDateTime &dt, int index) const;
+ bool setDigit(QDateTime &t, int index, int newval) const;
+ int parseSection(const QDateTime &currentValue, int sectionIndex, QString &txt, int &cursorPosition,
+ int index, QDateTimeParser::State &state, int *used = 0) const;
+ int absoluteMax(int index, const QDateTime &value = QDateTime()) const;
+ int absoluteMin(int index) const;
+ bool parseFormat(const QString &format);
+#ifndef QT_NO_DATESTRING
+ bool fromString(const QString &text, QDate *date, QTime *time) const;
+#endif
+
+#ifndef QT_NO_TEXTDATE
+ int findMonth(const QString &str1, int monthstart, int sectionIndex,
+ QString *monthName = 0, int *used = 0) const;
+ int findDay(const QString &str1, int intDaystart, int sectionIndex,
+ QString *dayName = 0, int *used = 0) const;
+#endif
+ int findAmPm(QString &str1, int index, int *used = 0) const;
+ int maxChange(int s) const;
+ bool potentialValue(const QString &str, int min, int max, int index,
+ const QDateTime &currentValue, int insert) const;
+ bool skipToNextSection(int section, const QDateTime &current, const QString &sectionText) const;
+ QString sectionName(int s) const;
+ QString stateName(int s) const;
+
+ QString sectionFormat(int index) const;
+ QString sectionFormat(Section s, int count) const;
+
+ enum FieldInfoFlag {
+ Numeric = 0x01,
+ FixedWidth = 0x02,
+ AllowPartial = 0x04,
+ Fraction = 0x08
+ };
+ Q_DECLARE_FLAGS(FieldInfo, FieldInfoFlag)
+
+ FieldInfo fieldInfo(int index) const;
+
+ virtual QDateTime getMinimum() const;
+ virtual QDateTime getMaximum() const;
+ virtual int cursorPosition() const { return -1; }
+ virtual QString displayText() const { return text; }
+ virtual QString getAmPmText(AmPm ap, Case cs) const;
+ virtual QLocale locale() const { return defaultLocale; }
+
+ mutable int currentSectionIndex;
+ Sections display;
+ mutable int cachedDay;
+ mutable QString text;
+ QVector<SectionNode> sectionNodes;
+ SectionNode first, last, none, popup;
+ QStringList separators;
+ QString displayFormat;
+ QLocale defaultLocale;
+ QVariant::Type parserType;
+
+ bool fixday;
+
+ Qt::TimeSpec spec; // spec if used by QDateTimeEdit
+ Context context;
+};
+
+Q_CORE_EXPORT bool operator==(const QDateTimeParser::SectionNode &s1, const QDateTimeParser::SectionNode &s2);
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QDateTimeParser::Sections)
+Q_DECLARE_OPERATORS_FOR_FLAGS(QDateTimeParser::FieldInfo)
+
+
+#endif // QT_BOOTSTRAPPED
+
+QT_END_NAMESPACE
+
+#endif // QDATETIME_P_H
diff --git a/src/corelib/tools/qdumper.cpp b/src/corelib/tools/qdumper.cpp
new file mode 100644
index 0000000000..c3b8524cee
--- /dev/null
+++ b/src/corelib/tools/qdumper.cpp
@@ -0,0 +1,1157 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qdatetime.h>
+#include <qdebug.h>
+#include <qdir.h>
+#include <qfileinfo.h>
+#include <qhash.h>
+#include <qmap.h>
+#include <qmetaobject.h>
+#include <qobject.h>
+#include <qstring.h>
+#include <qvariant.h>
+#include <qvector.h>
+
+#if !defined(Q_OS_WINCE) && !defined(QT_NO_DUMPER)
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#ifdef Q_OS_WIN
+# include <windows.h>
+#endif
+
+QT_BEGIN_NAMESPACE
+
+namespace {
+
+// This is used to abort evaluation of custom data dumpers in a "coordinated"
+// way. Abortion will happen anyway when we try to access a non-initialized
+// non-trivial object, so there is no way to prevent this from occuring at all
+// conceptionally. Gdb will catch SIGSEGV and return to the calling frame.
+// This is just fine provided we only _read_ memory in the custom handlers
+// below.
+
+volatile int qProvokeSegFaultHelper;
+
+static void qCheckAccess(const void *d)
+{
+ // provoke segfault when address is not readable
+ qProvokeSegFaultHelper = *(char*)d;
+}
+
+static void qCheckPointer(const void *d)
+{
+ if (!d)
+ return;
+ qProvokeSegFaultHelper = *(char*)d;
+}
+
+static void qProvokeSegFault()
+{
+ // provoke segfault unconditionally
+ qCheckAccess(0);
+}
+
+static char qDumpInBuffer[100];
+static char qDumpBuffer[1000];
+#ifdef Q_OS_WIN
+static char qDumpBuffer2[sizeof(qDumpBuffer) + 100];
+#endif
+
+static char toHex(int n)
+{
+ return n < 10 ? '0' + n : 'a' - 10 + n;
+}
+
+
+struct QDumper
+{
+ explicit QDumper();
+ ~QDumper();
+ void flush();
+ QDumper &operator<<(long c);
+ QDumper &operator<<(int i);
+ QDumper &operator<<(unsigned long c);
+ QDumper &operator<<(unsigned int i);
+ QDumper &operator<<(const void *p);
+ void put(char c);
+ void addCommaIfNeeded();
+ void putEncoded(unsigned c);
+ QDumper &operator<<(const char *str);
+ QDumper &operator<<(const QString &str);
+ void disarm();
+
+ void beginHash(); // start of data hash output
+ void endHash(); // start of data hash output
+
+ // the dumper arguments
+ int protocolVersion; // dumper protocol version
+ int token; // some token to show on success
+ const char *outertype; // object type
+ const char *iname; // object name used for display
+ const char *exp; // object expression
+ const char *innertype; // 'inner type' for class templates
+ const void *data; // pointer to raw data
+ bool dumpChildren; // do we want to see children?
+
+ // handling of nested templates
+ void setupTemplateParameters();
+ enum { maxTemplateParameters = 10 };
+ const char *templateParameters[maxTemplateParameters + 1];
+ int templateParametersCount;
+
+ // internal state
+ bool success; // are we finished?
+ size_t pos;
+};
+
+
+QDumper::QDumper()
+{
+ success = false;
+ pos = 0;
+}
+
+QDumper::~QDumper()
+{
+ flush();
+ put(0); // our end marker
+#ifdef Q_OS_WIN
+ sprintf(qDumpBuffer2, "@@CDD/%d/done\n", token);
+ OutputDebugStringA(qDumpBuffer2);
+#else
+ fprintf(stderr, "%d/done\n", token);
+#endif
+ qDumpInBuffer[0] = 0;
+}
+
+void QDumper::flush()
+{
+ qDumpBuffer[pos++] = 0;
+#ifdef Q_OS_WIN
+ sprintf(qDumpBuffer2, "@@CDD#%d#%d,%s\n", token, int(pos - 1), qDumpBuffer);
+ OutputDebugStringA(qDumpBuffer2);
+#else
+ fprintf(stderr, "%d#%d,%s\n", token, int(pos - 1), qDumpBuffer);
+#endif
+ pos = 0;
+}
+
+void QDumper::setupTemplateParameters()
+{
+ char *s = const_cast<char *>(innertype);
+
+ templateParametersCount = 1;
+ templateParameters[0] = s;
+ for (int i = 1; i != maxTemplateParameters + 1; ++i)
+ templateParameters[i] = 0;
+
+ while (*s) {
+ while (*s && *s != '@')
+ ++s;
+ if (*s) {
+ *s = '\0';
+ ++s;
+ templateParameters[templateParametersCount++] = s;
+ }
+ }
+}
+
+QDumper &QDumper::operator<<(unsigned long c)
+{
+ static char buf[100];
+ sprintf(buf, "%lu", c);
+ return (*this) << buf;
+}
+
+QDumper &QDumper::operator<<(unsigned int i)
+{
+ static char buf[100];
+ sprintf(buf, "%u", i);
+ return (*this) << buf;
+}
+
+QDumper &QDumper::operator<<(long c)
+{
+ static char buf[100];
+ sprintf(buf, "%ld", c);
+ return (*this) << buf;
+}
+
+QDumper &QDumper::operator<<(int i)
+{
+ static char buf[100];
+ sprintf(buf, "%d", i);
+ return (*this) << buf;
+}
+
+QDumper &QDumper::operator<<(const void *p)
+{
+ static char buf[100];
+ sprintf(buf, "%p", p);
+ // we get a '0x' prefix only on some implementations.
+ // if it isn't there, write it out manually.
+ if (buf[1] != 'x') {
+ put('0');
+ put('x');
+ }
+ return (*this) << buf;
+}
+
+void QDumper::put(char c)
+{
+ if (pos >= sizeof(qDumpBuffer) - 100)
+ flush();
+ qDumpBuffer[pos++] = c;
+}
+
+void QDumper::addCommaIfNeeded()
+{
+ if (pos == 0)
+ return;
+ if (qDumpBuffer[pos - 1] == '}' || qDumpBuffer[pos - 1] == '"')
+ put(',');
+}
+
+void QDumper::putEncoded(unsigned c)
+{
+ if (c >= 32 && c <= 126 && c != '"' && c != '\\') {
+ put(c);
+ } else {
+ put('\\');
+ put('u');
+ put(toHex((c >> 12) & 0xf));
+ put(toHex((c >> 8) & 0xf));
+ put(toHex((c >> 4) & 0xf));
+ put(toHex( c & 0xf));
+ }
+}
+
+QDumper &QDumper::operator<<(const char *str)
+{
+ while (*str)
+ put(*(str++));
+ return *this;
+}
+
+QDumper &QDumper::operator<<(const QString &str)
+{
+ int n = str.size();
+ if (n < 0) {
+ qProvokeSegFault();
+ } else {
+ //(*this) << "[" << n << "]";
+ if (n > 1000000)
+ n = 1000000;
+ //put(' ');
+ put('\\');
+ put('"');
+ for (int i = 0; i != n; ++i)
+ putEncoded(str[i].unicode());
+ put('\\');
+ put('"');
+ if (n < str.size())
+ (*this) << "<incomplete string>";
+ }
+ return *this;
+}
+
+void QDumper::disarm()
+{
+ flush();
+ success = true;
+}
+
+void QDumper::beginHash()
+{
+ addCommaIfNeeded();
+ put('{');
+}
+
+void QDumper::endHash()
+{
+ put('}');
+}
+
+
+//
+// Some helpers to keep the dumper code short
+//
+
+// dump property=value pair
+#undef P
+#define P(dumper,name,value) \
+ do { \
+ dumper.addCommaIfNeeded(); \
+ dumper << (name) << "=\"" << value << "\""; \
+ } while (0)
+
+// simple string property
+#undef S
+#define S(dumper, name, value) \
+ dumper.beginHash(); \
+ P(dumper, "name", name); \
+ P(dumper, "value", value); \
+ P(dumper, "type", "QString"); \
+ P(dumper, "numchild", "0"); \
+ dumper.endHash();
+
+// simple integer property
+#undef I
+#define I(dumper, name, value) \
+ dumper.beginHash(); \
+ P(dumper, "name", name); \
+ P(dumper, "value", value); \
+ P(dumper, "type", "int"); \
+ P(dumper, "numchild", "0"); \
+ dumper.endHash();
+
+// simple boolean property
+#undef BL
+#define BL(dumper, name, value) \
+ dumper.beginHash(); \
+ P(dumper, "name", name); \
+ P(dumper, "value", (value ? "true" : "false")); \
+ P(dumper, "type", "bool"); \
+ P(dumper, "numchild", "0"); \
+ dumper.endHash();
+
+#undef TT
+#define TT(type, value) \
+ "<tr><td>" << type << "</td><td> : </td><td>" << value << "</td></tr>"
+
+static void qDumpUnknown(QDumper &d)
+{
+ P(d, "iname", d.iname);
+ P(d, "addr", d.data);
+ P(d, "value", "<internal error>");
+ P(d, "type", d.outertype);
+ P(d, "numchild", "0");
+ d.disarm();
+}
+
+static void qDumpQPropertyList(QDumper &d)
+{
+ const QObject *ob = (const QObject *)d.data;
+ const QMetaObject *mo = ob->metaObject();
+ P(d, "iname", d.iname);
+ P(d, "addr", "<synthetic>");
+ P(d, "type", "QObject");
+ P(d, "numchild", mo->propertyCount());
+ if (d.dumpChildren) {
+ d << ",children=[";
+ for (int i = mo->propertyCount(); --i >= 0; ) {
+ const QMetaProperty & prop = mo->property(i);
+ d.beginHash();
+ P(d, "name", prop.name());
+ if (QLatin1String(prop.typeName()) == QLatin1String("QString")) {
+ P(d, "value", prop.read(ob).toString());
+ P(d, "numchild", "0");
+ } else if (QLatin1String(prop.typeName()) == QLatin1String("bool")) {
+ P(d, "value", (prop.read(ob).toBool() ? "true" : "false"));
+ P(d, "numchild", "0");
+ } else if (QLatin1String(prop.typeName()) == QLatin1String("int")) {
+ P(d, "value", prop.read(ob).toInt());
+ P(d, "numchild", "0");
+ } else {
+ P(d, "exp", "((" << mo->className() << "*)" << ob
+ << ")->" << prop.name() << "()");
+ }
+ P(d, "type", prop.typeName());
+ P(d, "numchild", "1");
+ d.endHash();
+ }
+ d << "]";
+ }
+ d.disarm();
+}
+
+static void qDumpQObject(QDumper &d)
+{
+ const QObject *ob = reinterpret_cast<const QObject *>(d.data);
+ P(d, "iname", d.iname);
+ P(d, "addr", d.data);
+ P(d, "value", (void*)d.data);
+ P(d, "type", "QObject");
+ P(d, "numchild", 4);
+ if (d.dumpChildren) {
+ const QMetaObject *mo = ob->metaObject();
+ const QObjectList &children = ob->children();
+ d << ",children=[";
+ S(d, "objectName", ob->objectName());
+ d.beginHash();
+ P(d, "name", "properties");
+ // FIXME: Note that when simply using '(QObject*)'
+ // in the cast below, Gdb/MI _sometimes misparses
+ // expressions further down in the tree.
+ P(d, "exp", "*(class QObject*)" << d.data);
+ P(d, "type", "QPropertyList");
+ P(d, "value", "<" << mo->propertyCount() << " items>");
+ P(d, "numchild", mo->propertyCount());
+ d.endHash();
+ d.beginHash();
+ P(d, "name", "children");
+ P(d, "exp", "((class QObject*)" << d.data << ")->children()");
+ P(d, "type", "QList<QObject *>");
+ P(d, "value", "<" << children.size() << " items>");
+ P(d, "numchild", children.size());
+ d.endHash();
+ d.beginHash();
+ P(d, "name", "parent");
+ P(d, "exp", "((class QObject*)" << d.data << ")->parent()");
+ P(d, "type", "QObject *");
+ P(d, "numchild", (ob->parent() ? "1" : "0"));
+ d.endHash();
+ d << "]";
+ }
+ d.disarm();
+}
+
+static void qDumpQDir(QDumper &d)
+{
+ const QDir &dir = *reinterpret_cast<const QDir *>(d.data);
+ P(d, "iname", d.iname);
+ P(d, "addr", d.data);
+ P(d, "value", dir.path());
+ P(d, "type", "QDir");
+ P(d, "numchild", "3");
+ if (d.dumpChildren) {
+ d << ",children=[";
+ S(d, "absolutePath", dir.absolutePath());
+ S(d, "canonicalPath", dir.canonicalPath());
+ d << "]";
+ }
+ d.disarm();
+}
+
+static void qDumpQFileInfo(QDumper &d)
+{
+ const QFileInfo &info = *reinterpret_cast<const QFileInfo *>(d.data);
+ P(d, "iname", d.iname);
+ P(d, "addr", d.data);
+ P(d, "value", info.filePath());
+ P(d, "type", "QDir");
+ P(d, "numchild", "3");
+ if (d.dumpChildren) {
+ d << ",children=[";
+ S(d, "absolutePath", info.absolutePath());
+ S(d, "absoluteFilePath", info.absoluteFilePath());
+ S(d, "canonicalPath", info.canonicalPath());
+ S(d, "canonicalFilePath", info.canonicalFilePath());
+ S(d, "completeBaseName", info.completeBaseName());
+ S(d, "completeSuffix", info.completeSuffix());
+ S(d, "baseName", info.baseName());
+#ifdef Q_OS_MACX
+ BL(d, "isBundle", info.isBundle());
+ S(d, "bundleName", info.bundleName());
+#endif
+ S(d, "completeSuffix", info.completeSuffix());
+ S(d, "fileName", info.fileName());
+ S(d, "filePath", info.filePath());
+ S(d, "group", info.group());
+ S(d, "owner", info.owner());
+ S(d, "path", info.path());
+
+ I(d, "groupid", (long)info.groupId());
+ I(d, "ownerid", (long)info.ownerId());
+ //QFile::Permissions permissions () const
+ I(d, "permissions", info.permissions());
+
+ //QDir absoluteDir () const
+ //QDir dir () const
+
+ BL(d, "caching", info.caching());
+ BL(d, "exists", info.exists());
+ BL(d, "isAbsolute", info.isAbsolute());
+ BL(d, "isDir", info.isDir());
+ BL(d, "isExecutable", info.isExecutable());
+ BL(d, "isFile", info.isFile());
+ BL(d, "isHidden", info.isHidden());
+ BL(d, "isReadable", info.isReadable());
+ BL(d, "isRelative", info.isRelative());
+ BL(d, "isRoot", info.isRoot());
+ BL(d, "isSymLink", info.isSymLink());
+ BL(d, "isWritable", info.isWritable());
+
+#ifndef QT_NO_DATESTRING
+ d.beginHash();
+ P(d, "name", "created");
+ P(d, "value", info.created().toString());
+ P(d, "exp", "((QFileInfo*)" << d.data << ")->created()");
+ P(d, "type", "QDateTime");
+ P(d, "numchild", "1");
+ d.endHash();
+
+ d.beginHash();
+ P(d, "name", "lastModified");
+ P(d, "value", info.lastModified().toString());
+ P(d, "exp", "((QFileInfo*)" << d.data << ")->lastModified()");
+ P(d, "type", "QDateTime");
+ P(d, "numchild", "1");
+ d.endHash();
+
+ d.beginHash();
+ P(d, "name", "lastRead");
+ P(d, "value", info.lastRead().toString());
+ P(d, "exp", "((QFileInfo*)" << d.data << ")->lastRead()");
+ P(d, "type", "QDateTime");
+ P(d, "numchild", "1");
+ d.endHash();
+#endif
+
+ d << "]";
+ }
+ d.disarm();
+}
+
+static void qDumpQDateTime(QDumper &d)
+{
+#ifdef QT_NO_DATESTRING
+ qDumpUnknown(d);
+#else
+ const QDateTime &date = *reinterpret_cast<const QDateTime *>(d.data);
+ P(d, "iname", d.iname);
+ P(d, "addr", d.data);
+ P(d, "value", date.toString());
+ P(d, "type", "QDateTime");
+ P(d, "numchild", "3");
+ if (d.dumpChildren) {
+ d << ",children=[";
+ BL(d, "isNull", date.isNull());
+ I(d, "toTime_t", (long)date.toTime_t());
+ S(d, "toString", date.toString());
+ S(d, "toString_(ISO)", date.toString(Qt::ISODate));
+ S(d, "toString_(SystemLocale)", date.toString(Qt::SystemLocaleDate));
+ S(d, "toString_(Locale)", date.toString(Qt::LocaleDate));
+ S(d, "toString", date.toString());
+
+ d.beginHash();
+ P(d, "name", "toUTC");
+ P(d, "exp", "((QDateTime*)" << d.data << ")->toTimeSpec(Qt::UTC)");
+ P(d, "type", "QDateTime");
+ P(d, "numchild", "1");
+ d.endHash();
+
+ d.beginHash();
+ P(d, "name", "toLocalTime");
+ P(d, "exp", "((QDateTime*)" << d.data << ")->toTimeSpec(Qt::LocalTime)");
+ P(d, "type", "QDateTime");
+ P(d, "numchild", "1");
+ d.endHash();
+
+ d << "]";
+ }
+ d.disarm();
+#endif // ifdef QT_NO_DATESTRING
+}
+
+static void qDumpQString(QDumper &d)
+{
+ const QString &str = *reinterpret_cast<const QString *>(d.data);
+
+ // Try to provoke segfaults early to prevent the frontend
+ // from asking for unavailable child details
+ if (!str.isEmpty()) {
+ volatile ushort dummy = 0;
+ dummy += str.at(0).unicode();
+ dummy += str.at(str.size() - 1).unicode();
+ }
+
+ P(d, "iname", d.iname);
+ P(d, "addr", d.data);
+ P(d, "value", str);
+ P(d, "type", "QString");
+ P(d, "numchild", "0");
+ d.disarm();
+}
+
+static void qDumpQStringList(QDumper &d)
+{
+ const QStringList &list = *reinterpret_cast<const QStringList *>(d.data);
+ int n = list.size();
+ if (n < 0)
+ qProvokeSegFault();
+ if (n > 0) {
+ qCheckAccess(&list.front());
+ qCheckAccess(&list.back());
+ }
+
+ P(d, "iname", d.iname);
+ P(d, "addr", d.data);
+ P(d, "value", "<" << n << " items>");
+ P(d, "valuedisabled", "true");
+ P(d, "numchild", n);
+ if (d.dumpChildren) {
+ if (n > 100)
+ n = 100;
+ d << ",children=[";
+ for (int i = 0; i != n; ++i) {
+ S(d, "[" << i << "]", list[i]);
+ }
+ if (n < list.size()) {
+ d.beginHash();
+ P(d, "value", "<incomplete>");
+ P(d, "type", " ");
+ P(d, "numchild", "0");
+ d.endHash();
+ }
+ d << "]";
+ }
+ d.disarm();
+}
+
+static void qDumpQVariantHelper(const void *data, QString *value,
+ QString *exp, int *numchild)
+{
+ const QVariant &v = *reinterpret_cast<const QVariant *>(data);
+ switch (v.type()) {
+ case QVariant::Invalid:
+ *value = QLatin1String("<invalid>");
+ *numchild = 0;
+ break;
+ case QVariant::String:
+ *value = QLatin1Char('"') + v.toString() + QLatin1Char('"');
+ *numchild = 0;
+ break;
+ case QVariant::StringList:
+ *exp = QString(QLatin1String("((QVariant*)%1)->d.data.c"))
+ .arg((qulonglong)data);
+ *numchild = v.toStringList().size();
+ break;
+ case QVariant::Int:
+ *value = QString::number(v.toInt());
+ *numchild= 0;
+ break;
+ case QVariant::Double:
+ *value = QString::number(v.toDouble());
+ *numchild = 0;
+ break;
+ default:
+ // FIXME
+ //*exp = QString("qVariantValue<" << v.typeName() << ">"
+ // << "(*(QVariant*)" << data << ")");
+ break;
+ }
+}
+
+static void qDumpQVariant(QDumper &d)
+{
+ const QVariant &v = *reinterpret_cast<const QVariant *>(d.data);
+ QString value;
+ QString exp;
+ int numchild = 0;
+ qDumpQVariantHelper(d.data, &value, &exp, &numchild);
+ P(d, "iname", d.iname);
+ P(d, "addr", d.data);
+ P(d, "value", "(" << v.typeName() << ") " << qPrintable(value));
+ P(d, "type", "QVariant");
+ P(d, "numchild", 1);
+ if (d.dumpChildren) {
+ d << ",children=[";
+ d.beginHash();
+ P(d, "name", "value");
+ if (!exp.isEmpty())
+ P(d, "exp", qPrintable(exp));
+ if (!value.isEmpty())
+ P(d, "value", qPrintable(value));
+ P(d, "type", v.typeName());
+ P(d, "numchild", numchild);
+ d.endHash();
+ d << "]";
+ }
+ d.disarm();
+}
+
+static void qDumpQList(QDumper &d)
+{
+ // This uses the knowledge that QList<T> has only a single member
+ // of type union { QListData p; QListData::Data *d; };
+ const QListData &ldata = *reinterpret_cast<const QListData*>(d.data);
+ const QListData::Data *pdata = *reinterpret_cast<const QListData::Data* const*>(d.data);
+ int nn = ldata.size();
+ if (nn < 0)
+ qProvokeSegFault();
+ if (nn > 0) {
+ qCheckAccess(ldata.d->array);
+ //qCheckAccess(ldata.d->array[0]);
+ //qCheckAccess(ldata.d->array[nn - 1]);
+ }
+
+ int n = nn;
+ P(d, "iname", d.iname);
+ P(d, "value", "<" << n << " items>");
+ P(d, "valuedisabled", "true");
+ P(d, "numchild", n);
+ if (d.dumpChildren) {
+ if (n > 100)
+ n = 100;
+ d << ",children=[";
+ for (int i = 0; i != n; ++i) {
+ d.beginHash();
+ P(d, "name", "[" << i << "]");
+ // The exact condition here is:
+ // QTypeInfo<T>::isLarge || QTypeInfo<T>::isStatic
+ // but this data is not available in the compiled binary.
+ // So as first approximation only do the 'isLarge' check:
+ void *p = &(ldata.d->array[i + pdata->begin]);
+ unsigned long voidpsize = sizeof(void*);
+ P(d, "exp", "(sizeof(" << d.innertype << ")>" << voidpsize <<
+ "?(**(" << d.innertype << "**)(" << p << "))"
+ ":(*(" << d.innertype << "*)(" << p << ")))");
+ P(d, "type", d.innertype);
+ d.endHash();
+ }
+ if (n < nn) {
+ d << ",{";
+ P(d, "value", "<incomplete>");
+ d.endHash();
+ }
+ d << "]";
+ }
+ d.disarm();
+}
+
+static void qDumpQVector(QDumper &d)
+{
+ // Use 'int' as representative value. No way (and no need)
+ // to deduce proper type here.
+ const QVector<int> &vec = *reinterpret_cast<const QVector<int> *>(d.data);
+ const int nn = vec.size();
+
+ // Try to provoke segfaults early to prevent the frontend
+ // from asking for unavailable child details
+ if (nn < 0)
+ qProvokeSegFault();
+ if (nn > 0) {
+ qCheckAccess(&vec.front());
+ qCheckAccess(&vec.back());
+ }
+
+ //int innersize = 0;
+ //scanf(qDumpInBuffer, "%d", &innersize);
+
+ int n = nn;
+ P(d, "iname", d.iname);
+ P(d, "addr", d.data);
+ P(d, "value", "<" << n << " items>");
+ P(d, "valuedisabled", "true");
+ P(d, "numchild", n);
+ if (d.dumpChildren) {
+ if (n > 100)
+ n = 100;
+ d << ",children=[";
+ for (int i = 0; i != n; ++i) {
+ if (i)
+ d << ",";
+ d.beginHash();
+ P(d, "name", "[" << i << "]");
+ P(d, "exp", "(" << d.exp << ".d->array[" << i << "])");
+ P(d, "type", d.innertype);
+ d.endHash();
+ }
+ if (n < nn) {
+ d << ",{";
+ P(d, "value", "<incomplete>");
+ d.endHash();
+ }
+ d << "]";
+ }
+ d.disarm();
+}
+
+static void qDumpQHashNode(QDumper &d)
+{
+ struct NodeOS { void *next; uint k; uint v; } nodeOS; // int-key optimization, small value
+ struct NodeOL { void *next; uint k; void *v; } nodeOL; // int-key optimiatzion, large value
+ struct NodeNS { void *next; uint h; uint k; uint v; } nodeNS; // no optimization, small value
+ struct NodeNL { void *next; uint h; uint k; void *v; } nodeNL; // no optimization, large value
+ struct NodeL { void *next; uint h; void *k; void *v; } nodeL; // complex key
+
+ // offsetof(...,...) not yet in Standard C++
+ const ulong nodeOSk ( (char *)&nodeOS.k - (char *)&nodeOS );
+ const ulong nodeOSv ( (char *)&nodeOS.v - (char *)&nodeOS );
+ const ulong nodeOLk ( (char *)&nodeOL.k - (char *)&nodeOL );
+ const ulong nodeOLv ( (char *)&nodeOL.v - (char *)&nodeOL );
+ const ulong nodeNSk ( (char *)&nodeNS.k - (char *)&nodeNS );
+ const ulong nodeNSv ( (char *)&nodeNS.v - (char *)&nodeNS );
+ const ulong nodeNLk ( (char *)&nodeNL.k - (char *)&nodeNL );
+ const ulong nodeNLv ( (char *)&nodeNL.v - (char *)&nodeNL );
+ const ulong nodeLk ( (char *)&nodeL.k - (char *)&nodeL );
+ const ulong nodeLv ( (char *)&nodeL.v - (char *)&nodeL );
+
+ const QHashData *h = reinterpret_cast<const QHashData *>(d.data);
+ const char *keyType = d.templateParameters[0];
+ const char *valueType = d.templateParameters[1];
+
+ P(d, "iname", d.iname);
+ P(d, "addr", d.data);
+ P(d, "value", "");
+ P(d, "numchild", 2);
+ if (d.dumpChildren) {
+ // there is a hash specialization in cast the key are integers or shorts
+ bool isOptimizedIntKey = qstrcmp(keyType, "int") == 0
+#if defined(Q_BYTE_ORDER) && Q_BYTE_ORDER == Q_LITTLE_ENDIAN
+ || qstrcmp(keyType, "short") == 0
+ || qstrcmp(keyType, "ushort") == 0
+#endif
+ || qstrcmp(keyType, "uint") == 0;
+
+ d << ",children=[";
+ d.beginHash();
+ P(d, "name", "key");
+ P(d, "type", keyType);
+ unsigned long intsize = sizeof(int);
+ if (isOptimizedIntKey) {
+ P(d, "exp", "*(" << keyType << "*)"
+ "(((sizeof(" << valueType << ")>" << intsize << ")?"
+ << nodeOLk << ":" << nodeOSk <<
+ ")+(char*)" << h << ")");
+ } else {
+ P(d, "exp", "*(" << keyType << "*)"
+ "(((sizeof(" << keyType << ")>" << intsize << ")?"
+ << nodeLk << ":"
+ "((sizeof(" << valueType << ")>" << intsize << ")?"
+ << nodeNLk << ":" << nodeNSk << "))+(char*)" << h << ")");
+ }
+ d.endHash();
+ d.beginHash();
+ P(d, "name", "value");
+ P(d, "type", valueType);
+ if (isOptimizedIntKey) {
+ P(d, "exp", "*(" << valueType << "*)"
+ "(((sizeof(" << valueType << ")>" << intsize << ")?"
+ << nodeOLv << ":" << nodeOSv << ")+(char*)" << h << ")");
+ } else {
+ P(d, "exp", "*(" << valueType << "*)"
+ "(((sizeof(" << keyType << ")>" << intsize << ")?" << nodeLv << ":"
+ "((sizeof(" << valueType << ")>" << intsize << ")?"
+ << nodeNLv << ":" << nodeNSv << "))+(char*)" << h << ")");
+ }
+ d.endHash();
+ d << "]";
+ }
+ d.disarm();
+}
+
+static void qDumpQHash(QDumper &d)
+{
+ QHashData *h = *reinterpret_cast<QHashData *const*>(d.data);
+ const char *keyType = d.templateParameters[0];
+ const char *valueType = d.templateParameters[1];
+
+ qCheckPointer(h->fakeNext);
+ qCheckPointer(h->buckets);
+
+ int n = h->size;
+
+ if (n < 0)
+ qProvokeSegFault();
+ if (n > 0) {
+ qCheckPointer(h->fakeNext);
+ qCheckPointer(*h->buckets);
+ }
+
+ P(d, "iname", d.iname);
+ P(d, "addr", d.data);
+ P(d, "value", "<" << n << " items>");
+ P(d, "numchild", n);
+ if (d.dumpChildren) {
+ if (n > 100)
+ n = 100;
+ d << ",children=[";
+
+ QHashData::Node *node = h->firstNode();
+ QHashData::Node *end = reinterpret_cast<QHashData::Node *>(h);
+ int i = 0;
+
+ while (node != end) {
+ d.beginHash();
+ P(d, "name", "[" << i << "]");
+ P(d, "type", "QHashNode<" << keyType << "," << valueType << " >");
+ P(d, "exp", "*(QHashNode<" << keyType << "," << valueType << " >*)" << node);
+ d.endHash();
+
+ ++i;
+ node = QHashData::nextNode(node);
+ }
+ d << "]";
+ }
+ d.disarm();
+}
+
+static void qDumpQMapNode(QDumper &d)
+{
+ const QMapData *h = reinterpret_cast<const QMapData *>(d.data);
+ const char *keyType = d.templateParameters[0];
+ const char *valueType = d.templateParameters[1];
+
+ qCheckAccess(h->backward);
+ qCheckAccess(h->forward[0]);
+
+ P(d, "iname", d.iname);
+ P(d, "addr", d.data);
+ P(d, "value", "");
+ P(d, "numchild", 2);
+ if (d.dumpChildren) {
+ unsigned long voidpsize = sizeof(void*);
+ d << ",children=[";
+ d.beginHash();
+ P(d, "name", "key");
+ P(d, "type", keyType);
+ P(d, "exp", "*(" << keyType << "*)"
+ << "("
+ << 2 * voidpsize
+ << "-sizeof('QMap<" << keyType << "," << valueType << ">::Node')"
+ << "+(char*)" << h
+ << ")");
+ d.endHash();
+ d.beginHash();
+ P(d, "name", "value");
+ P(d, "type", valueType);
+ P(d, "exp", "*(" << valueType << "*)"
+ << "("
+ << "(size_t)&(('QMap<" << keyType << "," << valueType << ">::Node'*)0)->value"
+ << "+" << 2 * voidpsize
+ << "-sizeof('QMap<" << keyType << "," << valueType << ">::Node')"
+ << "+(char*)" << h
+ << ")");
+ d.endHash();
+ d << "]";
+ }
+
+ d.disarm();
+}
+
+static void qDumpQMap(QDumper &d)
+{
+ QMapData *h = *reinterpret_cast<QMapData *const*>(d.data);
+ const char *keyType = d.templateParameters[0];
+ const char *valueType = d.templateParameters[1];
+
+ int n = h->size;
+
+ if (n < 0)
+ qProvokeSegFault();
+ if (n > 0) {
+ qCheckAccess(h->backward);
+ qCheckAccess(h->forward[0]);
+ qCheckPointer(h->backward->backward);
+ qCheckPointer(h->forward[0]->backward);
+ }
+
+ P(d, "iname", d.iname);
+ P(d, "addr", d.data);
+ P(d, "value", "<" << n << " items>");
+ P(d, "numchild", n);
+ if (d.dumpChildren) {
+ if (n > 100)
+ n = 100;
+ d << ",children=[";
+
+ QMapData::Node *node = reinterpret_cast<QMapData::Node *>(h->forward[0]);
+ QMapData::Node *end = reinterpret_cast<QMapData::Node *>(h);
+ int i = 0;
+
+ while (node != end) {
+ d.beginHash();
+ P(d, "name", "[" << i << "]");
+ P(d, "type", "QMap<" << keyType << "," << valueType << ">::Node");
+ P(d, "exp", "*('QMap<" << keyType << "," << valueType << ">::Node'*)" << node);
+ d.endHash();
+
+ ++i;
+ node = node->forward[0];
+ }
+ d << "]";
+ }
+
+ d.disarm();
+}
+
+static void qDumpQSet(QDumper &d)
+{
+ // This uses the knowledge that QHash<T> has only a single member
+ // of union { QHashData *d; QHashNode<Key, T> *e; };
+ QHashData *hd = *(QHashData**)d.data;
+ QHashData::Node *node = hd->firstNode();
+
+ int n = hd->size;
+ if (n < 0)
+ qProvokeSegFault();
+ if (n > 0) {
+ qCheckAccess(node);
+ qCheckPointer(node->next);
+ }
+
+ P(d, "iname", d.iname);
+ P(d, "addr", d.data);
+ P(d, "value", "<" << n << " items>");
+ P(d, "valuedisabled", "true");
+ P(d, "numchild", 2 * n);
+ if (d.dumpChildren) {
+ if (n > 100)
+ n = 100;
+ d << ",children=[";
+ int i = 0;
+ for (int bucket = 0; bucket != hd->numBuckets; ++bucket) {
+ for (node = hd->buckets[bucket]; node->next; node = node->next) {
+ d.beginHash();
+ P(d, "name", "[" << i << "]");
+ P(d, "type", d.innertype);
+ P(d, "exp", "(('QHashNode<" << d.innertype
+ << ",QHashDummyValue>'*)"
+ << static_cast<const void*>(node) << ")->key"
+ );
+ d.endHash();
+ ++i;
+ }
+ }
+ d << "]";
+ }
+ d.disarm();
+}
+
+static void handleProtocolVersion2(QDumper & d)
+{
+ if (!d.outertype[0]) {
+ qDumpUnknown(d);
+ return;
+ }
+
+ d.setupTemplateParameters();
+ // d.outertype[0] is usally 'Q', so don't use it
+ switch (d.outertype[1]) {
+ case 'D':
+ if (qstrcmp(d.outertype, "QDateTime") == 0)
+ qDumpQDateTime(d);
+ else if (qstrcmp(d.outertype, "QDir") == 0)
+ qDumpQDir(d);
+ break;
+ case 'F':
+ if (qstrcmp(d.outertype, "QFileInfo") == 0)
+ qDumpQFileInfo(d);
+ break;
+ case 'H':
+ if (qstrcmp(d.outertype, "QHash") == 0)
+ qDumpQHash(d);
+ else if (qstrcmp(d.outertype, "QHashNode") == 0)
+ qDumpQHashNode(d);
+ break;
+ case 'L':
+ if (qstrcmp(d.outertype, "QList") == 0)
+ qDumpQList(d);
+ break;
+ case 'M':
+ if (qstrcmp(d.outertype, "QMap") == 0)
+ qDumpQMap(d);
+ else if (qstrcmp(d.outertype, "QMap::Node") == 0)
+ qDumpQMapNode(d);
+ break;
+ case 'O':
+ if (qstrcmp(d.outertype, "QObject") == 0)
+ qDumpQObject(d);
+ break;
+ case 'P':
+ if (qstrcmp(d.outertype, "QPropertyList") == 0)
+ qDumpQPropertyList(d);
+ break;
+ case 'S':
+ if (qstrcmp(d.outertype, "QSet") == 0)
+ qDumpQSet(d);
+ else if (qstrcmp(d.outertype, "QString") == 0)
+ qDumpQString(d);
+ else if (qstrcmp(d.outertype, "QStringList") == 0)
+ qDumpQStringList(d);
+ break;
+ case 'V':
+ if (qstrcmp(d.outertype, "QVariant") == 0)
+ qDumpQVariant(d);
+ else if (qstrcmp(d.outertype, "QVector") == 0)
+ qDumpQVector(d);
+ break;
+ }
+
+ if (!d.success)
+ qDumpUnknown(d);
+}
+
+} // anonymous namespace
+
+
+extern "C" Q_CORE_EXPORT void qDumpObjectData(
+ int protocolVersion,
+ int token,
+ const char *outertype,
+ const char *iname,
+ const char *exp,
+ const char *innertype,
+ const void *data,
+ bool dumpChildren)
+{
+ if (protocolVersion == 1) {
+ // used to test whether error output gets through
+ //fprintf(stderr, "using stderr, qDebug follows: %d\n", token);
+ //qDebug() << "using qDebug, stderr already used: " << token;
+ }
+
+ else if (protocolVersion == 2) {
+ QDumper d;
+ d.protocolVersion = protocolVersion;
+ d.token = token;
+ d.outertype = outertype ? outertype : "";
+ d.iname = iname ? iname : "";
+ d.exp = exp ? exp : "";
+ d.innertype = innertype ? innertype : "";
+ d.data = data ? data : "";
+ d.dumpChildren = dumpChildren;
+ handleProtocolVersion2(d);
+ }
+
+ else {
+ qDebug() << "Unsupported protocol version" << protocolVersion;
+ }
+}
+
+QT_END_NAMESPACE
+
+#endif // !Q_OS_WINCE && !QT_NO_QDUMPER
diff --git a/src/corelib/tools/qharfbuzz.cpp b/src/corelib/tools/qharfbuzz.cpp
new file mode 100644
index 0000000000..1940209827
--- /dev/null
+++ b/src/corelib/tools/qharfbuzz.cpp
@@ -0,0 +1,169 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qharfbuzz_p.h"
+
+#include "qunicodetables_p.h"
+#include "qlibrary.h"
+#include "qtextcodec.h"
+
+QT_USE_NAMESPACE
+
+extern "C" {
+
+HB_GraphemeClass HB_GetGraphemeClass(HB_UChar32 ch)
+{
+ const QUnicodeTables::Properties *prop = QUnicodeTables::properties(ch);
+ return (HB_GraphemeClass) prop->graphemeBreak;
+}
+
+HB_WordClass HB_GetWordClass(HB_UChar32 ch)
+{
+ const QUnicodeTables::Properties *prop = QUnicodeTables::properties(ch);
+ return (HB_WordClass) prop->wordBreak;
+}
+
+HB_SentenceClass HB_GetSentenceClass(HB_UChar32 ch)
+{
+ const QUnicodeTables::Properties *prop = QUnicodeTables::properties(ch);
+ return (HB_SentenceClass) prop->sentenceBreak;
+}
+
+HB_LineBreakClass HB_GetLineBreakClass(HB_UChar32 ch)
+{
+ return (HB_LineBreakClass)QUnicodeTables::lineBreakClass(ch);
+}
+
+
+void HB_GetGraphemeAndLineBreakClass(HB_UChar32 ch, HB_GraphemeClass *grapheme, HB_LineBreakClass *lineBreak)
+{
+ const QUnicodeTables::Properties *prop = QUnicodeTables::properties(ch);
+ *grapheme = (HB_GraphemeClass) prop->graphemeBreak;
+ *lineBreak = (HB_LineBreakClass) prop->line_break_class;
+}
+
+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, const char *symbol)
+{
+#ifdef QT_NO_LIBRARY
+ return 0;
+#else
+ return QLibrary::resolve(QLatin1String(library), symbol);
+#endif
+}
+
+void *HB_TextCodecForMib(int mib)
+{
+#ifndef QT_NO_TEXTCODEC
+ return QTextCodec::codecForMib(mib);
+#else
+ return 0;
+#endif
+}
+
+char *HB_TextCodec_ConvertFromUnicode(void *codec, const HB_UChar16 *unicode, hb_uint32 length, hb_uint32 *outputLength)
+{
+#ifndef QT_NO_TEXTCODEC
+ QByteArray data = reinterpret_cast<QTextCodec *>(codec)->fromUnicode((const QChar *)unicode, length);
+ // ### suboptimal
+ char *output = (char *)malloc(data.length() + 1);
+ memcpy(output, data.constData(), data.length() + 1);
+ if (outputLength)
+ *outputLength = data.length();
+ return output;
+#else
+ return 0;
+#endif
+}
+
+void HB_TextCodec_FreeResult(char *string)
+{
+ free(string);
+}
+
+} // 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_NewFace(font, tableFunc);
+}
+
+void qHBFreeFace(HB_Face face)
+{
+ HB_FreeFace(face);
+}
+
+void qGetCharAttributes(const HB_UChar16 *string, hb_uint32 stringLength,
+ const HB_ScriptItem *items, hb_uint32 numItems,
+ HB_CharAttributes *attributes)
+{
+ HB_GetCharAttributes(string, stringLength, items, numItems, attributes);
+}
+
+QT_END_NAMESPACE
diff --git a/src/corelib/tools/qharfbuzz_p.h b/src/corelib/tools/qharfbuzz_p.h
new file mode 100644
index 0000000000..eaaf0d7318
--- /dev/null
+++ b/src/corelib/tools/qharfbuzz_p.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $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.
+//
+
+#ifndef QHARFBUZZ_P_H
+#define QHARFBUZZ_P_H
+
+#include <harfbuzz-shaper.h>
+#include <QtCore/qglobal.h>
+
+QT_BEGIN_NAMESPACE
+
+// temporary forward until all the textengine code has been moved to QtCore
+Q_CORE_EXPORT void qGetCharAttributes(const HB_UChar16 *string, hb_uint32 stringLength,
+ const HB_ScriptItem *items, hb_uint32 numItems,
+ HB_CharAttributes *attributes);
+
+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_DECLARE_TYPEINFO(HB_GlyphAttributes, Q_PRIMITIVE_TYPE);
+Q_DECLARE_TYPEINFO(HB_FixedPoint, Q_PRIMITIVE_TYPE);
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/corelib/tools/qhash.cpp b/src/corelib/tools/qhash.cpp
new file mode 100644
index 0000000000..540f43da11
--- /dev/null
+++ b/src/corelib/tools/qhash.cpp
@@ -0,0 +1,1843 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qhash.h"
+
+#ifdef truncate
+#undef truncate
+#endif
+
+#include <qbitarray.h>
+#include <qstring.h>
+#include <stdlib.h>
+#ifdef QT_QHASH_DEBUG
+#include <qstring.h>
+#endif
+
+QT_BEGIN_NAMESPACE
+
+/*
+ These functions are based on Peter J. Weinberger's hash function
+ (from the Dragon Book). The constant 24 in the original function
+ was replaced with 23 to produce fewer collisions on input such as
+ "a", "aa", "aaa", "aaaa", ...
+*/
+
+static uint hash(const uchar *p, int n)
+{
+ uint h = 0;
+ uint g;
+
+ while (n--) {
+ h = (h << 4) + *p++;
+ if ((g = (h & 0xf0000000)) != 0)
+ h ^= g >> 23;
+ h &= ~g;
+ }
+ return h;
+}
+
+static uint hash(const QChar *p, int n)
+{
+ uint h = 0;
+ uint g;
+
+ while (n--) {
+ h = (h << 4) + (*p++).unicode();
+ if ((g = (h & 0xf0000000)) != 0)
+ h ^= g >> 23;
+ h &= ~g;
+ }
+ return h;
+}
+
+uint qHash(const QByteArray &key)
+{
+ return hash(reinterpret_cast<const uchar *>(key.data()), key.size());
+}
+
+uint qHash(const QString &key)
+{
+ return hash(key.unicode(), key.size());
+}
+
+uint qHash(const QStringRef &key)
+{
+ return hash(key.unicode(), key.size());
+}
+
+uint qHash(const QBitArray &bitArray)
+{
+ int m = bitArray.d.size() - 1;
+ uint result = hash(reinterpret_cast<const uchar *>(bitArray.d.data()), qMax(0, m));
+
+ // deal with the last 0 to 7 bits manually, because we can't trust that
+ // the padding is initialized to 0 in bitArray.d
+ int n = bitArray.size();
+ if (n & 0x7)
+ result = ((result << 4) + bitArray.d.at(m)) & ((1 << n) - 1);
+ return result;
+}
+
+/*
+ The prime_deltas array is a table of selected prime values, even
+ though it doesn't look like one. The primes we are using are 1,
+ 2, 5, 11, 17, 37, 67, 131, 257, ..., i.e. primes in the immediate
+ surrounding of a power of two.
+
+ The primeForNumBits() function returns the prime associated to a
+ power of two. For example, primeForNumBits(8) returns 257.
+*/
+
+static const uchar prime_deltas[] = {
+ 0, 0, 1, 3, 1, 5, 3, 3, 1, 9, 7, 5, 3, 9, 25, 3,
+ 1, 21, 3, 21, 7, 15, 9, 5, 3, 29, 15, 0, 0, 0, 0, 0
+};
+
+static inline int primeForNumBits(int numBits)
+{
+ return (1 << numBits) + prime_deltas[numBits];
+}
+
+/*
+ Returns the smallest integer n such that
+ primeForNumBits(n) >= hint.
+*/
+static int countBits(int hint)
+{
+ int numBits = 0;
+ int bits = hint;
+
+ while (bits > 1) {
+ bits >>= 1;
+ numBits++;
+ }
+
+ if (numBits >= (int)sizeof(prime_deltas)) {
+ numBits = sizeof(prime_deltas) - 1;
+ } else if (primeForNumBits(numBits) < hint) {
+ ++numBits;
+ }
+ return numBits;
+}
+
+/*
+ A QHash has initially around pow(2, MinNumBits) buckets. For
+ example, if MinNumBits is 4, it has 17 buckets.
+*/
+const int MinNumBits = 4;
+
+QHashData QHashData::shared_null = {
+ 0, 0, Q_BASIC_ATOMIC_INITIALIZER(1), 0, 0, MinNumBits, 0, 0, true
+};
+
+void *QHashData::allocateNode()
+{
+ return qMalloc(nodeSize);
+}
+
+void QHashData::freeNode(void *node)
+{
+ qFree(node);
+}
+
+QHashData *QHashData::detach_helper(void (*node_duplicate)(Node *, void *), int nodeSize)
+{
+ union {
+ QHashData *d;
+ Node *e;
+ };
+ d = new QHashData;
+ d->fakeNext = 0;
+ d->buckets = 0;
+ d->ref = 1;
+ d->size = size;
+ d->nodeSize = nodeSize;
+ d->userNumBits = userNumBits;
+ d->numBits = numBits;
+ d->numBuckets = numBuckets;
+ d->sharable = true;
+
+ if (numBuckets) {
+ d->buckets = new Node *[numBuckets];
+ Node *this_e = reinterpret_cast<Node *>(this);
+ for (int i = 0; i < numBuckets; ++i) {
+ Node **nextNode = &d->buckets[i];
+ Node *oldNode = buckets[i];
+ while (oldNode != this_e) {
+ Node *dup = static_cast<Node *>(allocateNode());
+ node_duplicate(oldNode, dup);
+ dup->h = oldNode->h;
+ *nextNode = dup;
+ nextNode = &dup->next;
+ oldNode = oldNode->next;
+ }
+ *nextNode = e;
+ }
+ }
+ return d;
+}
+
+QHashData::Node *QHashData::nextNode(Node *node)
+{
+ union {
+ Node *next;
+ Node *e;
+ QHashData *d;
+ };
+ next = node->next;
+ Q_ASSERT_X(next, "QHash", "Iterating beyond end()");
+ if (next->next)
+ return next;
+
+ int start = (node->h % d->numBuckets) + 1;
+ Node **bucket = d->buckets + start;
+ int n = d->numBuckets - start;
+ while (n--) {
+ if (*bucket != e)
+ return *bucket;
+ ++bucket;
+ }
+ return e;
+}
+
+QHashData::Node *QHashData::previousNode(Node *node)
+{
+ union {
+ Node *e;
+ QHashData *d;
+ };
+
+ e = node;
+ while (e->next)
+ e = e->next;
+
+ int start;
+ if (node == e)
+ start = d->numBuckets - 1;
+ else
+ start = node->h % d->numBuckets;
+
+ Node *sentinel = node;
+ Node **bucket = d->buckets + start;
+ while (start >= 0) {
+ if (*bucket != sentinel) {
+ Node *prev = *bucket;
+ while (prev->next != sentinel)
+ prev = prev->next;
+ return prev;
+ }
+
+ sentinel = e;
+ --bucket;
+ --start;
+ }
+ Q_ASSERT_X(start >= 0, "QHash", "Iterating backward beyond begin()");
+ return e;
+}
+
+/*
+ If hint is negative, -hint gives the approximate number of
+ buckets that should be used for the hash table. If hint is
+ nonnegative, (1 << hint) gives the approximate number
+ of buckets that should be used.
+*/
+void QHashData::rehash(int hint)
+{
+ if (hint < 0) {
+ hint = countBits(-hint);
+ if (hint < MinNumBits)
+ hint = MinNumBits;
+ userNumBits = hint;
+ while (primeForNumBits(hint) < (size >> 1))
+ ++hint;
+ } else if (hint < MinNumBits) {
+ hint = MinNumBits;
+ }
+
+ if (numBits != hint) {
+ Node *e = reinterpret_cast<Node *>(this);
+ Node **oldBuckets = buckets;
+ int oldNumBuckets = numBuckets;
+
+ numBits = hint;
+ numBuckets = primeForNumBits(hint);
+ buckets = new Node *[numBuckets];
+ for (int i = 0; i < numBuckets; ++i)
+ buckets[i] = e;
+
+ for (int i = 0; i < oldNumBuckets; ++i) {
+ Node *firstNode = oldBuckets[i];
+ while (firstNode != e) {
+ uint h = firstNode->h;
+ Node *lastNode = firstNode;
+ while (lastNode->next != e && lastNode->next->h == h)
+ lastNode = lastNode->next;
+
+ Node *afterLastNode = lastNode->next;
+ Node **beforeFirstNode = &buckets[h % numBuckets];
+ while (*beforeFirstNode != e)
+ beforeFirstNode = &(*beforeFirstNode)->next;
+ lastNode->next = *beforeFirstNode;
+ *beforeFirstNode = firstNode;
+ firstNode = afterLastNode;
+ }
+ }
+ delete [] oldBuckets;
+ }
+}
+
+void QHashData::destroyAndFree()
+{
+ delete [] buckets;
+ delete this;
+}
+
+#ifdef QT_QHASH_DEBUG
+
+void QHashData::dump()
+{
+ qDebug("Hash data (ref = %d, size = %d, nodeSize = %d, userNumBits = %d, numBits = %d, numBuckets = %d)",
+ int(ref), size, nodeSize, userNumBits, numBits,
+ numBuckets);
+ qDebug(" %p (fakeNode = %p)", this, fakeNext);
+ for (int i = 0; i < numBuckets; ++i) {
+ QString line;
+ Node *n = buckets[i];
+ if (n != reinterpret_cast<Node *>(this)) {
+ line.sprintf("%d:", i);
+ while (n != reinterpret_cast<Node *>(this)) {
+ line += QString().sprintf(" -> [%p]", n);
+ if (!n) {
+ line += " (CORRUPT)";
+ break;
+ }
+ n = n->next;
+ }
+ qDebug(qPrintable(line));
+ }
+ }
+}
+
+void QHashData::checkSanity()
+{
+ if (fakeNext)
+ qFatal("Fake next isn't 0");
+
+ for (int i = 0; i < numBuckets; ++i) {
+ Node *n = buckets[i];
+ Node *p = n;
+ if (!n)
+ qFatal("%d: Bucket entry is 0", i);
+ if (n != reinterpret_cast<Node *>(this)) {
+ while (n != reinterpret_cast<Node *>(this)) {
+ if (!n->next)
+ qFatal("%d: Next of %p is 0, should be %p", i, n, this);
+ n = n->next;
+ }
+ }
+ }
+}
+#endif
+
+/*!
+ \class QHash
+ \brief The QHash class is a template class that provides a hash-table-based dictionary.
+
+ \ingroup tools
+ \ingroup shared
+ \mainclass
+ \reentrant
+
+ QHash\<Key, T\> is one of Qt's generic \l{container classes}. It
+ stores (key, value) pairs and provides very fast lookup of the
+ value associated with a key.
+
+ QHash provides very similar functionality to QMap. The
+ differences are:
+
+ \list
+ \i QHash provides faster lookups than QMap. (See \l{Algorithmic
+ Complexity} for details.)
+ \i When iterating over a QMap, the items are always sorted by
+ key. With QHash, the items are arbitrarily ordered.
+ \i The key type of a QMap must provide operator<(). The key
+ type of a QHash must provide operator==() and a global
+ \l{qHash()}{qHash}(Key) function.
+ \endlist
+
+ Here's an example QHash with QString keys and \c int values:
+ \snippet doc/src/snippets/code/src_corelib_tools_qhash.cpp 0
+
+ To insert a (key, value) pair into the hash, you can use operator[]():
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qhash.cpp 1
+
+ This inserts the following three (key, value) pairs into the
+ QHash: ("one", 1), ("three", 3), and ("seven", 7). Another way to
+ insert items into the hash is to use insert():
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qhash.cpp 2
+
+ To look up a value, use operator[]() or value():
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qhash.cpp 3
+
+ If there is no item with the specified key in the hash, these
+ functions return a \l{default-constructed value}.
+
+ If you want to check whether the hash contains a particular key,
+ use contains():
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qhash.cpp 4
+
+ There is also a value() overload that uses its second argument as
+ a default value if there is no item with the specified key:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qhash.cpp 5
+
+ In general, we recommend that you use contains() and value()
+ rather than operator[]() for looking up a key in a hash. The
+ reason is that operator[]() silently inserts an item into the
+ hash if no item exists with the same key (unless the hash is
+ const). For example, the following code snippet will create 1000
+ items in memory:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qhash.cpp 6
+
+ To avoid this problem, replace \c hash[i] with \c hash.value(i)
+ in the code above.
+
+ If you want to navigate through all the (key, value) pairs stored
+ in a QHash, you can use an iterator. QHash provides both
+ \l{Java-style iterators} (QHashIterator and QMutableHashIterator)
+ and \l{STL-style iterators} (QHash::const_iterator and
+ QHash::iterator). Here's how to iterate over a QHash<QString,
+ int> using a Java-style iterator:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qhash.cpp 7
+
+ Here's the same code, but using an STL-style iterator:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qhash.cpp 8
+
+ QHash is unordered, so an iterator's sequence cannot be assumed
+ to be predictable. If ordering by key is required, use a QMap.
+
+ Normally, a QHash allows only one value per key. If you call
+ insert() with a key that already exists in the QHash, the
+ previous value is erased. For example:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qhash.cpp 9
+
+ However, you can store multiple values per key by using
+ insertMulti() instead of insert() (or using the convenience
+ subclass QMultiHash). If you want to retrieve all
+ the values for a single key, you can use values(const Key &key),
+ which returns a QList<T>:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qhash.cpp 10
+
+ The items that share the same key are available from most
+ recently to least recently inserted. A more efficient approach is
+ to call find() to get the iterator for the first item with a key
+ and iterate from there:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qhash.cpp 11
+
+ If you only need to extract the values from a hash (not the keys),
+ you can also use \l{foreach}:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qhash.cpp 12
+
+ Items can be removed from the hash in several ways. One way is to
+ call remove(); this will remove any item with the given key.
+ Another way is to use QMutableHashIterator::remove(). In addition,
+ you can clear the entire hash using clear().
+
+ QHash's key and value data types must be \l{assignable data
+ types}. You cannot, for example, store a QWidget as a value;
+ instead, store a QWidget *. In addition, QHash's key type must
+ provide operator==(), and there must also be a global qHash()
+ function that returns a hash value for an argument of the key's
+ type.
+
+ Here's a list of the C++ and Qt types that can serve as keys in a
+ QHash: any integer type (char, unsigned long, etc.), any pointer
+ type, QChar, QString, and QByteArray. For all of these, the \c
+ <QHash> header defines a qHash() function that computes an
+ adequate hash value. If you want to use other types as the key,
+ make sure that you provide operator==() and a qHash()
+ implementation.
+
+ Example:
+ \snippet doc/src/snippets/code/src_corelib_tools_qhash.cpp 13
+
+ The qHash() function computes a numeric value based on a key. It
+ can use any algorithm imaginable, as long as it always returns
+ the same value if given the same argument. In other words, if
+ \c{e1 == e2}, then \c{qHash(e1) == qHash(e2)} must hold as well.
+ However, to obtain good performance, the qHash() function should
+ attempt to return different hash values for different keys to the
+ largest extent possible.
+
+ In the example above, we've relied on Qt's global qHash(const
+ QString &) to give us a hash value for the employee's name, and
+ XOR'ed this with the day they were born to help produce unique
+ hashes for people with the same name.
+
+ Internally, QHash uses a hash table to perform lookups. Unlike Qt
+ 3's \c QDict class, which needed to be initialized with a prime
+ number, QHash's hash table automatically grows and shrinks to
+ provide fast lookups without wasting too much memory. You can
+ still control the size of the hash table by calling reserve() if
+ you already know approximately how many items the QHash will
+ contain, but this isn't necessary to obtain good performance. You
+ can also call capacity() to retrieve the hash table's size.
+
+ \sa QHashIterator, QMutableHashIterator, QMap, QSet
+*/
+
+/*! \fn QHash::QHash()
+
+ Constructs an empty hash.
+
+ \sa clear()
+*/
+
+/*! \fn QHash::QHash(const QHash<Key, T> &other)
+
+ Constructs a copy of \a other.
+
+ This operation occurs in \l{constant time}, because QHash is
+ \l{implicitly shared}. This makes returning a QHash from a
+ function very fast. If a shared instance is modified, it will be
+ copied (copy-on-write), and this takes \l{linear time}.
+
+ \sa operator=()
+*/
+
+/*! \fn QHash::~QHash()
+
+ Destroys the hash. References to the values in the hash and all
+ iterators of this hash become invalid.
+*/
+
+/*! \fn QHash<Key, T> &QHash::operator=(const QHash<Key, T> &other)
+
+ Assigns \a other to this hash and returns a reference to this hash.
+*/
+
+/*! \fn bool QHash::operator==(const QHash<Key, T> &other) const
+
+ Returns true if \a other is equal to this hash; otherwise returns
+ false.
+
+ Two hashes are considered equal if they contain the same (key,
+ value) pairs.
+
+ This function requires the value type to implement \c operator==().
+
+ \sa operator!=()
+*/
+
+/*! \fn bool QHash::operator!=(const QHash<Key, T> &other) const
+
+ Returns true if \a other is not equal to this hash; otherwise
+ returns false.
+
+ Two hashes are considered equal if they contain the same (key,
+ value) pairs.
+
+ This function requires the value type to implement \c operator==().
+
+ \sa operator==()
+*/
+
+/*! \fn int QHash::size() const
+
+ Returns the number of items in the hash.
+
+ \sa isEmpty(), count()
+*/
+
+/*! \fn bool QHash::isEmpty() const
+
+ Returns true if the hash contains no items; otherwise returns
+ false.
+
+ \sa size()
+*/
+
+/*! \fn int QHash::capacity() const
+
+ Returns the number of buckets in the QHash's internal hash table.
+
+ The sole purpose of this function is to provide a means of fine
+ tuning QHash's memory usage. In general, you will rarely ever
+ need to call this function. If you want to know how many items are
+ in the hash, call size().
+
+ \sa reserve(), squeeze()
+*/
+
+/*! \fn void QHash::reserve(int size)
+
+ Ensures that the QHash's internal hash table consists of at least
+ \a size buckets.
+
+ This function is useful for code that needs to build a huge hash
+ and wants to avoid repeated reallocation. For example:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qhash.cpp 14
+
+ Ideally, \a size should be slightly more than the maximum number
+ of items expected in the hash. \a size doesn't have to be prime,
+ because QHash will use a prime number internally anyway. If \a size
+ is an underestimate, the worst that will happen is that the QHash
+ will be a bit slower.
+
+ In general, you will rarely ever need to call this function.
+ QHash's internal hash table automatically shrinks or grows to
+ provide good performance without wasting too much memory.
+
+ \sa squeeze(), capacity()
+*/
+
+/*! \fn void QHash::squeeze()
+
+ Reduces the size of the QHash's internal hash table to save
+ memory.
+
+ The sole purpose of this function is to provide a means of fine
+ tuning QHash's memory usage. In general, you will rarely ever
+ need to call this function.
+
+ \sa reserve(), capacity()
+*/
+
+/*! \fn void QHash::detach()
+
+ \internal
+
+ Detaches this hash from any other hashes with which it may share
+ data.
+
+ \sa isDetached()
+*/
+
+/*! \fn bool QHash::isDetached() const
+
+ \internal
+
+ Returns true if the hash's internal data isn't shared with any
+ other hash object; otherwise returns false.
+
+ \sa detach()
+*/
+
+/*! \fn void QHash::setSharable(bool sharable)
+
+ \internal
+*/
+
+/*! \fn void QHash::clear()
+
+ Removes all items from the hash.
+
+ \sa remove()
+*/
+
+/*! \fn int QHash::remove(const Key &key)
+
+ Removes all the items that have the \a key from the hash.
+ Returns the number of items removed which is usually 1 but will
+ be 0 if the key isn't in the hash, or greater than 1 if
+ insertMulti() has been used with the \a key.
+
+ \sa clear(), take(), QMultiHash::remove()
+*/
+
+/*! \fn T QHash::take(const Key &key)
+
+ Removes the item with the \a key from the hash and returns
+ the value associated with it.
+
+ If the item does not exist in the hash, the function simply
+ returns a \l{default-constructed value}. If there are multiple
+ items for \a key in the hash, only the most recently inserted one
+ is removed.
+
+ If you don't use the return value, remove() is more efficient.
+
+ \sa remove()
+*/
+
+/*! \fn bool QHash::contains(const Key &key) const
+
+ Returns true if the hash contains an item with the \a key;
+ otherwise returns false.
+
+ \sa count(), QMultiHash::contains()
+*/
+
+/*! \fn const T QHash::value(const Key &key) const
+
+ Returns the value associated with the \a key.
+
+ If the hash contains no item with the \a key, the function
+ returns a \l{default-constructed value}. If there are multiple
+ items for the \a key in the hash, the value of the most recently
+ inserted one is returned.
+
+ \sa key(), values(), contains(), operator[]()
+*/
+
+/*! \fn const T QHash::value(const Key &key, const T &defaultValue) const
+
+ \overload
+
+ If the hash contains no item with the given \a key, the function returns
+ \a defaultValue.
+*/
+
+/*! \fn T &QHash::operator[](const Key &key)
+
+ Returns the value associated with the \a key as a modifiable
+ reference.
+
+ If the hash contains no item with the \a key, the function inserts
+ a \l{default-constructed value} into the hash with the \a key, and
+ returns a reference to it. If the hash contains multiple items
+ with the \a key, this function returns a reference to the most
+ recently inserted value.
+
+ \sa insert(), value()
+*/
+
+/*! \fn const T QHash::operator[](const Key &key) const
+
+ \overload
+
+ Same as value().
+*/
+
+/*! \fn QList<Key> QHash::uniqueKeys() const
+ \since 4.2
+
+ Returns a list containing all the keys in the map. Keys that occur multiple
+ times in the map (because items were inserted with insertMulti(), or
+ unite() was used) occur only once in the returned list.
+
+ \sa keys(), values()
+*/
+
+/*! \fn QList<Key> QHash::keys() const
+
+ Returns a list containing all the keys in the hash, in an
+ arbitrary order. Keys that occur multiple times in the hash
+ (because items were inserted with insertMulti(), or unite() was
+ used) also occur multiple times in the list.
+
+ To obtain a list of unique keys, where each key from the map only
+ occurs once, use uniqueKeys().
+
+ The order is guaranteed to be the same as that used by values().
+
+ \sa uniqueKeys(), values(), key()
+*/
+
+/*! \fn QList<Key> QHash::keys(const T &value) const
+
+ \overload
+
+ Returns a list containing all the keys associated with value \a
+ value, in an arbitrary order.
+
+ This function can be slow (\l{linear time}), because QHash's
+ internal data structure is optimized for fast lookup by key, not
+ by value.
+*/
+
+/*! \fn QList<T> QHash::values() const
+
+ Returns a list containing all the values in the hash, in an
+ arbitrary order. If a key is associated multiple values, all of
+ its values will be in the list, and not just the most recently
+ inserted one.
+
+ The order is guaranteed to be the same as that used by keys().
+
+ \sa keys(), value()
+*/
+
+/*! \fn QList<T> QHash::values(const Key &key) const
+
+ \overload
+
+ Returns a list of all the values associated with the \a key,
+ from the most recently inserted to the least recently inserted.
+
+ \sa count(), insertMulti()
+*/
+
+/*! \fn Key QHash::key(const T &value) const
+
+ Returns the first key mapped to \a value.
+
+ If the hash contains no item with the \a value, the function
+ returns a \link {default-constructed value} default-constructed
+ key \endlink.
+
+ This function can be slow (\l{linear time}), because QHash's
+ internal data structure is optimized for fast lookup by key, not
+ by value.
+
+ \sa value(), keys()
+*/
+
+/*!
+ \fn Key QHash::key(const T &value, const Key &defaultKey) const
+ \since 4.3
+ \overload
+
+ Returns the first key mapped to \a value, or \a defaultKey if the
+ hash contains no item mapped to \a value.
+
+ This function can be slow (\l{linear time}), because QHash's
+ internal data structure is optimized for fast lookup by key, not
+ by value.
+*/
+
+/*! \fn int QHash::count(const Key &key) const
+
+ Returns the number of items associated with the \a key.
+
+ \sa contains(), insertMulti()
+*/
+
+/*! \fn int QHash::count() const
+
+ \overload
+
+ Same as size().
+*/
+
+/*! \fn QHash::iterator QHash::begin()
+
+ Returns an \l{STL-style iterator} pointing to the first item in
+ the hash.
+
+ \sa constBegin(), end()
+*/
+
+/*! \fn QHash::const_iterator QHash::begin() const
+
+ \overload
+*/
+
+/*! \fn QHash::const_iterator QHash::constBegin() const
+
+ Returns a const \l{STL-style iterator} pointing to the first item
+ in the hash.
+
+ \sa begin(), constEnd()
+*/
+
+/*! \fn QHash::iterator QHash::end()
+
+ Returns an \l{STL-style iterator} pointing to the imaginary item
+ after the last item in the hash.
+
+ \sa begin(), constEnd()
+*/
+
+/*! \fn QHash::const_iterator QHash::end() const
+
+ \overload
+*/
+
+/*! \fn QHash::const_iterator QHash::constEnd() const
+
+ Returns a const \l{STL-style iterator} pointing to the imaginary
+ item after the last item in the hash.
+
+ \sa constBegin(), end()
+*/
+
+/*! \fn QHash::iterator QHash::erase(iterator pos)
+
+ Removes the (key, value) pair associated with the iterator \a pos
+ from the hash, and returns an iterator to the next item in the
+ hash.
+
+ Unlike remove() and take(), this function never causes QHash to
+ rehash its internal data structure. This means that it can safely
+ be called while iterating, and won't affect the order of items in
+ the hash. For example:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qhash.cpp 15
+
+ \sa remove(), take(), find()
+*/
+
+/*! \fn QHash::iterator QHash::find(const Key &key)
+
+ Returns an iterator pointing to the item with the \a key in the
+ hash.
+
+ If the hash contains no item with the \a key, the function
+ returns end().
+
+ If the hash contains multiple items with the \a key, this
+ function returns an iterator that points to the most recently
+ inserted value. The other values are accessible by incrementing
+ the iterator. For example, here's some code that iterates over all
+ the items with the same key:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qhash.cpp 16
+
+ \sa value(), values(), QMultiHash::find()
+*/
+
+/*! \fn QHash::const_iterator QHash::find(const Key &key) const
+
+ \overload
+*/
+
+/*! \fn QHash::iterator QHash::constFind(const Key &key) const
+ \since 4.1
+
+ Returns an iterator pointing to the item with the \a key in the
+ hash.
+
+ If the hash contains no item with the \a key, the function
+ returns constEnd().
+
+ \sa find(), QMultiHash::constFind()
+*/
+
+/*! \fn QHash::iterator QHash::insert(const Key &key, const T &value)
+
+ Inserts a new item with the \a key and a value of \a value.
+
+ If there is already an item with the \a key, that item's value
+ is replaced with \a value.
+
+ If there are multiple items with the \a key, the most
+ recently inserted item's value is replaced with \a value.
+
+ \sa insertMulti()
+*/
+
+/*! \fn QHash::iterator QHash::insertMulti(const Key &key, const T &value)
+
+ Inserts a new item with the \a key and a value of \a value.
+
+ If there is already an item with the same key in the hash, this
+ function will simply create a new one. (This behavior is
+ different from insert(), which overwrites the value of an
+ existing item.)
+
+ \sa insert(), values()
+*/
+
+/*! \fn QHash<Key, T> &QHash::unite(const QHash<Key, T> &other)
+
+ Inserts all the items in the \a other hash into this hash. If a
+ key is common to both hashes, the resulting hash will contain the
+ key multiple times.
+
+ \sa insertMulti()
+*/
+
+/*! \fn bool QHash::empty() const
+
+ This function is provided for STL compatibility. It is equivalent
+ to isEmpty(), returning true if the hash is empty; otherwise
+ returns false.
+*/
+
+/*! \typedef QHash::ConstIterator
+
+ Qt-style synonym for QHash::const_iterator.
+*/
+
+/*! \typedef QHash::Iterator
+
+ Qt-style synonym for QHash::iterator.
+*/
+
+/*! \typedef QHash::difference_type
+
+ Typedef for ptrdiff_t. Provided for STL compatibility.
+*/
+
+/*! \typedef QHash::key_type
+
+ Typedef for Key. Provided for STL compatibility.
+*/
+
+/*! \typedef QHash::mapped_type
+
+ Typedef for T. Provided for STL compatibility.
+*/
+
+/*! \typedef QHash::size_type
+
+ Typedef for int. Provided for STL compatibility.
+*/
+
+/*! \typedef QHash::iterator::difference_type
+ \internal
+*/
+
+/*! \typedef QHash::iterator::iterator_category
+ \internal
+*/
+
+/*! \typedef QHash::iterator::pointer
+ \internal
+*/
+
+/*! \typedef QHash::iterator::reference
+ \internal
+*/
+
+/*! \typedef QHash::iterator::value_type
+ \internal
+*/
+
+/*! \typedef QHash::const_iterator::difference_type
+ \internal
+*/
+
+/*! \typedef QHash::const_iterator::iterator_category
+ \internal
+*/
+
+/*! \typedef QHash::const_iterator::pointer
+ \internal
+*/
+
+/*! \typedef QHash::const_iterator::reference
+ \internal
+*/
+
+/*! \typedef QHash::const_iterator::value_type
+ \internal
+*/
+
+/*! \class QHash::iterator
+ \brief The QHash::iterator class provides an STL-style non-const iterator for QHash and QMultiHash.
+
+ QHash features both \l{STL-style iterators} and \l{Java-style
+ iterators}. The STL-style iterators are more low-level and more
+ cumbersome to use; on the other hand, they are slightly faster
+ and, for developers who already know STL, have the advantage of
+ familiarity.
+
+ QHash\<Key, T\>::iterator allows you to iterate over a QHash (or
+ QMultiHash) and to modify the value (but not the key) associated
+ with a particular key. If you want to iterate over a const QHash,
+ you should use QHash::const_iterator. It is generally good
+ practice to use QHash::const_iterator on a non-const QHash as
+ well, unless you need to change the QHash through the iterator.
+ Const iterators are slightly faster, and can improve code
+ readability.
+
+ The default QHash::iterator constructor creates an uninitialized
+ iterator. You must initialize it using a QHash function like
+ QHash::begin(), QHash::end(), or QHash::find() before you can
+ start iterating. Here's a typical loop that prints all the (key,
+ value) pairs stored in a hash:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qhash.cpp 17
+
+ Unlike QMap, which orders its items by key, QHash stores its
+ items in an arbitrary order. The only guarantee is that items that
+ share the same key (because they were inserted using
+ QHash::insertMulti()) will appear consecutively, from the most
+ recently to the least recently inserted value.
+
+ Let's see a few examples of things we can do with a
+ QHash::iterator that we cannot do with a QHash::const_iterator.
+ Here's an example that increments every value stored in the QHash
+ by 2:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qhash.cpp 18
+
+ Here's an example that removes all the items whose key is a
+ string that starts with an underscore character:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qhash.cpp 19
+
+ The call to QHash::erase() removes the item pointed to by the
+ iterator from the hash, and returns an iterator to the next item.
+ Here's another way of removing an item while iterating:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qhash.cpp 20
+
+ It might be tempting to write code like this:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qhash.cpp 21
+
+ However, this will potentially crash in \c{++i}, because \c i is
+ a dangling iterator after the call to erase().
+
+ Multiple iterators can be used on the same hash. However, be
+ aware that any modification performed directly on the QHash has
+ the potential of dramatically changing the order in which the
+ items are stored in the hash, as they might cause QHash to rehash
+ its internal data structure. There is one notable exception:
+ QHash::erase(). This function can safely be called while
+ iterating, and won't affect the order of items in the hash. If you
+ need to keep iterators over a long period of time, we recommend
+ that you use QMap rather than QHash.
+
+ \sa QHash::const_iterator, QMutableHashIterator
+*/
+
+/*! \fn QHash::iterator::operator Node *() const
+
+ \internal
+*/
+
+/*! \fn QHash::iterator::iterator()
+
+ Constructs an uninitialized iterator.
+
+ Functions like key(), value(), and operator++() must not be
+ called on an uninitialized iterator. Use operator=() to assign a
+ value to it before using it.
+
+ \sa QHash::begin() QHash::end()
+*/
+
+/*! \fn QHash::iterator::iterator(void *node)
+
+ \internal
+*/
+
+/*! \fn const Key &QHash::iterator::key() const
+
+ Returns the current item's key as a const reference.
+
+ There is no direct way of changing an item's key through an
+ iterator, although it can be done by calling QHash::erase()
+ followed by QHash::insert() or QHash::insertMulti().
+
+ \sa value()
+*/
+
+/*! \fn T &QHash::iterator::value() const
+
+ Returns a modifiable reference to the current item's value.
+
+ You can change the value of an item by using value() on
+ the left side of an assignment, for example:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qhash.cpp 22
+
+ \sa key(), operator*()
+*/
+
+/*! \fn T &QHash::iterator::operator*() const
+
+ Returns a modifiable reference to the current item's value.
+
+ Same as value().
+
+ \sa key()
+*/
+
+/*! \fn T *QHash::iterator::operator->() const
+
+ Returns a pointer to the current item's value.
+
+ \sa value()
+*/
+
+/*!
+ \fn bool QHash::iterator::operator==(const iterator &other) const
+ \fn bool QHash::iterator::operator==(const const_iterator &other) const
+
+ Returns true if \a other points to the same item as this
+ iterator; otherwise returns false.
+
+ \sa operator!=()
+*/
+
+/*!
+ \fn bool QHash::iterator::operator!=(const iterator &other) const
+ \fn bool QHash::iterator::operator!=(const const_iterator &other) const
+
+ Returns true if \a other points to a different item than this
+ iterator; otherwise returns false.
+
+ \sa operator==()
+*/
+
+/*!
+ \fn QHash::iterator &QHash::iterator::operator++()
+
+ The prefix ++ operator (\c{++i}) advances the iterator to the
+ next item in the hash and returns an iterator to the new current
+ item.
+
+ Calling this function on QHash::end() leads to undefined results.
+
+ \sa operator--()
+*/
+
+/*! \fn QHash::iterator QHash::iterator::operator++(int)
+
+ \overload
+
+ The postfix ++ operator (\c{i++}) advances the iterator to the
+ next item in the hash and returns an iterator to the previously
+ current item.
+*/
+
+/*!
+ \fn QHash::iterator &QHash::iterator::operator--()
+
+ The prefix -- operator (\c{--i}) makes the preceding item
+ current and returns an iterator pointing to the new current item.
+
+ Calling this function on QHash::begin() leads to undefined
+ results.
+
+ \sa operator++()
+*/
+
+/*!
+ \fn QHash::iterator QHash::iterator::operator--(int)
+
+ \overload
+
+ The postfix -- operator (\c{i--}) makes the preceding item
+ current and returns an iterator pointing to the previously
+ current item.
+*/
+
+/*! \fn QHash::iterator QHash::iterator::operator+(int j) const
+
+ Returns an iterator to the item at \a j positions forward from
+ this iterator. (If \a j is negative, the iterator goes backward.)
+
+ This operation can be slow for large \a j values.
+
+ \sa operator-()
+
+*/
+
+/*! \fn QHash::iterator QHash::iterator::operator-(int j) const
+
+ Returns an iterator to the item at \a j positions backward from
+ this iterator. (If \a j is negative, the iterator goes forward.)
+
+ This operation can be slow for large \a j values.
+
+ \sa operator+()
+*/
+
+/*! \fn QHash::iterator &QHash::iterator::operator+=(int j)
+
+ Advances the iterator by \a j items. (If \a j is negative, the
+ iterator goes backward.)
+
+ \sa operator-=(), operator+()
+*/
+
+/*! \fn QHash::iterator &QHash::iterator::operator-=(int j)
+
+ Makes the iterator go back by \a j items. (If \a j is negative,
+ the iterator goes forward.)
+
+ \sa operator+=(), operator-()
+*/
+
+/*! \class QHash::const_iterator
+ \brief The QHash::const_iterator class provides an STL-style const iterator for QHash and QMultiHash.
+
+ QHash features both \l{STL-style iterators} and \l{Java-style
+ iterators}. The STL-style iterators are more low-level and more
+ cumbersome to use; on the other hand, they are slightly faster
+ and, for developers who already know STL, have the advantage of
+ familiarity.
+
+ QHash\<Key, T\>::const_iterator allows you to iterate over a
+ QHash (or a QMultiHash). If you want to modify the QHash as you
+ iterate over it, you must use QHash::iterator instead. It is
+ generally good practice to use QHash::const_iterator on a
+ non-const QHash as well, unless you need to change the QHash
+ through the iterator. Const iterators are slightly faster, and
+ can improve code readability.
+
+ The default QHash::const_iterator constructor creates an
+ uninitialized iterator. You must initialize it using a QHash
+ function like QHash::constBegin(), QHash::constEnd(), or
+ QHash::find() before you can start iterating. Here's a typical
+ loop that prints all the (key, value) pairs stored in a hash:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qhash.cpp 23
+
+ Unlike QMap, which orders its items by key, QHash stores its
+ items in an arbitrary order. The only guarantee is that items that
+ share the same key (because they were inserted using
+ QHash::insertMulti()) will appear consecutively, from the most
+ recently to the least recently inserted value.
+
+ Multiple iterators can be used on the same hash. However, be aware
+ that any modification performed directly on the QHash has the
+ potential of dramatically changing the order in which the items
+ are stored in the hash, as they might cause QHash to rehash its
+ internal data structure. If you need to keep iterators over a long
+ period of time, we recommend that you use QMap rather than QHash.
+
+ \sa QHash::iterator, QHashIterator
+*/
+
+/*! \fn QHash::const_iterator::operator Node *() const
+
+ \internal
+*/
+
+/*! \fn QHash::const_iterator::const_iterator()
+
+ Constructs an uninitialized iterator.
+
+ Functions like key(), value(), and operator++() must not be
+ called on an uninitialized iterator. Use operator=() to assign a
+ value to it before using it.
+
+ \sa QHash::constBegin() QHash::constEnd()
+*/
+
+/*! \fn QHash::const_iterator::const_iterator(void *node)
+
+ \internal
+*/
+
+/*! \fn QHash::const_iterator::const_iterator(const iterator &other)
+
+ Constructs a copy of \a other.
+*/
+
+/*! \fn const Key &QHash::const_iterator::key() const
+
+ Returns the current item's key.
+
+ \sa value()
+*/
+
+/*! \fn const T &QHash::const_iterator::value() const
+
+ Returns the current item's value.
+
+ \sa key(), operator*()
+*/
+
+/*! \fn const T &QHash::const_iterator::operator*() const
+
+ Returns the current item's value.
+
+ Same as value().
+
+ \sa key()
+*/
+
+/*! \fn const T *QHash::const_iterator::operator->() const
+
+ Returns a pointer to the current item's value.
+
+ \sa value()
+*/
+
+/*! \fn bool QHash::const_iterator::operator==(const const_iterator &other) const
+
+ Returns true if \a other points to the same item as this
+ iterator; otherwise returns false.
+
+ \sa operator!=()
+*/
+
+/*! \fn bool QHash::const_iterator::operator!=(const const_iterator &other) const
+
+ Returns true if \a other points to a different item than this
+ iterator; otherwise returns false.
+
+ \sa operator==()
+*/
+
+/*!
+ \fn QHash::const_iterator &QHash::const_iterator::operator++()
+
+ The prefix ++ operator (\c{++i}) advances the iterator to the
+ next item in the hash and returns an iterator to the new current
+ item.
+
+ Calling this function on QHash::end() leads to undefined results.
+
+ \sa operator--()
+*/
+
+/*! \fn QHash::const_iterator QHash::const_iterator::operator++(int)
+
+ \overload
+
+ The postfix ++ operator (\c{i++}) advances the iterator to the
+ next item in the hash and returns an iterator to the previously
+ current item.
+*/
+
+/*! \fn QHash::const_iterator &QHash::const_iterator::operator--()
+
+ The prefix -- operator (\c{--i}) makes the preceding item
+ current and returns an iterator pointing to the new current item.
+
+ Calling this function on QHash::begin() leads to undefined
+ results.
+
+ \sa operator++()
+*/
+
+/*! \fn QHash::const_iterator QHash::const_iterator::operator--(int)
+
+ \overload
+
+ The postfix -- operator (\c{i--}) makes the preceding item
+ current and returns an iterator pointing to the previously
+ current item.
+*/
+
+/*! \fn QHash::const_iterator QHash::const_iterator::operator+(int j) const
+
+ Returns an iterator to the item at \a j positions forward from
+ this iterator. (If \a j is negative, the iterator goes backward.)
+
+ This operation can be slow for large \a j values.
+
+ \sa operator-()
+*/
+
+/*! \fn QHash::const_iterator QHash::const_iterator::operator-(int j) const
+
+ Returns an iterator to the item at \a j positions backward from
+ this iterator. (If \a j is negative, the iterator goes forward.)
+
+ This operation can be slow for large \a j values.
+
+ \sa operator+()
+*/
+
+/*! \fn QHash::const_iterator &QHash::const_iterator::operator+=(int j)
+
+ Advances the iterator by \a j items. (If \a j is negative, the
+ iterator goes backward.)
+
+ This operation can be slow for large \a j values.
+
+ \sa operator-=(), operator+()
+*/
+
+/*! \fn QHash::const_iterator &QHash::const_iterator::operator-=(int j)
+
+ Makes the iterator go back by \a j items. (If \a j is negative,
+ the iterator goes forward.)
+
+ This operation can be slow for large \a j values.
+
+ \sa operator+=(), operator-()
+*/
+
+/*! \fn uint qHash(char key)
+ \relates QHash
+
+ Returns the hash value for the \a key.
+*/
+
+/*! \fn uint qHash(uchar key)
+ \relates QHash
+ \overload
+
+ Returns the hash value for the \a key.
+*/
+
+/*! \fn uint qHash(signed char key)
+ \relates QHash
+ \overload
+
+ Returns the hash value for the \a key.
+*/
+
+/*! \fn uint qHash(ushort key)
+ \relates QHash
+ \overload
+
+ Returns the hash value for the \a key.
+*/
+
+/*! \fn uint qHash(short key)
+ \relates QHash
+ \overload
+
+ Returns the hash value for the \a key.
+*/
+
+/*! \fn uint qHash(uint key)
+ \relates QHash
+ \overload
+
+ Returns the hash value for the \a key.
+*/
+
+/*! \fn uint qHash(int key)
+ \relates QHash
+ \overload
+
+ Returns the hash value for the \a key.
+*/
+
+/*! \fn uint qHash(ulong key)
+ \relates QHash
+ \overload
+
+ Returns the hash value for the \a key.
+*/
+
+/*! \fn uint qHash(long key)
+ \relates QHash
+ \overload
+
+ Returns the hash value for the \a key.
+*/
+
+/*! \fn uint qHash(quint64 key)
+ \relates QHash
+ \overload
+
+ Returns the hash value for the \a key.
+*/
+
+/*! \fn uint qHash(qint64 key)
+ \relates QHash
+ \overload
+
+ Returns the hash value for the \a key.
+*/
+
+/*! \fn uint qHash(QChar key)
+ \relates QHash
+ \overload
+
+ Returns the hash value for the \a key.
+*/
+
+/*! \fn uint qHash(const QByteArray &key)
+ \fn uint qHash(const QBitArray &key)
+ \relates QHash
+ \overload
+
+ Returns the hash value for the \a key.
+*/
+
+/*! \fn uint qHash(const QString &key)
+ \relates QHash
+ \overload
+
+ Returns the hash value for the \a key.
+*/
+
+/*! \fn uint qHash(const T *key)
+ \relates QHash
+ \overload
+
+ Returns the hash value for the \a key.
+*/
+
+/*!
+ \fn uint qHash(const QPair<T1, T2> &key)
+ \relates QHash
+ \since 4.3
+
+ Returns the hash value for the \a key.
+
+ Types \c T1 and \c T2 must be supported by qHash().
+*/
+
+/*! \fn QDataStream &operator<<(QDataStream &out, const QHash<Key, T>& hash)
+ \relates QHash
+
+ Writes the hash \a hash to stream \a out.
+
+ This function requires the key and value types to implement \c
+ operator<<().
+
+ \sa {Format of the QDataStream operators}
+*/
+
+/*! \fn QDataStream &operator>>(QDataStream &in, QHash<Key, T> &hash)
+ \relates QHash
+
+ Reads a hash from stream \a in into \a hash.
+
+ This function requires the key and value types to implement \c
+ operator>>().
+
+ \sa {Format of the QDataStream operators}
+*/
+
+/*! \class QMultiHash
+ \brief The QMultiHash class is a convenience QHash subclass that provides multi-valued hashes.
+
+ \ingroup tools
+ \ingroup shared
+ \mainclass
+ \reentrant
+
+ QMultiHash\<Key, T\> is one of Qt's generic \l{container classes}.
+ It inherits QHash and extends it with a few convenience functions
+ that make it more suitable than QHash for storing multi-valued
+ hashes. A multi-valued hash is a hash that allows multiple values
+ with the same key; QHash normally doesn't allow that, unless you
+ call QHash::insertMulti().
+
+ Because QMultiHash inherits QHash, all of QHash's functionality also
+ applies to QMultiHash. For example, you can use isEmpty() to test
+ whether the hash is empty, and you can traverse a QMultiHash using
+ QHash's iterator classes (for example, QHashIterator). But in
+ addition, it provides an insert() function that corresponds to
+ QHash::insertMulti(), and a replace() function that corresponds to
+ QHash::insert(). It also provides convenient operator+() and
+ operator+=().
+
+ Example:
+ \snippet doc/src/snippets/code/src_corelib_tools_qhash.cpp 24
+
+ Unlike QHash, QMultiHash provides no operator[]. Use value() or
+ replace() if you want to access the most recently inserted item
+ with a certain key.
+
+ If you want to retrieve all the values for a single key, you can
+ use values(const Key &key), which returns a QList<T>:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qhash.cpp 25
+
+ The items that share the same key are available from most
+ recently to least recently inserted.
+
+ A more efficient approach is to call find() to get
+ the STL-style iterator for the first item with a key and iterate from
+ there:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qhash.cpp 26
+
+ QMultiHash's key and value data types must be \l{assignable data
+ types}. You cannot, for example, store a QWidget as a value;
+ instead, store a QWidget *. In addition, QMultiHash's key type
+ must provide operator==(), and there must also be a global
+ qHash() function that returns a hash value for an argument of the
+ key's type. See the QHash documentation for details.
+
+ \sa QHash, QHashIterator, QMutableHashIterator, QMultiMap
+*/
+
+/*! \fn QMultiHash::QMultiHash()
+
+ Constructs an empty hash.
+*/
+
+/*! \fn QMultiHash::QMultiHash(const QHash<Key, T> &other)
+
+ Constructs a copy of \a other (which can be a QHash or a
+ QMultiHash).
+
+ \sa operator=()
+*/
+
+/*! \fn QMultiHash::iterator QMultiHash::replace(const Key &key, const T &value)
+
+ Inserts a new item with the \a key and a value of \a value.
+
+ If there is already an item with the \a key, that item's value
+ is replaced with \a value.
+
+ If there are multiple items with the \a key, the most
+ recently inserted item's value is replaced with \a value.
+
+ \sa insert()
+*/
+
+/*! \fn QMultiHash::iterator QMultiHash::insert(const Key &key, const T &value)
+
+ Inserts a new item with the \a key and a value of \a value.
+
+ If there is already an item with the same key in the hash, this
+ function will simply create a new one. (This behavior is
+ different from replace(), which overwrites the value of an
+ existing item.)
+
+ \sa replace()
+*/
+
+/*! \fn QMultiHash &QMultiHash::operator+=(const QMultiHash &other)
+
+ Inserts all the items in the \a other hash into this hash
+ and returns a reference to this hash.
+
+ \sa insert()
+*/
+
+/*! \fn QMultiHash QMultiHash::operator+(const QMultiHash &other) const
+
+ Returns a hash that contains all the items in this hash in
+ addition to all the items in \a other. If a key is common to both
+ hashes, the resulting hash will contain the key multiple times.
+
+ \sa operator+=()
+*/
+
+/*!
+ \fn bool QMultiHash::contains(const Key &key, const T &value) const
+ \since 4.3
+
+ Returns true if the hash contains an item with the \a key and
+ \a value; otherwise returns false.
+
+ \sa QHash::contains()
+*/
+
+/*!
+ \fn bool QMultiHash::contains(const Key &key) const
+ \overload
+ \sa QHash::contains()
+*/
+
+/*!
+ \fn int QMultiHash::remove(const Key &key, const T &value)
+ \since 4.3
+
+ Removes all the items that have the \a key and the value \a
+ value from the hash. Returns the number of items removed.
+
+ \sa QHash::remove()
+*/
+
+/*!
+ \fn int QMultiHash::remove(const Key &key)
+ \overload
+ \sa QHash::remove()
+*/
+
+/*!
+ \fn int QMultiHash::count(const Key &key, const T &value) const
+ \since 4.3
+
+ Returns the number of items with the \a key and \a value.
+
+ \sa QHash::count()
+*/
+
+/*!
+ \fn int QMultiHash::count(const Key &key) const
+ \overload
+ \sa QHash::count()
+*/
+
+/*!
+ \fn int QMultiHash::count() const
+ \overload
+ \sa QHash::count()
+*/
+
+/*!
+ \fn typename QHash<Key, T>::iterator QMultiHash::find(const Key &key, const T &value)
+ \since 4.3
+
+ Returns an iterator pointing to the item with the \a key and \a value.
+ If the hash contains no such item, the function returns end().
+
+ If the hash contains multiple items with the \a key and \a value, the
+ iterator returned points to the most recently inserted item.
+
+ \sa QHash::find()
+*/
+
+/*!
+ \fn typename QHash<Key, T>::iterator QMultiHash::find(const Key &key)
+ \overload
+ \sa QHash::find()
+*/
+
+/*!
+ \fn typename QHash<Key, T>::const_iterator QMultiHash::find(const Key &key, const T &value) const
+ \since 4.3
+ \overload
+*/
+
+/*!
+ \fn typename QHash<Key, T>::const_iterator QMultiHash::find(const Key &key) const
+ \overload
+ \sa QHash::find()
+*/
+
+/*!
+ \fn typename QHash<Key, T>::const_iterator QMultiHash::constFind(const Key &key, const T &value) const
+ \since 4.3
+
+ Returns an iterator pointing to the item with the \a key and the
+ \a value in the hash.
+
+ If the hash contains no such item, the function returns
+ constEnd().
+
+ \sa QHash::constFind()
+*/
+
+/*!
+ \fn typename QHash<Key, T>::const_iterator QMultiHash::constFind(const Key &key) const
+ \overload
+ \sa QHash::constFind()
+*/
+
+QT_END_NAMESPACE
diff --git a/src/corelib/tools/qhash.h b/src/corelib/tools/qhash.h
new file mode 100644
index 0000000000..a18b531dd9
--- /dev/null
+++ b/src/corelib/tools/qhash.h
@@ -0,0 +1,1017 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QHASH_H
+#define QHASH_H
+
+#include <QtCore/qatomic.h>
+#include <QtCore/qchar.h>
+#include <QtCore/qiterator.h>
+#include <QtCore/qlist.h>
+#include <QtCore/qpair.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+#undef QT_QHASH_DEBUG
+QT_MODULE(Core)
+
+class QBitArray;
+class QByteArray;
+class QString;
+class QStringRef;
+
+inline uint qHash(char key) { return uint(key); }
+inline uint qHash(uchar key) { return uint(key); }
+inline uint qHash(signed char key) { return uint(key); }
+inline uint qHash(ushort key) { return uint(key); }
+inline uint qHash(short key) { return uint(key); }
+inline uint qHash(uint key) { return key; }
+inline uint qHash(int key) { return uint(key); }
+inline uint qHash(ulong key)
+{
+ if (sizeof(ulong) > sizeof(uint)) {
+ return uint((key >> (8 * sizeof(uint) - 1)) ^ key);
+ } else {
+ return uint(key);
+ }
+}
+inline uint qHash(long key) { return qHash(ulong(key)); }
+inline uint qHash(quint64 key)
+{
+ if (sizeof(quint64) > sizeof(uint)) {
+ return uint((key >> (8 * sizeof(uint) - 1)) ^ key);
+ } else {
+ return uint(key);
+ }
+}
+inline uint qHash(qint64 key) { return qHash(quint64(key)); }
+inline uint qHash(QChar key) { return qHash(key.unicode()); }
+Q_CORE_EXPORT uint qHash(const QByteArray &key);
+Q_CORE_EXPORT uint qHash(const QString &key);
+Q_CORE_EXPORT uint qHash(const QStringRef &key);
+Q_CORE_EXPORT uint qHash(const QBitArray &key);
+
+#if defined(Q_CC_MSVC)
+#pragma warning( push )
+#pragma warning( disable : 4311 ) // disable pointer truncation warning
+#endif
+template <class T> inline uint qHash(const T *key)
+{
+ if (sizeof(const T *) > sizeof(uint))
+ return qHash(reinterpret_cast<quint64>(key));
+ else
+ return uint(reinterpret_cast<ulong>(key));
+}
+#if defined(Q_CC_MSVC)
+#pragma warning( pop )
+#endif
+
+template <typename T1, typename T2> inline uint qHash(const QPair<T1, T2> &key)
+{
+ uint h1 = qHash(key.first);
+ uint h2 = qHash(key.second);
+ return ((h1 << 16) | (h1 >> 16)) ^ h2;
+}
+
+struct Q_CORE_EXPORT QHashData
+{
+ struct Node {
+ Node *next;
+ uint h;
+ };
+
+ Node *fakeNext;
+ Node **buckets;
+ QBasicAtomicInt ref;
+ int size;
+ int nodeSize;
+ short userNumBits;
+ short numBits;
+ int numBuckets;
+ uint sharable : 1;
+
+ void *allocateNode();
+ void freeNode(void *node);
+ QHashData *detach_helper(void (*node_duplicate)(Node *, void *), int nodeSize);
+ void mightGrow();
+ bool willGrow();
+ void hasShrunk();
+ void rehash(int hint);
+ void destroyAndFree();
+ Node *firstNode();
+#ifdef QT_QHASH_DEBUG
+ void dump();
+ void checkSanity();
+#endif
+ static Node *nextNode(Node *node);
+ static Node *previousNode(Node *node);
+
+ static QHashData shared_null;
+};
+
+inline void QHashData::mightGrow() // ### Qt 5: eliminate
+{
+ if (size >= numBuckets)
+ rehash(numBits + 1);
+}
+
+inline bool QHashData::willGrow()
+{
+ if (size >= numBuckets) {
+ rehash(numBits + 1);
+ return true;
+ } else {
+ return false;
+ }
+}
+
+inline void QHashData::hasShrunk()
+{
+ if (size <= (numBuckets >> 3) && numBits > userNumBits)
+ rehash(qMax(int(numBits) - 2, int(userNumBits)));
+}
+
+inline QHashData::Node *QHashData::firstNode()
+{
+ Node *e = reinterpret_cast<Node *>(this);
+ Node **bucket = buckets;
+ int n = numBuckets;
+ while (n--) {
+ if (*bucket != e)
+ return *bucket;
+ ++bucket;
+ }
+ return e;
+}
+
+struct QHashDummyValue
+{
+};
+
+inline bool operator==(const QHashDummyValue & /* v1 */, const QHashDummyValue & /* v2 */)
+{
+ return true;
+}
+
+Q_DECLARE_TYPEINFO(QHashDummyValue, Q_MOVABLE_TYPE | Q_DUMMY_TYPE);
+
+template <class Key, class T>
+struct QHashDummyNode
+{
+ QHashDummyNode *next;
+ uint h;
+ Key key;
+
+ inline QHashDummyNode(const Key &key0) : key(key0) {}
+};
+
+template <class Key, class T>
+struct QHashNode
+{
+ QHashNode *next;
+ uint h;
+ Key key;
+ T value;
+
+ inline QHashNode(const Key &key0) : key(key0) {} // ### remove in 5.0
+ inline QHashNode(const Key &key0, const T &value0) : key(key0), value(value0) {}
+ inline bool same_key(uint h0, const Key &key0) { return h0 == h && key0 == key; }
+};
+
+#ifndef QT_NO_PARTIAL_TEMPLATE_SPECIALIZATION
+#define Q_HASH_DECLARE_INT_NODES(key_type) \
+ template <class T> \
+ struct QHashDummyNode<key_type, T> { \
+ QHashDummyNode *next; \
+ union { uint h; key_type key; }; \
+\
+ inline QHashDummyNode(key_type /* key0 */) {} \
+ }; \
+\
+ template <class T> \
+ struct QHashNode<key_type, T> { \
+ QHashNode *next; \
+ union { uint h; key_type key; }; \
+ T value; \
+\
+ inline QHashNode(key_type /* key0 */) {} \
+ inline QHashNode(key_type /* key0 */, const T &value0) : value(value0) {} \
+ inline bool same_key(uint h0, key_type) { return h0 == h; } \
+ }
+
+#if defined(Q_BYTE_ORDER) && Q_BYTE_ORDER == Q_LITTLE_ENDIAN
+Q_HASH_DECLARE_INT_NODES(short);
+Q_HASH_DECLARE_INT_NODES(ushort);
+#endif
+Q_HASH_DECLARE_INT_NODES(int);
+Q_HASH_DECLARE_INT_NODES(uint);
+#undef Q_HASH_DECLARE_INT_NODES
+#endif // QT_NO_PARTIAL_TEMPLATE_SPECIALIZATION
+
+template <class Key, class T>
+class QHash
+{
+ typedef QHashDummyNode<Key, T> DummyNode;
+ typedef QHashNode<Key, T> Node;
+
+ union {
+ QHashData *d;
+ QHashNode<Key, T> *e;
+ };
+
+ static inline Node *concrete(QHashData::Node *node) {
+ return reinterpret_cast<Node *>(node);
+ }
+
+public:
+ inline QHash() : d(&QHashData::shared_null) { d->ref.ref(); }
+ inline QHash(const QHash<Key, T> &other) : d(other.d) { d->ref.ref(); if (!d->sharable) detach(); }
+ inline ~QHash() { if (!d->ref.deref()) freeData(d); }
+
+ QHash<Key, T> &operator=(const QHash<Key, T> &other);
+
+ bool operator==(const QHash<Key, T> &other) const;
+ inline bool operator!=(const QHash<Key, T> &other) const { return !(*this == other); }
+
+ inline int size() const { return d->size; }
+
+ inline bool isEmpty() const { return d->size == 0; }
+
+ inline int capacity() const { return d->numBuckets; }
+ void reserve(int size);
+ inline void squeeze() { reserve(1); }
+
+ inline void detach() { if (d->ref != 1) detach_helper(); }
+ inline bool isDetached() const { return d->ref == 1; }
+ inline void setSharable(bool sharable) { if (!sharable) detach(); d->sharable = sharable; }
+
+ void clear();
+
+ int remove(const Key &key);
+ T take(const Key &key);
+
+ bool contains(const Key &key) const;
+ const Key key(const T &value) const;
+ const Key key(const T &value, const Key &defaultKey) const;
+ const T value(const Key &key) const;
+ const T value(const Key &key, const T &defaultValue) const;
+ T &operator[](const Key &key);
+ const T operator[](const Key &key) const;
+
+ QList<Key> uniqueKeys() const;
+ QList<Key> keys() const;
+ QList<Key> keys(const T &value) const;
+ QList<T> values() const;
+ QList<T> values(const Key &key) const;
+ int count(const Key &key) const;
+
+ class const_iterator;
+
+ class iterator
+ {
+ friend class const_iterator;
+ QHashData::Node *i;
+
+ public:
+ typedef std::bidirectional_iterator_tag iterator_category;
+ typedef ptrdiff_t difference_type;
+ typedef T value_type;
+ typedef T *pointer;
+ typedef T &reference;
+
+ // ### Qt 5: get rid of 'operator Node *'
+ inline operator Node *() const { return concrete(i); }
+ inline iterator() : i(0) { }
+ explicit inline iterator(void *node) : i(reinterpret_cast<QHashData::Node *>(node)) { }
+
+ inline const Key &key() const { return concrete(i)->key; }
+ inline T &value() const { return concrete(i)->value; }
+ inline T &operator*() const { return concrete(i)->value; }
+ inline T *operator->() const { return &concrete(i)->value; }
+ inline bool operator==(const iterator &o) const { return i == o.i; }
+ inline bool operator!=(const iterator &o) const { return i != o.i; }
+
+ inline iterator &operator++() {
+ i = QHashData::nextNode(i);
+ return *this;
+ }
+ inline iterator operator++(int) {
+ iterator r = *this;
+ i = QHashData::nextNode(i);
+ return r;
+ }
+ inline iterator &operator--() {
+ i = QHashData::previousNode(i);
+ return *this;
+ }
+ inline iterator operator--(int) {
+ iterator r = *this;
+ i = QHashData::previousNode(i);
+ return r;
+ }
+ inline iterator operator+(int j) const
+ { iterator r = *this; if (j > 0) while (j--) ++r; else while (j++) --r; return r; }
+ inline iterator operator-(int j) const { return operator+(-j); }
+ inline iterator &operator+=(int j) { return *this = *this + j; }
+ inline iterator &operator-=(int j) { return *this = *this - j; }
+
+ // ### Qt 5: not sure this is necessary anymore
+#ifdef QT_STRICT_ITERATORS
+ private:
+#else
+ public:
+#endif
+ inline bool operator==(const const_iterator &o) const
+ { return i == o.i; }
+ inline bool operator!=(const const_iterator &o) const
+ { return i != o.i; }
+
+ private:
+ // ### Qt 5: remove
+ inline operator bool() const { return false; }
+ };
+ friend class iterator;
+
+ class const_iterator
+ {
+ friend class iterator;
+ QHashData::Node *i;
+
+ public:
+ typedef std::bidirectional_iterator_tag iterator_category;
+ typedef ptrdiff_t difference_type;
+ typedef T value_type;
+ typedef const T *pointer;
+ typedef const T &reference;
+
+ // ### Qt 5: get rid of 'operator Node *'
+ inline operator Node *() const { return concrete(i); }
+ inline const_iterator() : i(0) { }
+ explicit inline const_iterator(void *node)
+ : i(reinterpret_cast<QHashData::Node *>(node)) { }
+#ifdef QT_STRICT_ITERATORS
+ explicit inline const_iterator(const iterator &o)
+#else
+ inline const_iterator(const iterator &o)
+#endif
+ { i = o.i; }
+
+ inline const Key &key() const { return concrete(i)->key; }
+ inline const T &value() const { return concrete(i)->value; }
+ inline const T &operator*() const { return concrete(i)->value; }
+ inline const T *operator->() const { return &concrete(i)->value; }
+ inline bool operator==(const const_iterator &o) const { return i == o.i; }
+ inline bool operator!=(const const_iterator &o) const { return i != o.i; }
+
+ inline const_iterator &operator++() {
+ i = QHashData::nextNode(i);
+ return *this;
+ }
+ inline const_iterator operator++(int) {
+ const_iterator r = *this;
+ i = QHashData::nextNode(i);
+ return r;
+ }
+ inline const_iterator &operator--() {
+ i = QHashData::previousNode(i);
+ return *this;
+ }
+ inline const_iterator operator--(int) {
+ const_iterator r = *this;
+ i = QHashData::previousNode(i);
+ return r;
+ }
+ inline const_iterator operator+(int j) const
+ { const_iterator r = *this; if (j > 0) while (j--) ++r; else while (j++) --r; return r; }
+ inline const_iterator operator-(int j) const { return operator+(-j); }
+ inline const_iterator &operator+=(int j) { return *this = *this + j; }
+ inline const_iterator &operator-=(int j) { return *this = *this - j; }
+
+ // ### Qt 5: not sure this is necessary anymore
+#ifdef QT_STRICT_ITERATORS
+ private:
+ inline bool operator==(const iterator &o) const { return operator==(const_iterator(o)); }
+ inline bool operator!=(const iterator &o) const { return operator!=(const_iterator(o)); }
+#endif
+
+ private:
+ // ### Qt 5: remove
+ inline operator bool() const { return false; }
+ };
+ friend class const_iterator;
+
+ // STL style
+ inline iterator begin() { detach(); return iterator(d->firstNode()); }
+ inline const_iterator begin() const { return const_iterator(d->firstNode()); }
+ inline const_iterator constBegin() const { return const_iterator(d->firstNode()); }
+ inline iterator end() { detach(); return iterator(e); }
+ inline const_iterator end() const { return const_iterator(e); }
+ inline const_iterator constEnd() const { return const_iterator(e); }
+ iterator erase(iterator it);
+
+ // more Qt
+ typedef iterator Iterator;
+ typedef const_iterator ConstIterator;
+ inline int count() const { return d->size; }
+ iterator find(const Key &key);
+ const_iterator find(const Key &key) const;
+ const_iterator constFind(const Key &key) const;
+ iterator insert(const Key &key, const T &value);
+ iterator insertMulti(const Key &key, const T &value);
+ QHash<Key, T> &unite(const QHash<Key, T> &other);
+
+ // STL compatibility
+ typedef T mapped_type;
+ typedef Key key_type;
+ typedef ptrdiff_t difference_type;
+ typedef int size_type;
+
+ inline bool empty() const { return isEmpty(); }
+
+#ifdef QT_QHASH_DEBUG
+ inline void dump() const { d->dump(); }
+ inline void checkSanity() const { d->checkSanity(); }
+#endif
+
+private:
+ void detach_helper();
+ void freeData(QHashData *d);
+ Node **findNode(const Key &key, uint *hp = 0) const;
+ Node *createNode(uint h, const Key &key, const T &value, Node **nextNode);
+ void deleteNode(Node *node);
+
+ static void duplicateNode(QHashData::Node *originalNode, void *newNode);
+};
+
+template <class Key, class T>
+Q_INLINE_TEMPLATE void QHash<Key, T>::deleteNode(Node *node)
+{
+#ifdef Q_CC_BOR
+ node->~QHashNode<Key, T>();
+#elif defined(QT_NO_PARTIAL_TEMPLATE_SPECIALIZATION)
+ node->~QHashNode();
+#else
+ node->~Node();
+#endif
+ d->freeNode(node);
+}
+
+template <class Key, class T>
+Q_INLINE_TEMPLATE void QHash<Key, T>::duplicateNode(QHashData::Node *node, void *newNode)
+{
+ Node *concreteNode = concrete(node);
+ if (QTypeInfo<T>::isDummy) {
+ (void) new (newNode) DummyNode(concreteNode->key);
+ } else {
+ (void) new (newNode) Node(concreteNode->key, concreteNode->value);
+ }
+}
+
+template <class Key, class T>
+Q_INLINE_TEMPLATE typename QHash<Key, T>::Node *
+QHash<Key, T>::createNode(uint ah, const Key &akey, const T &avalue, Node **anextNode)
+{
+ Node *node;
+
+ if (QTypeInfo<T>::isDummy) {
+ node = reinterpret_cast<Node *>(new (d->allocateNode()) DummyNode(akey));
+ } else {
+ node = new (d->allocateNode()) Node(akey, avalue);
+ }
+
+ node->h = ah;
+ node->next = *anextNode;
+ *anextNode = node;
+ ++d->size;
+ return node;
+}
+
+template <class Key, class T>
+Q_INLINE_TEMPLATE QHash<Key, T> &QHash<Key, T>::unite(const QHash<Key, T> &other)
+{
+ QHash<Key, T> copy(other);
+ const_iterator it = copy.constEnd();
+ while (it != copy.constBegin()) {
+ --it;
+ insertMulti(it.key(), it.value());
+ }
+ return *this;
+}
+
+template <class Key, class T>
+Q_OUTOFLINE_TEMPLATE void QHash<Key, T>::freeData(QHashData *x)
+{
+ Node *e_for_x = reinterpret_cast<Node *>(x);
+ Node **bucket = reinterpret_cast<Node **>(x->buckets);
+ int n = x->numBuckets;
+ while (n--) {
+ Node *cur = *bucket++;
+ while (cur != e_for_x) {
+ Node *next = cur->next;
+ deleteNode(cur);
+ cur = next;
+ }
+ }
+ x->destroyAndFree();
+}
+
+template <class Key, class T>
+Q_INLINE_TEMPLATE void QHash<Key, T>::clear()
+{
+ *this = QHash<Key,T>();
+}
+
+template <class Key, class T>
+Q_OUTOFLINE_TEMPLATE void QHash<Key, T>::detach_helper()
+{
+ QHashData *x = d->detach_helper(duplicateNode,
+ QTypeInfo<T>::isDummy ? sizeof(DummyNode) : sizeof(Node));
+ if (!d->ref.deref())
+ freeData(d);
+ d = x;
+}
+
+template <class Key, class T>
+Q_INLINE_TEMPLATE QHash<Key, T> &QHash<Key, T>::operator=(const QHash<Key, T> &other)
+{
+ if (d != other.d) {
+ other.d->ref.ref();
+ if (!d->ref.deref())
+ freeData(d);
+ d = other.d;
+ if (!d->sharable)
+ detach_helper();
+ }
+ return *this;
+}
+
+template <class Key, class T>
+Q_INLINE_TEMPLATE const T QHash<Key, T>::value(const Key &akey) const
+{
+ Node *node;
+ if (d->size == 0 || (node = *findNode(akey)) == e) {
+ return T();
+ } else {
+ return node->value;
+ }
+}
+
+template <class Key, class T>
+Q_INLINE_TEMPLATE const T QHash<Key, T>::value(const Key &akey, const T &adefaultValue) const
+{
+ Node *node;
+ if (d->size == 0 || (node = *findNode(akey)) == e) {
+ return adefaultValue;
+ } else {
+ return node->value;
+ }
+}
+
+template <class Key, class T>
+Q_OUTOFLINE_TEMPLATE QList<Key> QHash<Key, T>::uniqueKeys() const
+{
+ QList<Key> res;
+ const_iterator i = begin();
+ if (i != end()) {
+ for (;;) {
+ const Key &aKey = i.key();
+ res.append(aKey);
+ do {
+ if (++i == end())
+ goto break_out_of_outer_loop;
+ } while (aKey == i.key());
+ }
+ }
+break_out_of_outer_loop:
+ return res;
+}
+
+template <class Key, class T>
+Q_OUTOFLINE_TEMPLATE QList<Key> QHash<Key, T>::keys() const
+{
+ QList<Key> res;
+ const_iterator i = begin();
+ while (i != end()) {
+ res.append(i.key());
+ ++i;
+ }
+ return res;
+}
+
+template <class Key, class T>
+Q_OUTOFLINE_TEMPLATE QList<Key> QHash<Key, T>::keys(const T &avalue) const
+{
+ QList<Key> res;
+ const_iterator i = begin();
+ while (i != end()) {
+ if (i.value() == avalue)
+ res.append(i.key());
+ ++i;
+ }
+ return res;
+}
+
+template <class Key, class T>
+Q_OUTOFLINE_TEMPLATE const Key QHash<Key, T>::key(const T &avalue) const
+{
+ return key(avalue, Key());
+}
+
+template <class Key, class T>
+Q_OUTOFLINE_TEMPLATE const Key QHash<Key, T>::key(const T &avalue, const Key &defaultValue) const
+{
+ const_iterator i = begin();
+ while (i != end()) {
+ if (i.value() == avalue)
+ return i.key();
+ ++i;
+ }
+
+ return defaultValue;
+}
+
+template <class Key, class T>
+Q_OUTOFLINE_TEMPLATE QList<T> QHash<Key, T>::values() const
+{
+ QList<T> res;
+ const_iterator i = begin();
+ while (i != end()) {
+ res.append(i.value());
+ ++i;
+ }
+ return res;
+}
+
+template <class Key, class T>
+Q_OUTOFLINE_TEMPLATE QList<T> QHash<Key, T>::values(const Key &akey) const
+{
+ QList<T> res;
+ Node *node = *findNode(akey);
+ if (node != e) {
+ do {
+ res.append(node->value);
+ } while ((node = node->next) != e && node->key == akey);
+ }
+ return res;
+}
+
+template <class Key, class T>
+Q_OUTOFLINE_TEMPLATE int QHash<Key, T>::count(const Key &akey) const
+{
+ int cnt = 0;
+ Node *node = *findNode(akey);
+ if (node != e) {
+ do {
+ ++cnt;
+ } while ((node = node->next) != e && node->key == akey);
+ }
+ return cnt;
+}
+
+template <class Key, class T>
+Q_INLINE_TEMPLATE const T QHash<Key, T>::operator[](const Key &akey) const
+{
+ return value(akey);
+}
+
+template <class Key, class T>
+Q_INLINE_TEMPLATE T &QHash<Key, T>::operator[](const Key &akey)
+{
+ detach();
+
+ uint h;
+ Node **node = findNode(akey, &h);
+ if (*node == e) {
+ if (d->willGrow())
+ node = findNode(akey, &h);
+ return createNode(h, akey, T(), node)->value;
+ }
+ return (*node)->value;
+}
+
+template <class Key, class T>
+Q_INLINE_TEMPLATE typename QHash<Key, T>::iterator QHash<Key, T>::insert(const Key &akey,
+ const T &avalue)
+{
+ detach();
+
+ uint h;
+ Node **node = findNode(akey, &h);
+ if (*node == e) {
+ if (d->willGrow())
+ node = findNode(akey, &h);
+ return iterator(createNode(h, akey, avalue, node));
+ }
+
+ if (!QTypeInfo<T>::isDummy)
+ (*node)->value = avalue;
+ return iterator(*node);
+}
+
+template <class Key, class T>
+Q_INLINE_TEMPLATE typename QHash<Key, T>::iterator QHash<Key, T>::insertMulti(const Key &akey,
+ const T &avalue)
+{
+ detach();
+ d->willGrow();
+
+ uint h;
+ Node **nextNode = findNode(akey, &h);
+ return iterator(createNode(h, akey, avalue, nextNode));
+}
+
+template <class Key, class T>
+Q_OUTOFLINE_TEMPLATE int QHash<Key, T>::remove(const Key &akey)
+{
+ detach();
+
+ int oldSize = d->size;
+ Node **node = findNode(akey);
+ if (*node != e) {
+ bool deleteNext = true;
+ do {
+ Node *next = (*node)->next;
+ deleteNext = (next != e && next->key == (*node)->key);
+ deleteNode(*node);
+ *node = next;
+ --d->size;
+ } while (deleteNext);
+ d->hasShrunk();
+ }
+ return oldSize - d->size;
+}
+
+template <class Key, class T>
+Q_OUTOFLINE_TEMPLATE T QHash<Key, T>::take(const Key &akey)
+{
+ detach();
+
+ Node **node = findNode(akey);
+ if (*node != e) {
+ T t = (*node)->value;
+ Node *next = (*node)->next;
+ deleteNode(*node);
+ *node = next;
+ --d->size;
+ d->hasShrunk();
+ return t;
+ }
+ return T();
+}
+
+template <class Key, class T>
+Q_OUTOFLINE_TEMPLATE typename QHash<Key, T>::iterator QHash<Key, T>::erase(iterator it)
+{
+ if (it == iterator(e))
+ return it;
+
+ iterator ret = it;
+ ++ret;
+
+ Node *node = it;
+ Node **node_ptr = reinterpret_cast<Node **>(&d->buckets[node->h % d->numBuckets]);
+ while (*node_ptr != node)
+ node_ptr = &(*node_ptr)->next;
+ *node_ptr = node->next;
+ deleteNode(node);
+ --d->size;
+ return ret;
+}
+
+template <class Key, class T>
+Q_INLINE_TEMPLATE void QHash<Key, T>::reserve(int asize)
+{
+ detach();
+ d->rehash(-qMax(asize, 1));
+}
+
+template <class Key, class T>
+Q_INLINE_TEMPLATE typename QHash<Key, T>::const_iterator QHash<Key, T>::find(const Key &akey) const
+{
+ return const_iterator(*findNode(akey));
+}
+
+template <class Key, class T>
+Q_INLINE_TEMPLATE typename QHash<Key, T>::const_iterator QHash<Key, T>::constFind(const Key &akey) const
+{
+ return const_iterator(*findNode(akey));
+}
+
+template <class Key, class T>
+Q_INLINE_TEMPLATE typename QHash<Key, T>::iterator QHash<Key, T>::find(const Key &akey)
+{
+ detach();
+ return iterator(*findNode(akey));
+}
+
+template <class Key, class T>
+Q_INLINE_TEMPLATE bool QHash<Key, T>::contains(const Key &akey) const
+{
+ return *findNode(akey) != e;
+}
+
+template <class Key, class T>
+Q_OUTOFLINE_TEMPLATE typename QHash<Key, T>::Node **QHash<Key, T>::findNode(const Key &akey,
+ uint *ahp) const
+{
+ Node **node;
+ uint h = qHash(akey);
+
+ if (d->numBuckets) {
+ node = reinterpret_cast<Node **>(&d->buckets[h % d->numBuckets]);
+ Q_ASSERT(*node == e || (*node)->next);
+ while (*node != e && !(*node)->same_key(h, akey))
+ node = &(*node)->next;
+ } else {
+ node = const_cast<Node **>(reinterpret_cast<const Node * const *>(&e));
+ }
+ if (ahp)
+ *ahp = h;
+ return node;
+}
+
+template <class Key, class T>
+Q_OUTOFLINE_TEMPLATE bool QHash<Key, T>::operator==(const QHash<Key, T> &other) const
+{
+ if (size() != other.size())
+ return false;
+ if (d == other.d)
+ return true;
+
+ const_iterator it = begin();
+
+ while (it != end()) {
+ const Key &akey = it.key();
+
+ const_iterator it2 = other.find(akey);
+ do {
+ if (it2 == other.end() || !(it2.key() == akey))
+ return false;
+ if (!QTypeInfo<T>::isDummy && !(it.value() == it2.value()))
+ return false;
+ ++it;
+ ++it2;
+ } while (it != end() && it.key() == akey);
+ }
+ return true;
+}
+
+template <class Key, class T>
+class QMultiHash : public QHash<Key, T>
+{
+public:
+ QMultiHash() {}
+ QMultiHash(const QHash<Key, T> &other) : QHash<Key, T>(other) {}
+
+ inline typename QHash<Key, T>::iterator replace(const Key &key, const T &value)
+ { return QHash<Key, T>::insert(key, value); }
+
+ inline typename QHash<Key, T>::iterator insert(const Key &key, const T &value)
+ { return QHash<Key, T>::insertMulti(key, value); }
+
+ inline QMultiHash &operator+=(const QMultiHash &other)
+ { unite(other); return *this; }
+ inline QMultiHash operator+(const QMultiHash &other) const
+ { QMultiHash result = *this; result += other; return result; }
+
+#ifndef Q_NO_USING_KEYWORD
+ using QHash<Key, T>::contains;
+ using QHash<Key, T>::remove;
+ using QHash<Key, T>::count;
+ using QHash<Key, T>::find;
+ using QHash<Key, T>::constFind;
+#else
+ inline bool contains(const Key &key) const
+ { return QHash<Key, T>::contains(key); }
+ inline int remove(const Key &key)
+ { return QHash<Key, T>::remove(key); }
+ inline int count(const Key &key) const
+ { return QHash<Key, T>::count(key); }
+ inline int count() const
+ { return QHash<Key, T>::count(); }
+ inline typename QHash<Key, T>::iterator find(const Key &key)
+ { return QHash<Key, T>::find(key); }
+ inline typename QHash<Key, T>::const_iterator find(const Key &key) const
+ { return QHash<Key, T>::find(key); }
+ inline typename QHash<Key, T>::const_iterator constFind(const Key &key) const
+ { return QHash<Key, T>::constFind(key); }
+#endif
+
+ bool contains(const Key &key, const T &value) const;
+
+ int remove(const Key &key, const T &value);
+
+ int count(const Key &key, const T &value) const;
+
+ typename QHash<Key, T>::iterator find(const Key &key, const T &value) {
+ typename QHash<Key, T>::iterator i(find(key));
+ typename QHash<Key, T>::iterator end(this->end());
+ while (i != end && i.key() == key) {
+ if (i.value() == value)
+ return i;
+ ++i;
+ }
+ return end;
+ }
+ typename QHash<Key, T>::const_iterator find(const Key &key, const T &value) const {
+ typename QHash<Key, T>::const_iterator i(constFind(key));
+ typename QHash<Key, T>::const_iterator end(QHash<Key, T>::constEnd());
+ while (i != end && i.key() == key) {
+ if (i.value() == value)
+ return i;
+ ++i;
+ }
+ return end;
+ }
+ typename QHash<Key, T>::const_iterator constFind(const Key &key, const T &value) const
+ { return find(key, value); }
+private:
+ T &operator[](const Key &key);
+ const T operator[](const Key &key) const;
+};
+
+template <class Key, class T>
+Q_INLINE_TEMPLATE bool QMultiHash<Key, T>::contains(const Key &key, const T &value) const
+{
+ return constFind(key, value) != QHash<Key, T>::constEnd();
+}
+
+template <class Key, class T>
+Q_INLINE_TEMPLATE int QMultiHash<Key, T>::remove(const Key &key, const T &value)
+{
+ int n = 0;
+ typename QHash<Key, T>::iterator i(find(key));
+ typename QHash<Key, T>::iterator end(QHash<Key, T>::end());
+ while (i != end && i.key() == key) {
+ if (i.value() == value) {
+ i = erase(i);
+ ++n;
+ } else {
+ ++i;
+ }
+ }
+ return n;
+}
+
+template <class Key, class T>
+Q_INLINE_TEMPLATE int QMultiHash<Key, T>::count(const Key &key, const T &value) const
+{
+ int n = 0;
+ typename QHash<Key, T>::const_iterator i(constFind(key));
+ typename QHash<Key, T>::const_iterator end(QHash<Key, T>::constEnd());
+ while (i != end && i.key() == key) {
+ if (i.value() == value)
+ ++n;
+ ++i;
+ }
+ return n;
+}
+
+Q_DECLARE_ASSOCIATIVE_ITERATOR(Hash)
+Q_DECLARE_MUTABLE_ASSOCIATIVE_ITERATOR(Hash)
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QHASH_H
diff --git a/src/corelib/tools/qiterator.h b/src/corelib/tools/qiterator.h
new file mode 100644
index 0000000000..3f050fee6b
--- /dev/null
+++ b/src/corelib/tools/qiterator.h
@@ -0,0 +1,202 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QITERATOR_H
+#define QITERATOR_H
+
+#include <QtCore/qglobal.h>
+
+QT_BEGIN_HEADER
+
+namespace std {
+ struct bidirectional_iterator_tag;
+ struct random_access_iterator_tag;
+}
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Core)
+
+#define Q_DECLARE_SEQUENTIAL_ITERATOR(C) \
+\
+template <class T> \
+class Q##C##Iterator \
+{ \
+ typedef typename Q##C<T>::const_iterator const_iterator; \
+ Q##C<T> c; \
+ const_iterator i; \
+public: \
+ inline Q##C##Iterator(const Q##C<T> &container) \
+ : c(container), i(c.constBegin()) {} \
+ inline Q##C##Iterator &operator=(const Q##C<T> &container) \
+ { c = container; i = c.constBegin(); return *this; } \
+ inline void toFront() { i = c.constBegin(); } \
+ inline void toBack() { i = c.constEnd(); } \
+ inline bool hasNext() const { return i != c.constEnd(); } \
+ inline const T &next() { return *i++; } \
+ inline const T &peekNext() const { return *i; } \
+ inline bool hasPrevious() const { return i != c.constBegin(); } \
+ inline const T &previous() { return *--i; } \
+ inline const T &peekPrevious() const { const_iterator p = i; return *--p; } \
+ inline bool findNext(const T &t) \
+ { while (i != c.constEnd()) if (*i++ == t) return true; return false; } \
+ inline bool findPrevious(const T &t) \
+ { while (i != c.constBegin()) if (*(--i) == t) return true; \
+ return false; } \
+};
+
+#define Q_DECLARE_MUTABLE_SEQUENTIAL_ITERATOR(C) \
+\
+template <class T> \
+class QMutable##C##Iterator \
+{ \
+ typedef typename Q##C<T>::iterator iterator; \
+ typedef typename Q##C<T>::const_iterator const_iterator; \
+ Q##C<T> *c; \
+ iterator i, n; \
+ inline bool item_exists() const { return const_iterator(n) != c->constEnd(); } \
+public: \
+ inline QMutable##C##Iterator(Q##C<T> &container) \
+ : c(&container) \
+ { c->setSharable(false); i = c->begin(); n = c->end(); } \
+ inline ~QMutable##C##Iterator() \
+ { c->setSharable(true); } \
+ inline QMutable##C##Iterator &operator=(Q##C<T> &container) \
+ { c->setSharable(true); c = &container; c->setSharable(false); \
+ i = c->begin(); n = c->end(); return *this; } \
+ inline void toFront() { i = c->begin(); n = c->end(); } \
+ inline void toBack() { i = c->end(); n = i; } \
+ inline bool hasNext() const { return c->constEnd() != const_iterator(i); } \
+ inline T &next() { n = i++; return *n; } \
+ inline T &peekNext() const { return *i; } \
+ inline bool hasPrevious() const { return c->constBegin() != const_iterator(i); } \
+ inline T &previous() { n = --i; return *n; } \
+ inline T &peekPrevious() const { iterator p = i; return *--p; } \
+ inline void remove() \
+ { if (c->constEnd() != const_iterator(n)) { i = c->erase(n); n = c->end(); } } \
+ inline void setValue(const T &t) const { if (c->constEnd() != const_iterator(n)) *n = t; } \
+ inline T &value() { Q_ASSERT(item_exists()); return *n; } \
+ inline const T &value() const { Q_ASSERT(item_exists()); return *n; } \
+ inline void insert(const T &t) { n = i = c->insert(i, t); ++i; } \
+ inline bool findNext(const T &t) \
+ { while (c->constEnd() != const_iterator(n = i)) if (*i++ == t) return true; return false; } \
+ inline bool findPrevious(const T &t) \
+ { while (c->constBegin() != const_iterator(i)) if (*(n = --i) == t) return true; \
+ n = c->end(); return false; } \
+};
+
+#define Q_DECLARE_ASSOCIATIVE_ITERATOR(C) \
+\
+template <class Key, class T> \
+class Q##C##Iterator \
+{ \
+ typedef typename Q##C<Key,T>::const_iterator const_iterator; \
+ typedef const_iterator Item; \
+ Q##C<Key,T> c; \
+ const_iterator i, n; \
+ inline bool item_exists() const { return n != c.constEnd(); } \
+public: \
+ inline Q##C##Iterator(const Q##C<Key,T> &container) \
+ : c(container), i(c.constBegin()), n(c.constEnd()) {} \
+ inline Q##C##Iterator &operator=(const Q##C<Key,T> &container) \
+ { c = container; i = c.constBegin(); n = c.constEnd(); return *this; } \
+ inline void toFront() { i = c.constBegin(); n = c.constEnd(); } \
+ inline void toBack() { i = c.constEnd(); n = c.constEnd(); } \
+ inline bool hasNext() const { return i != c.constEnd(); } \
+ inline Item next() { n = i++; return n; } \
+ inline Item peekNext() const { return i; } \
+ inline bool hasPrevious() const { return i != c.constBegin(); } \
+ inline Item previous() { n = --i; return n; } \
+ inline Item peekPrevious() const { const_iterator p = i; return --p; } \
+ inline const T &value() const { Q_ASSERT(item_exists()); return *n; } \
+ inline const Key &key() const { Q_ASSERT(item_exists()); return n.key(); } \
+ inline bool findNext(const T &t) \
+ { while ((n = i) != c.constEnd()) if (*i++ == t) return true; return false; } \
+ inline bool findPrevious(const T &t) \
+ { while (i != c.constBegin()) if (*(n = --i) == t) return true; \
+ n = c.constEnd(); return false; } \
+};
+
+#define Q_DECLARE_MUTABLE_ASSOCIATIVE_ITERATOR(C) \
+\
+template <class Key, class T> \
+class QMutable##C##Iterator \
+{ \
+ typedef typename Q##C<Key,T>::iterator iterator; \
+ typedef typename Q##C<Key,T>::const_iterator const_iterator; \
+ typedef iterator Item; \
+ Q##C<Key,T> *c; \
+ iterator i, n; \
+ inline bool item_exists() const { return const_iterator(n) != c->constEnd(); } \
+public: \
+ inline QMutable##C##Iterator(Q##C<Key,T> &container) \
+ : c(&container) \
+ { c->setSharable(false); i = c->begin(); n = c->end(); } \
+ inline ~QMutable##C##Iterator() \
+ { c->setSharable(true); } \
+ inline QMutable##C##Iterator &operator=(Q##C<Key,T> &container) \
+ { c->setSharable(true); c = &container; c->setSharable(false); i = c->begin(); n = c->end(); return *this; } \
+ inline void toFront() { i = c->begin(); n = c->end(); } \
+ inline void toBack() { i = c->end(); n = c->end(); } \
+ inline bool hasNext() const { return const_iterator(i) != c->constEnd(); } \
+ inline Item next() { n = i++; return n; } \
+ inline Item peekNext() const { return i; } \
+ inline bool hasPrevious() const { return const_iterator(i) != c->constBegin(); } \
+ inline Item previous() { n = --i; return n; } \
+ inline Item peekPrevious() const { iterator p = i; return --p; } \
+ inline void remove() \
+ { if (const_iterator(n) != c->constEnd()) { i = c->erase(n); n = c->end(); } } \
+ inline void setValue(const T &t) { if (const_iterator(n) != c->constEnd()) *n = t; } \
+ inline T &value() { Q_ASSERT(item_exists()); return *n; } \
+ inline const T &value() const { Q_ASSERT(item_exists()); return *n; } \
+ inline const Key &key() const { Q_ASSERT(item_exists()); return n.key(); } \
+ inline bool findNext(const T &t) \
+ { while (const_iterator(n = i) != c->constEnd()) if (*i++ == t) return true; return false; } \
+ inline bool findPrevious(const T &t) \
+ { while (const_iterator(i) != c->constBegin()) if (*(n = --i) == t) return true; \
+ n = c->end(); return false; } \
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QITERATOR_H
diff --git a/src/corelib/tools/qline.cpp b/src/corelib/tools/qline.cpp
new file mode 100644
index 0000000000..f615dcdaa4
--- /dev/null
+++ b/src/corelib/tools/qline.cpp
@@ -0,0 +1,867 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qline.h"
+#include "qdebug.h"
+#include "qdatastream.h"
+#include "qmath.h"
+#include <private/qnumeric_p.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QLine
+ \ingroup multimedia
+
+ \brief The QLine class provides a two-dimensional vector using
+ integer precision.
+
+ A QLine describes a finite length line (or a line segment) on a
+ two-dimensional surface. The start and end points of the line are
+ specified using integer point accuracy for coordinates. Use the
+ QLineF constructor to retrieve a floating point copy.
+
+ \table
+ \row
+ \o \inlineimage qline-point.png
+ \o \inlineimage qline-coordinates.png
+ \endtable
+
+ The positions of the line's start and end points can be retrieved
+ using the p1(), x1(), y1(), p2(), x2(), and y2() functions. The
+ dx() and dy() functions return the horizontal and vertical
+ components of the line. Use isNull() to determine whether the
+ QLine represents a valid line or a null line.
+
+ Finally, the line can be translated a given offset using the
+ translate() function.
+
+ \sa QLineF, QPolygon, QRect
+*/
+
+/*!
+ \fn QLine::QLine()
+
+ Constructs a null line.
+*/
+
+/*!
+ \fn QLine::QLine(const QPoint &p1, const QPoint &p2)
+
+ Constructs a line object that represents the line between \a p1 and
+ \a p2.
+*/
+
+/*!
+ \fn QLine::QLine(int x1, int y1, int x2, int y2)
+
+ Constructs a line object that represents the line between (\a x1, \a y1) and
+ (\a x2, \a y2).
+*/
+
+/*!
+ \fn bool QLine::isNull() const
+
+ Returns true if the line is not set up with valid start and end point;
+ otherwise returns false.
+*/
+
+/*!
+ \fn QPoint QLine::p1() const
+
+ Returns the line's start point.
+
+ \sa x1(), y1(), p2()
+*/
+
+/*!
+ \fn QPoint QLine::p2() const
+
+ Returns the line's end point.
+
+ \sa x2(), y2(), p1()
+*/
+
+/*!
+ \fn int QLine::x1() const
+
+ Returns the x-coordinate of the line's start point.
+
+ \sa p1()
+*/
+
+/*!
+ \fn int QLine::y1() const
+
+ Returns the y-coordinate of the line's start point.
+
+ \sa p1()
+*/
+
+/*!
+ \fn int QLine::x2() const
+
+ Returns the x-coordinate of the line's end point.
+
+ \sa p2()
+*/
+
+/*!
+ \fn int QLine::y2() const
+
+ Returns the y-coordinate of the line's end point.
+
+ \sa p2()
+*/
+
+/*!
+ \fn int QLine::dx() const
+
+ Returns the horizontal component of the line's vector.
+
+ \sa dy()
+*/
+
+/*!
+ \fn int QLine::dy() const
+
+ Returns the vertical component of the line's vector.
+
+ \sa dx()
+*/
+
+/*!
+ \fn bool QLine::operator!=(const QLine &line) const
+
+ Returns true if the given \a line is not the same as \e this line.
+
+ A line is different from another line if any of their start or
+ end points differ, or the internal order of the points is different.
+*/
+
+/*!
+ \fn bool QLine::operator==(const QLine &line) const
+
+ Returns true if the given \a line is the same as \e this line.
+
+ A line is identical to another line if the start and end points
+ are identical, and the internal order of the points is the same.
+*/
+
+/*!
+ \fn void QLine::translate(const QPoint &offset)
+
+ Translates this line by the given \a offset.
+*/
+
+/*!
+ \fn void QLine::translate(int dx, int dy)
+ \overload
+
+ Translates this line the distance specified by \a dx and \a dy.
+*/
+
+/*!
+ \fn QLine QLine::translated(const QPoint &offset) const
+
+ \since 4.4
+
+ Returns this line translated by the given \a offset.
+*/
+
+/*!
+ \fn QLine QLine::translated(int dx, int dy) const
+ \overload
+ \since 4.4
+
+ Returns this line translated the distance specified by \a dx and \a dy.
+*/
+
+
+/*!
+ \fn void QLine::setP1(const QPoint &p1)
+ \since 4.4
+
+ Sets the starting point of this line to \a p1.
+
+ \sa setP2(), p1()
+*/
+
+
+/*!
+ \fn void QLine::setP2(const QPoint &p2)
+ \since 4.4
+
+ Sets the end point of this line to \a p2.
+
+ \sa setP1(), p2()
+*/
+
+
+/*!
+ \fn void QLine::setPoints(const QPoint &p1, const QPoint &p2)
+ \since 4.4
+
+ Sets the start point of this line to \a p1 and the end point of this line to \a p2.
+
+ \sa setP1(), setP2(), p1(), p2()
+*/
+
+
+/*!
+ \fn void QLine::setLine(int x1, int y1, int x2, int y2)
+ \since 4.4
+
+ Sets this line to the start in \a x1, \a y1 and end in \a x2, \a y2.
+
+ \sa setP1(), setP2(), p1(), p2()
+*/
+
+
+
+#ifndef QT_NO_DEBUG_STREAM
+QDebug operator<<(QDebug d, const QLine &p)
+{
+ d << "QLine(" << p.p1() << "," << p.p2() << ")";
+ return d;
+}
+#endif
+
+#ifndef QT_NO_DATASTREAM
+/*!
+ \relates QLine
+
+ Writes the given \a line to the given \a stream and returns a
+ reference to the stream.
+
+ \sa {Format of the QDataStream Operators}
+*/
+
+QDataStream &operator<<(QDataStream &stream, const QLine &line)
+{
+ stream << line.p1() << line.p2();
+ return stream;
+}
+
+/*!
+ \relates QLine
+
+ Reads a line from the given \a stream into the given \a line and
+ returns a reference to the stream.
+
+ \sa {Format of the QDataStream Operators}
+*/
+
+QDataStream &operator>>(QDataStream &stream, QLine &line)
+{
+ QPoint p1, p2;
+ stream >> p1;
+ stream >> p2;
+ line = QLine(p1, p2);
+
+ return stream;
+}
+
+#endif // QT_NO_DATASTREAM
+
+
+#ifndef M_2PI
+#define M_2PI 6.28318530717958647692528676655900576
+#endif
+
+/*!
+ \class QLineF
+ \ingroup multimedia
+
+ \brief The QLineF class provides a two-dimensional vector using
+ floating point precision.
+
+ A QLineF describes a finite length line (or line segment) on a
+ two-dimensional surface. QLineF defines the start and end points
+ of the line using floating point accuracy for coordinates. Use
+ the toLine() function to retrieve an integer based copy of this
+ line.
+
+ \table
+ \row
+ \o \inlineimage qline-point.png
+ \o \inlineimage qline-coordinates.png
+ \endtable
+
+ The positions of the line's start and end points can be retrieved
+ using the p1(), x1(), y1(), p2(), x2(), and y2() functions. The
+ dx() and dy() functions return the horizontal and vertical
+ components of the line, respectively.
+
+ The line's length can be retrieved using the length() function,
+ and altered using the setLength() function. Similarly, angle()
+ and setAngle() are respectively used for retrieving and altering
+ the angle of the line. Use the isNull()
+ function to determine whether the QLineF represents a valid line
+ or a null line.
+
+ The intersect() function determines the IntersectType for this
+ line and a given line, while the angle() function returns the
+ angle between the lines. In addition, the unitVector() function
+ returns a line that has the same starting point as this line, but
+ with a length of only 1, while the normalVector() function returns
+ a line that is perpendicular to this line with the same starting
+ point and length.
+
+ Finally, the line can be translated a given offset using the
+ translate() function, and can be traversed using the pointAt()
+ function.
+
+ \sa QLine, QPolygonF, QRectF
+*/
+
+/*!
+ \enum QLineF::IntersectType
+
+ Describes the intersection between two lines.
+
+ \table
+ \row
+ \o \inlineimage qlinef-unbounded.png
+ \o \inlineimage qlinef-bounded.png
+ \row
+ \o QLineF::UnboundedIntersection
+ \o QLineF::BoundedIntersection
+ \endtable
+
+ \value NoIntersection Indicates that the lines do not intersect;
+ i.e. they are parallel.
+
+ \value UnboundedIntersection The two lines intersect, but not
+ within the range defined by their lengths. This will be the case
+ if the lines are not parallel.
+
+ intersect() will also return this value if the intersect point is
+ within the start and end point of only one of the lines.
+
+ \value BoundedIntersection The two lines intersect with each other
+ within the start and end points of each line.
+
+ \sa intersect()
+*/
+
+/*!
+ \fn QLineF::QLineF()
+
+ Constructs a null line.
+*/
+
+/*!
+ \fn QLineF::QLineF(const QPointF &p1, const QPointF &p2)
+
+ Constructs a line object that represents the line between \a p1 and
+ \a p2.
+*/
+
+/*!
+ \fn QLineF::QLineF(qreal x1, qreal y1, qreal x2, qreal y2)
+
+ Constructs a line object that represents the line between (\a x1, \a y1) and
+ (\a x2, \a y2).
+*/
+
+/*!
+ \fn QLineF::QLineF(const QLine &line)
+
+ Construct a QLineF object from the given integer-based \a line.
+
+ \sa toLine()
+*/
+
+/*!
+ Returns true if the line is not set up with valid start and end point;
+ otherwise returns false.
+*/
+
+bool QLineF::isNull() const
+{
+ return (qFuzzyCompare(pt1.x(), pt2.x()) && qFuzzyCompare(pt1.y(), pt2.y())) ? true : false;
+}
+
+
+/*!
+ \fn QPointF QLineF::p1() const
+
+ Returns the line's start point.
+
+ \sa x1(), y1(), p2()
+*/
+
+/*!
+ \fn QPointF QLineF::p2() const
+
+ Returns the line's end point.
+
+ \sa x2(), y2(), p1()
+*/
+
+/*!
+ \fn QLine QLineF::toLine() const
+
+ Returns an integer based copy of this line.
+
+ Note that the returned line's start and end points are rounded to
+ the nearest integer.
+
+ \sa QLineF()
+*/
+/*!
+ \fn qreal QLineF::x1() const
+
+ Returns the x-coordinate of the line's start point.
+
+ \sa p1()
+*/
+
+/*!
+ \fn qreal QLineF::y1() const
+
+ Returns the y-coordinate of the line's start point.
+
+ \sa p1()
+*/
+
+/*!
+ \fn qreal QLineF::x2() const
+
+ Returns the x-coordinate of the line's end point.
+
+ \sa p2()
+*/
+
+/*!
+ \fn qreal QLineF::y2() const
+
+ Returns the y-coordinate of the line's end point.
+
+ \sa p2()
+*/
+
+/*!
+ \fn qreal QLineF::dx() const
+
+ Returns the horizontal component of the line's vector.
+
+ \sa dy(), pointAt()
+*/
+
+/*!
+ \fn qreal QLineF::dy() const
+
+ Returns the vertical component of the line's vector.
+
+ \sa dx(), pointAt()
+*/
+
+/*!
+ \fn QLineF::setLength(qreal length)
+
+ Sets the length of the line to the given \a length. QLineF will
+ move the end point - p2() - of the line to give the line its new length.
+
+ If the line is a null line, the length will remain zero regardless
+ of the length specified.
+
+ \sa length(), isNull()
+*/
+
+/*!
+ \fn QLineF QLineF::normalVector() const
+
+ Returns a line that is perpendicular to this line with the same starting
+ point and length.
+
+ \image qlinef-normalvector.png
+
+ \sa unitVector()
+*/
+
+/*!
+ \fn bool QLineF::operator!=(const QLineF &line) const
+
+ Returns true if the given \a line is not the same as \e this line.
+
+ A line is different from another line if their start or end points
+ differ, or the internal order of the points is different.
+*/
+
+/*!
+ \fn bool QLineF::operator==(const QLineF &line) const
+
+ Returns true if the given \a line is the same as this line.
+
+ A line is identical to another line if the start and end points
+ are identical, and the internal order of the points is the same.
+*/
+
+/*!
+ \fn qreal QLineF::pointAt(qreal t) const
+
+ Returns the point at the parameterized position specified by \a
+ t. The function returns the line's start point if t = 0, and its end
+ point if t = 1.
+
+ \sa dx(), dy()
+*/
+
+/*!
+ Returns the length of the line.
+
+ \sa setLength()
+*/
+qreal QLineF::length() const
+{
+ qreal x = pt2.x() - pt1.x();
+ qreal y = pt2.y() - pt1.y();
+ return qSqrt(x*x + y*y);
+}
+
+/*!
+ \since 4.4
+
+ Returns the angle of the line in degrees.
+
+ Positive values for the angles mean counter-clockwise while negative values
+ mean the clockwise direction. Zero degrees is at the 3 o'clock position.
+
+ \sa setAngle()
+*/
+qreal QLineF::angle() const
+{
+ const qreal dx = pt2.x() - pt1.x();
+ const qreal dy = pt2.y() - pt1.y();
+
+ const qreal theta = atan2(-dy, dx) * 360.0 / M_2PI;
+
+ const qreal theta_normalized = theta < 0 ? theta + 360 : theta;
+
+ if (qFuzzyCompare(theta_normalized, qreal(360)))
+ return qreal(0);
+ else
+ return theta_normalized;
+}
+
+/*!
+ \since 4.4
+
+ Sets the angle of the line to the given \a angle (in degrees).
+ This will change the position of the second point of the line such that
+ the line has the given angle.
+
+ Positive values for the angles mean counter-clockwise while negative values
+ mean the clockwise direction. Zero degrees is at the 3 o'clock position.
+
+ \sa angle()
+*/
+void QLineF::setAngle(qreal angle)
+{
+ const qreal angleR = angle * M_2PI / 360.0;
+ const qreal l = length();
+
+ const qreal dx = qCos(angleR) * l;
+ const qreal dy = -qSin(angleR) * l;
+
+ pt2.rx() = pt1.x() + dx;
+ pt2.ry() = pt1.y() + dy;
+}
+
+/*!
+ \since 4.4
+
+ Returns a QLineF with the given \a length and \a angle.
+
+ The first point of the line will be on the origin.
+
+ Positive values for the angles mean counter-clockwise while negative values
+ mean the clockwise direction. Zero degrees is at the 3 o'clock position.
+*/
+QLineF QLineF::fromPolar(qreal length, qreal angle)
+{
+ const qreal angleR = angle * M_2PI / 360.0;
+ return QLineF(0, 0, qCos(angleR) * length, -qSin(angleR) * length);
+}
+
+/*!
+ Returns the unit vector for this line, i.e a line starting at the
+ same point as \e this line with a length of 1.0.
+
+ \sa normalVector()
+*/
+QLineF QLineF::unitVector() const
+{
+ qreal x = pt2.x() - pt1.x();
+ qreal y = pt2.y() - pt1.y();
+
+ qreal len = qSqrt(x*x + y*y);
+ QLineF f(p1(), QPointF(pt1.x() + x/len, pt1.y() + y/len));
+
+#ifndef QT_NO_DEBUG
+ if (qAbs(f.length() - 1) >= 0.001)
+ qWarning("QLine::unitVector: New line does not have unit length");
+#endif
+
+ return f;
+}
+
+/*!
+ \fn QLineF::IntersectType QLineF::intersect(const QLineF &line, QPointF *intersectionPoint) const
+
+ Returns a value indicating whether or not \e this line intersects
+ with the given \a line.
+
+ The actual intersection point is extracted to \a intersectionPoint
+ (if the pointer is valid). If the lines are parallel, the
+ intersection point is undefined.
+*/
+
+QLineF::IntersectType QLineF::intersect(const QLineF &l, QPointF *intersectionPoint) const
+{
+ // ipmlementation is based on Graphics Gems III's "Faster Line Segment Intersection"
+ const QPointF a = pt2 - pt1;
+ const QPointF b = l.pt1 - l.pt2;
+ const QPointF c = pt1 - l.pt1;
+
+ const qreal denominator = a.y() * b.x() - a.x() * b.y();
+ if (denominator == 0 || !qt_is_finite(denominator))
+ return NoIntersection;
+
+ const qreal reciprocal = 1 / denominator;
+ const qreal na = (b.y() * c.x() - b.x() * c.y()) * reciprocal;
+ if (intersectionPoint)
+ *intersectionPoint = pt1 + a * na;
+
+ if (na < 0 || na > 1)
+ return UnboundedIntersection;
+
+ const qreal nb = (a.x() * c.y() - a.y() * c.x()) * reciprocal;
+ if (nb < 0 || nb > 1)
+ return UnboundedIntersection;
+
+ return BoundedIntersection;
+}
+
+/*!
+ \fn void QLineF::translate(const QPointF &offset)
+
+ Translates this line by the given \a offset.
+*/
+
+/*!
+ \fn void QLineF::translate(qreal dx, qreal dy)
+ \overload
+
+ Translates this line the distance specified by \a dx and \a dy.
+*/
+
+/*!
+ \fn QLineF QLineF::translated(const QPointF &offset) const
+
+ \since 4.4
+
+ Returns this line translated by the given \a offset.
+*/
+
+/*!
+ \fn QLineF QLineF::translated(qreal dx, qreal dy) const
+ \overload
+ \since 4.4
+
+ Returns this line translated the distance specified by \a dx and \a dy.
+*/
+
+/*!
+ \fn void QLineF::setP1(const QPointF &p1)
+ \since 4.4
+
+ Sets the starting point of this line to \a p1.
+
+ \sa setP2(), p1()
+*/
+
+
+/*!
+ \fn void QLineF::setP2(const QPointF &p2)
+ \since 4.4
+
+ Sets the end point of this line to \a p2.
+
+ \sa setP1(), p2()
+*/
+
+
+/*!
+ \fn void QLineF::setPoints(const QPointF &p1, const QPointF &p2)
+ \since 4.4
+
+ Sets the start point of this line to \a p1 and the end point of this line to \a p2.
+
+ \sa setP1(), setP2(), p1(), p2()
+*/
+
+
+/*!
+ \fn void QLineF::setLine(qreal x1, qreal y1, qreal x2, qreal y2)
+ \since 4.4
+
+ Sets this line to the start in \a x1, \a y1 and end in \a x2, \a y2.
+
+ \sa setP1(), setP2(), p1(), p2()
+*/
+
+/*!
+ \fn qreal QLineF::angleTo(const QLineF &line) const
+
+ \since 4.4
+
+ Returns the angle (in degrees) from this line to the given \a
+ line, taking the direction of the lines into account. If the lines
+ do not intersect within their range, it is the intersection point of
+ the extended lines that serves as origin (see
+ QLineF::UnboundedIntersection).
+
+ The returned value represents the number of degrees you need to add
+ to this line to make it have the same angle as the given \a line,
+ going counter-clockwise.
+
+ \sa intersect()
+*/
+qreal QLineF::angleTo(const QLineF &l) const
+{
+ if (isNull() || l.isNull())
+ return 0;
+
+ const qreal a1 = angle();
+ const qreal a2 = l.angle();
+
+ const qreal delta = a2 - a1;
+ const qreal delta_normalized = delta < 0 ? delta + 360 : delta;
+
+ if (qFuzzyCompare(delta, qreal(360)))
+ return 0;
+ else
+ return delta_normalized;
+}
+
+/*!
+ \fn qreal QLineF::angle(const QLineF &line) const
+
+ \obsolete
+
+ Returns the angle (in degrees) between this line and the given \a
+ line, taking the direction of the lines into account. If the lines
+ do not intersect within their range, it is the intersection point of
+ the extended lines that serves as origin (see
+ QLineF::UnboundedIntersection).
+
+ \table
+ \row
+ \o \inlineimage qlinef-angle-identicaldirection.png
+ \o \inlineimage qlinef-angle-oppositedirection.png
+ \endtable
+
+ When the lines are parallel, this function returns 0 if they have
+ the same direction; otherwise it returns 180.
+
+ \sa intersect()
+*/
+qreal QLineF::angle(const QLineF &l) const
+{
+ if (isNull() || l.isNull())
+ return 0;
+ qreal cos_line = (dx()*l.dx() + dy()*l.dy()) / (length()*l.length());
+ qreal rad = 0;
+ // only accept cos_line in the range [-1,1], if it is outside, use 0 (we return 0 rather than PI for those cases)
+ if (cos_line >= -1.0 && cos_line <= 1.0) rad = acos( cos_line );
+ return rad * 360 / M_2PI;
+}
+
+
+#ifndef QT_NO_DEBUG_STREAM
+QDebug operator<<(QDebug d, const QLineF &p)
+{
+ d << "QLineF(" << p.p1() << "," << p.p2() << ")";
+ return d;
+}
+#endif
+
+#ifndef QT_NO_DATASTREAM
+/*!
+ \relates QLineF
+
+ Writes the given \a line to the given \a stream and returns a
+ reference to the stream.
+
+ \sa {Format of the QDataStream Operators}
+*/
+
+QDataStream &operator<<(QDataStream &stream, const QLineF &line)
+{
+ stream << line.p1() << line.p2();
+ return stream;
+}
+
+/*!
+ \relates QLineF
+
+ Reads a line from the given \a stream into the given \a line and
+ returns a reference to the stream.
+
+ \sa {Format of the QDataStream Operators}
+*/
+
+QDataStream &operator>>(QDataStream &stream, QLineF &line)
+{
+ QPointF start, end;
+ stream >> start;
+ stream >> end;
+ line = QLineF(start, end);
+
+ return stream;
+}
+
+#endif // QT_NO_DATASTREAM
+
+QT_END_NAMESPACE
diff --git a/src/corelib/tools/qline.h b/src/corelib/tools/qline.h
new file mode 100644
index 0000000000..e4c8c27795
--- /dev/null
+++ b/src/corelib/tools/qline.h
@@ -0,0 +1,424 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QLINE_H
+#define QLINE_H
+
+#include <QtCore/qpoint.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Core)
+
+/*******************************************************************************
+ * class QLine
+ *******************************************************************************/
+
+class Q_CORE_EXPORT QLine
+{
+public:
+ inline QLine();
+ inline QLine(const QPoint &pt1, const QPoint &pt2);
+ inline QLine(int x1, int y1, int x2, int y2);
+
+ inline bool isNull() const;
+
+ inline QPoint p1() const;
+ inline QPoint p2() const;
+
+ inline int x1() const;
+ inline int y1() const;
+
+ inline int x2() const;
+ inline int y2() const;
+
+ inline int dx() const;
+ inline int dy() const;
+
+ inline void translate(const QPoint &p);
+ inline void translate(int dx, int dy);
+
+ inline QLine translated(const QPoint &p) const;
+ inline QLine translated(int dx, int dy) const;
+
+ inline void setP1(const QPoint &p1);
+ inline void setP2(const QPoint &p2);
+ inline void setPoints(const QPoint &p1, const QPoint &p2);
+ inline void setLine(int x1, int y1, int x2, int y2);
+
+ inline bool operator==(const QLine &d) const;
+ inline bool operator!=(const QLine &d) const { return !(*this == d); }
+
+private:
+ QPoint pt1, pt2;
+};
+Q_DECLARE_TYPEINFO(QLine, Q_MOVABLE_TYPE);
+
+/*******************************************************************************
+ * class QLine inline members
+ *******************************************************************************/
+
+inline QLine::QLine() { }
+
+inline QLine::QLine(const QPoint &pt1_, const QPoint &pt2_) : pt1(pt1_), pt2(pt2_) { }
+
+inline QLine::QLine(int x1pos, int y1pos, int x2pos, int y2pos) : pt1(QPoint(x1pos, y1pos)), pt2(QPoint(x2pos, y2pos)) { }
+
+inline bool QLine::isNull() const
+{
+ return pt1 == pt2;
+}
+
+inline int QLine::x1() const
+{
+ return pt1.x();
+}
+
+inline int QLine::y1() const
+{
+ return pt1.y();
+}
+
+inline int QLine::x2() const
+{
+ return pt2.x();
+}
+
+inline int QLine::y2() const
+{
+ return pt2.y();
+}
+
+inline QPoint QLine::p1() const
+{
+ return pt1;
+}
+
+inline QPoint QLine::p2() const
+{
+ return pt2;
+}
+
+inline int QLine::dx() const
+{
+ return pt2.x() - pt1.x();
+}
+
+inline int QLine::dy() const
+{
+ return pt2.y() - pt1.y();
+}
+
+inline void QLine::translate(const QPoint &point)
+{
+ pt1 += point;
+ pt2 += point;
+}
+
+inline void QLine::translate(int adx, int ady)
+{
+ this->translate(QPoint(adx, ady));
+}
+
+inline QLine QLine::translated(const QPoint &p) const
+{
+ return QLine(pt1 + p, pt2 + p);
+}
+
+inline QLine QLine::translated(int adx, int ady) const
+{
+ return translated(QPoint(adx, ady));
+}
+
+inline void QLine::setP1(const QPoint &aP1)
+{
+ pt1 = aP1;
+}
+
+inline void QLine::setP2(const QPoint &aP2)
+{
+ pt2 = aP2;
+}
+
+inline void QLine::setPoints(const QPoint &aP1, const QPoint &aP2)
+{
+ pt1 = aP1;
+ pt2 = aP2;
+}
+
+inline void QLine::setLine(int aX1, int aY1, int aX2, int aY2)
+{
+ pt1 = QPoint(aX1, aY1);
+ pt2 = QPoint(aX2, aY2);
+}
+
+inline bool QLine::operator==(const QLine &d) const
+{
+ return pt1 == d.pt1 && pt2 == d.pt2;
+}
+
+#ifndef QT_NO_DEBUG_STREAM
+Q_CORE_EXPORT QDebug operator<<(QDebug d, const QLine &p);
+#endif
+
+#ifndef QT_NO_DATASTREAM
+Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QLine &);
+Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QLine &);
+#endif
+
+/*******************************************************************************
+ * class QLineF
+ *******************************************************************************/
+class Q_CORE_EXPORT QLineF {
+public:
+
+ enum IntersectType { NoIntersection, BoundedIntersection, UnboundedIntersection };
+
+ inline QLineF();
+ inline QLineF(const QPointF &pt1, const QPointF &pt2);
+ inline QLineF(qreal x1, qreal y1, qreal x2, qreal y2);
+ inline QLineF(const QLine &line) : pt1(line.p1()), pt2(line.p2()) { }
+
+ static QLineF fromPolar(qreal length, qreal angle);
+
+ bool isNull() const;
+
+ inline QPointF p1() const;
+ inline QPointF p2() const;
+
+ inline qreal x1() const;
+ inline qreal y1() const;
+
+ inline qreal x2() const;
+ inline qreal y2() const;
+
+ inline qreal dx() const;
+ inline qreal dy() const;
+
+ qreal length() const;
+ void setLength(qreal len);
+
+ qreal angle() const;
+ void setAngle(qreal angle);
+
+ qreal angleTo(const QLineF &l) const;
+
+ QLineF unitVector() const;
+ QLineF normalVector() const;
+
+ // ### Qt 5: rename intersects() or intersection() and rename IntersectType IntersectionType
+ IntersectType intersect(const QLineF &l, QPointF *intersectionPoint) const;
+
+ qreal angle(const QLineF &l) const;
+
+ QPointF pointAt(qreal t) const;
+ inline void translate(const QPointF &p);
+ inline void translate(qreal dx, qreal dy);
+
+ inline QLineF translated(const QPointF &p) const;
+ inline QLineF translated(qreal dx, qreal dy) const;
+
+ inline void setP1(const QPointF &p1);
+ inline void setP2(const QPointF &p2);
+ inline void setPoints(const QPointF &p1, const QPointF &p2);
+ inline void setLine(qreal x1, qreal y1, qreal x2, qreal y2);
+
+ inline bool operator==(const QLineF &d) const;
+ inline bool operator!=(const QLineF &d) const { return !(*this == d); }
+
+ QLine toLine() const;
+
+private:
+ QPointF pt1, pt2;
+};
+Q_DECLARE_TYPEINFO(QLineF, Q_MOVABLE_TYPE);
+
+/*******************************************************************************
+ * class QLineF inline members
+ *******************************************************************************/
+
+inline QLineF::QLineF()
+{
+}
+
+inline QLineF::QLineF(const QPointF &apt1, const QPointF &apt2)
+ : pt1(apt1), pt2(apt2)
+{
+}
+
+inline QLineF::QLineF(qreal x1pos, qreal y1pos, qreal x2pos, qreal y2pos)
+ : pt1(x1pos, y1pos), pt2(x2pos, y2pos)
+{
+}
+
+inline qreal QLineF::x1() const
+{
+ return pt1.x();
+}
+
+inline qreal QLineF::y1() const
+{
+ return pt1.y();
+}
+
+inline qreal QLineF::x2() const
+{
+ return pt2.x();
+}
+
+inline qreal QLineF::y2() const
+{
+ return pt2.y();
+}
+
+inline QPointF QLineF::p1() const
+{
+ return pt1;
+}
+
+inline QPointF QLineF::p2() const
+{
+ return pt2;
+}
+
+inline qreal QLineF::dx() const
+{
+ return pt2.x() - pt1.x();
+}
+
+inline qreal QLineF::dy() const
+{
+ return pt2.y() - pt1.y();
+}
+
+inline QLineF QLineF::normalVector() const
+{
+ return QLineF(p1(), p1() + QPointF(dy(), -dx()));
+}
+
+inline void QLineF::translate(const QPointF &point)
+{
+ pt1 += point;
+ pt2 += point;
+}
+
+inline void QLineF::translate(qreal adx, qreal ady)
+{
+ this->translate(QPointF(adx, ady));
+}
+
+inline QLineF QLineF::translated(const QPointF &p) const
+{
+ return QLineF(pt1 + p, pt2 + p);
+}
+
+inline QLineF QLineF::translated(qreal adx, qreal ady) const
+{
+ return translated(QPointF(adx, ady));
+}
+
+inline void QLineF::setLength(qreal len)
+{
+ if (isNull())
+ return;
+ QLineF v = unitVector();
+ pt2 = QPointF(pt1.x() + v.dx() * len, pt1.y() + v.dy() * len);
+}
+
+inline QPointF QLineF::pointAt(qreal t) const
+{
+ qreal vx = pt2.x() - pt1.x();
+ qreal vy = pt2.y() - pt1.y();
+ return QPointF(pt1.x() + vx * t, pt1.y() + vy * t);
+}
+
+inline QLine QLineF::toLine() const
+{
+ return QLine(pt1.toPoint(), pt2.toPoint());
+}
+
+
+inline void QLineF::setP1(const QPointF &aP1)
+{
+ pt1 = aP1;
+}
+
+inline void QLineF::setP2(const QPointF &aP2)
+{
+ pt2 = aP2;
+}
+
+inline void QLineF::setPoints(const QPointF &aP1, const QPointF &aP2)
+{
+ pt1 = aP1;
+ pt2 = aP2;
+}
+
+inline void QLineF::setLine(qreal aX1, qreal aY1, qreal aX2, qreal aY2)
+{
+ pt1 = QPointF(aX1, aY1);
+ pt2 = QPointF(aX2, aY2);
+}
+
+
+inline bool QLineF::operator==(const QLineF &d) const
+{
+ return pt1 == d.pt1 && pt2 == d.pt2;
+}
+
+
+
+#ifndef QT_NO_DEBUG_STREAM
+Q_CORE_EXPORT QDebug operator<<(QDebug d, const QLineF &p);
+#endif
+
+#ifndef QT_NO_DATASTREAM
+Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QLineF &);
+Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QLineF &);
+#endif
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QLINE_H
diff --git a/src/corelib/tools/qlinkedlist.cpp b/src/corelib/tools/qlinkedlist.cpp
new file mode 100644
index 0000000000..a3cbecc99d
--- /dev/null
+++ b/src/corelib/tools/qlinkedlist.cpp
@@ -0,0 +1,1158 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qlinkedlist.h"
+
+QT_BEGIN_NAMESPACE
+
+QLinkedListData QLinkedListData::shared_null = {
+ &QLinkedListData::shared_null, &QLinkedListData::shared_null,
+ Q_BASIC_ATOMIC_INITIALIZER(1), 0, true
+};
+
+/*! \class QLinkedList
+ \brief The QLinkedList class is a template class that provides linked lists.
+
+ \ingroup tools
+ \ingroup shared
+ \mainclass
+ \reentrant
+
+ QLinkedList\<T\> is one of Qt's generic \l{container classes}. It
+ stores a list of values and provides iterator-based access as
+ well as \l{constant time} insertions and removals.
+
+ QList\<T\>, QLinkedList\<T\>, and QVector\<T\> provide similar
+ functionality. Here's an overview:
+
+ \list
+ \i For most purposes, QList is the right class to use. Its
+ index-based API is more convenient than QLinkedList's
+ iterator-based API, and it is usually faster than
+ QVector because of the way it stores its items in
+ memory (see \l{Algorithmic Complexity} for details).
+ It also expands to less code in your executable.
+ \i If you need a real linked list, with guarantees of \l{constant
+ time} insertions in the middle of the list and iterators to
+ items rather than indexes, use QLinkedList.
+ \i If you want the items to occupy adjacent memory positions,
+ use QVector.
+ \endlist
+
+ Here's an example of a QLinkedList that stores integers and a
+ QLinkedList that stores QTime values:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qlinkedlist.cpp 0
+
+ QLinkedList stores a list of items. The default constructor
+ creates an empty list. To insert items into the list, you can use
+ operator<<():
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qlinkedlist.cpp 1
+
+ If you want to get the first or last item in a linked list, use
+ first() or last(). If you want to remove an item from either end
+ of the list, use removeFirst() or removeLast(). If you want to
+ remove all occurrences of a given value in the list, use
+ removeAll().
+
+ A common requirement is to remove the first or last item in the
+ list and do something with it. For this, QLinkedList provides
+ takeFirst() and takeLast(). Here's a loop that removes the items
+ from a list one at a time and calls \c delete on them:
+ \snippet doc/src/snippets/code/src_corelib_tools_qlinkedlist.cpp 2
+
+ QLinkedList's value type must be an \l {assignable data type}. This
+ covers most data types that are commonly used, but the compiler
+ won't let you, for example, store a QWidget as a value; instead,
+ store a QWidget *. A few functions have additional requirements;
+ for example, contains() and removeAll() expect the value type to
+ support \c operator==(). These requirements are documented on a
+ per-function basis.
+
+ If you want to insert, modify, or remove items in the middle of
+ the list, you must use an iterator. QLinkedList provides both
+ \l{Java-style iterators} (QLinkedListIterator and
+ QMutableLinkedListIterator) and \l{STL-style iterators}
+ (QLinkedList::const_iterator and QLinkedList::iterator). See the
+ documentation for these classes for details.
+
+ \sa QLinkedListIterator, QMutableLinkedListIterator, QList, QVector
+*/
+
+/*! \fn QLinkedList::QLinkedList()
+
+ Constructs an empty list.
+*/
+
+/*! \fn QLinkedList::QLinkedList(const QLinkedList<T> &other)
+
+ Constructs a copy of \a other.
+
+ This operation occurs in \l{constant time}, because QLinkedList
+ is \l{implicitly shared}. This makes returning a QLinkedList from
+ a function very fast. If a shared instance is modified, it will
+ be copied (copy-on-write), and this takes \l{linear time}.
+
+ \sa operator=()
+*/
+
+/*! \fn QLinkedList::~QLinkedList()
+
+ Destroys the list. References to the values in the list, and all
+ iterators over this list, become invalid.
+*/
+
+/*! \fn QLinkedList<T> &QLinkedList::operator=(const QLinkedList<T> &other)
+
+ Assigns \a other to this list and returns a reference to this
+ list.
+*/
+
+/*! \fn bool QLinkedList::operator==(const QLinkedList<T> &other) const
+
+ Returns true if \a other is equal to this list; otherwise returns
+ false.
+
+ Two lists are considered equal if they contain the same values in
+ the same order.
+
+ This function requires the value type to implement \c
+ operator==().
+
+ \sa operator!=()
+*/
+
+/*! \fn bool QLinkedList::operator!=(const QLinkedList<T> &other) const
+
+ Returns true if \a other is not equal to this list; otherwise
+ returns false.
+
+ Two lists are considered equal if they contain the same values in
+ the same order.
+
+ This function requires the value type to implement \c
+ operator==().
+
+ \sa operator==()
+*/
+
+/*! \fn int QLinkedList::size() const
+
+ Returns the number of items in the list.
+
+ \sa isEmpty(), count()
+*/
+
+/*! \fn void QLinkedList::detach()
+
+ \internal
+*/
+
+/*! \fn bool QLinkedList::isDetached() const
+
+ \internal
+*/
+
+/*! \fn void QLinkedList::setSharable(bool sharable)
+
+ \internal
+*/
+
+/*! \fn bool QLinkedList::isEmpty() const
+
+ Returns true if the list contains no items; otherwise returns
+ false.
+
+ \sa size()
+*/
+
+/*! \fn void QLinkedList::clear()
+
+ Removes all the items in the list.
+
+ \sa removeAll()
+*/
+
+/*! \fn void QLinkedList::append(const T &value)
+
+ Inserts \a value at the end of the list.
+
+ Example:
+ \snippet doc/src/snippets/code/src_corelib_tools_qlinkedlist.cpp 3
+
+ This is the same as list.insert(end(), \a value).
+
+ \sa operator<<(), prepend(), insert()
+*/
+
+/*! \fn void QLinkedList::prepend(const T &value)
+
+ Inserts \a value at the beginning of the list.
+
+ Example:
+ \snippet doc/src/snippets/code/src_corelib_tools_qlinkedlist.cpp 4
+
+ This is the same as list.insert(begin(), \a value).
+
+ \sa append(), insert()
+*/
+
+/*! \fn int QLinkedList::removeAll(const T &value)
+
+ Removes all occurrences of \a value in the list.
+
+ Example:
+ \snippet doc/src/snippets/code/src_corelib_tools_qlinkedlist.cpp 5
+
+ This function requires the value type to have an implementation of
+ \c operator==().
+
+ \sa insert()
+*/
+
+/*!
+ \fn bool QLinkedList::removeOne(const T &value)
+ \since 4.4
+
+ Removes the first occurrences of \a value in the list. Returns true on
+ success; otherwise returns false.
+
+ Example:
+ \snippet doc/src/snippets/code/src_corelib_tools_qlinkedlist.cpp 6
+
+ This function requires the value type to have an implementation of
+ \c operator==().
+
+ \sa insert()
+*/
+
+/*! \fn bool QLinkedList::contains(const T &value) const
+
+ Returns true if the list contains an occurrence of \a value;
+ otherwise returns false.
+
+ This function requires the value type to have an implementation of
+ \c operator==().
+
+ \sa QLinkedListIterator::findNext(), QLinkedListIterator::findPrevious()
+*/
+
+/*! \fn int QLinkedList::count(const T &value) const
+
+ Returns the number of occurrences of \a value in the list.
+
+ This function requires the value type to have an implementation of
+ \c operator==().
+
+ \sa contains()
+*/
+
+/*! \fn bool QLinkedList::startsWith(const T &value) const
+ \since 4.5
+
+ Returns true if the list is not empty and its first
+ item is equal to \a value; otherwise returns false.
+
+ \sa isEmpty(), first()
+*/
+
+/*! \fn bool QLinkedList::endsWith(const T &value) const
+ \since 4.5
+
+ Returns true if the list is not empty and its last
+ item is equal to \a value; otherwise returns false.
+
+ \sa isEmpty(), last()
+*/
+
+/*! \fn QLinkedList::iterator QLinkedList::begin()
+
+ Returns an \l{STL-style iterator} pointing to the first item in
+ the list.
+
+ \sa constBegin(), end()
+*/
+
+/*! \fn QLinkedList::const_iterator QLinkedList::begin() const
+
+ \overload
+*/
+
+/*! \fn QLinkedList::const_iterator QLinkedList::constBegin() const
+
+ Returns a const \l{STL-style iterator} pointing to the first item
+ in the list.
+
+ \sa begin(), constEnd()
+*/
+
+/*! \fn QLinkedList::iterator QLinkedList::end()
+
+ Returns an \l{STL-style iterator} pointing to the imaginary item
+ after the last item in the list.
+
+ \sa begin(), constEnd()
+*/
+
+/*! \fn QLinkedList::const_iterator QLinkedList::end() const
+
+ \overload
+*/
+
+/*! \fn QLinkedList::const_iterator QLinkedList::constEnd() const
+
+ Returns a const \l{STL-style iterator} pointing to the imaginary
+ item after the last item in the list.
+
+ \sa constBegin(), end()
+*/
+
+/*! \fn QLinkedList::iterator QLinkedList::insert(iterator before, const T &value)
+
+ Inserts \a value in front of the item pointed to by the iterator
+ \a before. Returns an iterator pointing at the inserted item.
+
+ \sa erase()
+*/
+
+/*! \fn QLinkedList::iterator QLinkedList::erase(iterator pos)
+
+ Removes the item pointed to by the iterator \a pos from the list,
+ and returns an iterator to the next item in the list (which may be
+ end()).
+
+ \sa insert()
+*/
+
+/*! \fn QLinkedList::iterator QLinkedList::erase(iterator begin, iterator end)
+
+ \overload
+
+ Removes all the items from \a begin up to (but not including) \a
+ end.
+*/
+
+/*! \typedef QLinkedList::Iterator
+
+ Qt-style synonym for QLinkedList::iterator.
+*/
+
+/*! \typedef QLinkedList::ConstIterator
+
+ Qt-style synonym for QLinkedList::const_iterator.
+*/
+
+/*!
+ \typedef QLinkedList::size_type
+
+ Typedef for int. Provided for STL compatibility.
+*/
+
+/*!
+ \typedef QLinkedList::value_type
+
+ Typedef for T. Provided for STL compatibility.
+*/
+
+/*!
+ \typedef QLinkedList::pointer
+
+ Typedef for T *. Provided for STL compatibility.
+*/
+
+/*!
+ \typedef QLinkedList::const_pointer
+
+ Typedef for const T *. Provided for STL compatibility.
+*/
+
+/*!
+ \typedef QLinkedList::reference
+
+ Typedef for T &. Provided for STL compatibility.
+*/
+
+/*!
+ \typedef QLinkedList::const_reference
+
+ Typedef for const T &. Provided for STL compatibility.
+*/
+
+/*!
+ \typedef QLinkedList::difference_type
+
+ Typedef for ptrdiff_t. Provided for STL compatibility.
+*/
+
+/*! \fn int QLinkedList::count() const
+
+ Same as size().
+*/
+
+/*! \fn T& QLinkedList::first()
+
+ Returns a reference to the first item in the list. This function
+ assumes that the list isn't empty.
+
+ \sa last(), isEmpty()
+*/
+
+/*! \fn const T& QLinkedList::first() const
+
+ \overload
+*/
+
+/*! \fn T& QLinkedList::last()
+
+ Returns a reference to the last item in the list. This function
+ assumes that the list isn't empty.
+
+ \sa first(), isEmpty()
+*/
+
+/*! \fn const T& QLinkedList::last() const
+
+ \overload
+*/
+
+/*! \fn void QLinkedList::removeFirst()
+
+ Removes the first item in the list.
+
+ This is the same as erase(begin()).
+
+ \sa removeLast(), erase()
+*/
+
+/*! \fn void QLinkedList::removeLast()
+
+ Removes the last item in the list.
+
+ \sa removeFirst(), erase()
+*/
+
+/*! \fn T QLinkedList::takeFirst()
+
+ Removes the first item in the list and returns it.
+
+ If you don't use the return value, removeFirst() is more
+ efficient.
+
+ \sa takeLast(), removeFirst()
+*/
+
+/*! \fn T QLinkedList::takeLast()
+
+ Removes the last item in the list and returns it.
+
+ If you don't use the return value, removeLast() is more
+ efficient.
+
+ \sa takeFirst(), removeLast()
+*/
+
+/*! \fn void QLinkedList::push_back(const T &value)
+
+ This function is provided for STL compatibility. It is equivalent
+ to append(\a value).
+*/
+
+/*! \fn void QLinkedList::push_front(const T &value)
+
+ This function is provided for STL compatibility. It is equivalent
+ to prepend(\a value).
+*/
+
+/*! \fn T& QLinkedList::front()
+
+ This function is provided for STL compatibility. It is equivalent
+ to first().
+*/
+
+/*! \fn const T& QLinkedList::front() const
+
+ \overload
+*/
+
+/*! \fn T& QLinkedList::back()
+
+ This function is provided for STL compatibility. It is equivalent
+ to last().
+*/
+
+/*! \fn const T& QLinkedList::back() const
+
+ \overload
+*/
+
+/*! \fn void QLinkedList::pop_front()
+
+ This function is provided for STL compatibility. It is equivalent
+ to removeFirst().
+*/
+
+/*! \fn void QLinkedList::pop_back()
+
+ This function is provided for STL compatibility. It is equivalent
+ to removeLast().
+*/
+
+/*! \fn bool QLinkedList::empty() const
+
+ This function is provided for STL compatibility. It is equivalent
+ to isEmpty() and returns true if the list is empty.
+*/
+
+/*! \fn QLinkedList<T> &QLinkedList::operator+=(const QLinkedList<T> &other)
+
+ Appends the items of the \a other list to this list and returns a
+ reference to this list.
+
+ \sa operator+(), append()
+*/
+
+/*! \fn void QLinkedList::operator+=(const T &value)
+
+ \overload
+
+ Appends \a value to the list.
+*/
+
+/*! \fn QLinkedList<T> QLinkedList::operator+(const QLinkedList<T> &other) const
+
+ Returns a list that contains all the items in this list followed
+ by all the items in the \a other list.
+
+ \sa operator+=()
+*/
+
+/*! \fn QLinkedList<T> &QLinkedList::operator<<(const QLinkedList<T> &other)
+
+ Appends the items of the \a other list to this list and returns a
+ reference to this list.
+
+ \sa operator+=(), append()
+*/
+
+/*! \fn QLinkedList<T> &QLinkedList::operator<<(const T &value)
+
+ \overload
+
+ Appends \a value to the list.
+*/
+
+/*! \class QLinkedList::iterator
+ \brief The QLinkedList::iterator class provides an STL-style non-const iterator for QLinkedList.
+
+ QLinkedList features both \l{STL-style iterators} and
+ \l{Java-style iterators}. The STL-style iterators are more
+ low-level and more cumbersome to use; on the other hand, they are
+ slightly faster and, for developers who already know STL, have
+ the advantage of familiarity.
+
+ QLinkedList\<T\>::iterator allows you to iterate over a
+ QLinkedList\<T\> and to modify the list item associated with the
+ iterator. If you want to iterate over a const QLinkedList, use
+ QLinkedList::const_iterator instead. It is generally good
+ practice to use QLinkedList::const_iterator on a non-const
+ QLinkedList as well, unless you need to change the QLinkedList
+ through the iterator. Const iterators are slightly faster, and
+ can improve code readability.
+
+ The default QLinkedList::iterator constructor creates an
+ uninitialized iterator. You must initialize it using a
+ function like QLinkedList::begin(), QLinkedList::end(), or
+ QLinkedList::insert() before you can start iterating. Here's a
+ typical loop that prints all the items stored in a list:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qlinkedlist.cpp 7
+
+ STL-style iterators can be used as arguments to \l{generic
+ algorithms}. For example, here's how to find an item in the list
+ using the qFind() algorithm:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qlinkedlist.cpp 8
+
+ Let's see a few examples of things we can do with a
+ QLinkedList::iterator that we cannot do with a QLinkedList::const_iterator.
+ Here's an example that increments every value stored in a
+ QLinkedList\<int\> by 2:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qlinkedlist.cpp 9
+
+ Here's an example that removes all the items that start with an
+ underscore character in a QLinkedList\<QString\>:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qlinkedlist.cpp 10
+
+ The call to QLinkedList::erase() removes the item pointed to by
+ the iterator from the list, and returns an iterator to the next
+ item. Here's another way of removing an item while iterating:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qlinkedlist.cpp 11
+
+ It might be tempting to write code like this:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qlinkedlist.cpp 12
+
+ However, this will potentially crash in \c{++i}, because \c i is
+ a dangling iterator after the call to erase().
+
+ Multiple iterators can be used on the same list. If you add items
+ to the list, existing iterators will remain valid. If you remove
+ items from the list, iterators that point to the removed items
+ will become dangling iterators. However, because of how \l{implicit
+ sharing} works, you must not take a copy of a container while
+ iterators are active on that container.
+
+ \sa QLinkedList::const_iterator, QMutableLinkedListIterator
+*/
+
+/*! \fn QLinkedList::iterator::iterator()
+
+ Constructs an uninitialized iterator.
+
+ Functions like operator*() and operator++() should not be called
+ on an uninitialized iterartor. Use operator=() to assign a value
+ to it before using it.
+
+ \sa QLinkedList::begin() QLinkedList::end()
+*/
+
+/*! \fn QLinkedList::iterator::iterator(Node *node)
+
+ \internal
+*/
+
+/*! \typedef QLinkedList::iterator::iterator_category
+
+ \internal
+*/
+
+/*! \typedef QLinkedList::iterator::difference_type
+
+ \internal
+*/
+
+/*! \typedef QLinkedList::iterator::value_type
+
+ \internal
+*/
+
+/*! \typedef QLinkedList::iterator::pointer
+
+ \internal
+*/
+
+/*! \typedef QLinkedList::iterator::reference
+
+ \internal
+*/
+
+/*! \fn QLinkedList::iterator::iterator(const iterator &other)
+
+ Constructs a copy of \a other.
+*/
+
+/*! \fn QLinkedList::iterator &QLinkedList::iterator::operator=(const iterator &other)
+
+ Assigns \a other to this iterator.
+*/
+
+/*! \fn T &QLinkedList::iterator::operator*() const
+
+ Returns a modifiable reference to the current item.
+
+ You can change the value of an item by using operator*() on the
+ left side of an assignment, for example:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qlinkedlist.cpp 13
+
+ \sa operator->()
+*/
+
+/*! \fn T *QLinkedList::iterator::operator->() const
+
+ Returns a pointer to the current item.
+
+ \sa operator*()
+*/
+
+/*!
+ \fn bool QLinkedList::iterator::operator==(const iterator &other) const
+ \fn bool QLinkedList::iterator::operator==(const const_iterator &other) const
+
+ Returns true if \a other points to the same item as this
+ iterator; otherwise returns false.
+
+ \sa operator!=()
+*/
+
+/*!
+ \fn bool QLinkedList::iterator::operator!=(const iterator &other) const
+ \fn bool QLinkedList::iterator::operator!=(const const_iterator &other) const
+
+ Returns true if \a other points to a different item than this
+ iterator; otherwise returns false.
+
+ \sa operator==()
+*/
+
+/*! \fn QLinkedList::iterator &QLinkedList::iterator::operator++()
+
+ The prefix ++ operator (\c{++it}) advances the iterator to the
+ next item in the list and returns an iterator to the new current
+ item.
+
+ Calling this function on QLinkedList::end() leads to undefined
+ results.
+
+ \sa operator--()
+*/
+
+/*! \fn QLinkedList::iterator QLinkedList::iterator::operator++(int)
+
+ \overload
+
+ The postfix ++ operator (\c{it++}) advances the iterator to the
+ next item in the list and returns an iterator to the previously
+ current item.
+*/
+
+/*! \fn QLinkedList::iterator &QLinkedList::iterator::operator--()
+
+ The prefix -- operator (\c{--it}) makes the preceding item
+ current and returns an iterator to the new current item.
+
+ Calling this function on QLinkedList::begin() leads to undefined
+ results.
+
+ \sa operator++()
+*/
+
+/*! \fn QLinkedList::iterator QLinkedList::iterator::operator--(int)
+
+ \overload
+
+ The postfix -- operator (\c{it--}) makes the preceding item
+ current and returns an iterator to the previously current item.
+*/
+
+/*! \fn QLinkedList::iterator QLinkedList::iterator::operator+(int j) const
+
+ Returns an iterator to the item at \a j positions forward from
+ this iterator. (If \a j is negative, the iterator goes backward.)
+
+ This operation can be slow for large \a j values.
+
+ \sa operator-()
+
+*/
+
+/*! \fn QLinkedList::iterator QLinkedList::iterator::operator-(int j) const
+
+ Returns an iterator to the item at \a j positions backward from
+ this iterator. (If \a j is negative, the iterator goes forward.)
+
+ This operation can be slow for large \a j values.
+
+ \sa operator+()
+*/
+
+/*! \fn QLinkedList::iterator &QLinkedList::iterator::operator+=(int j)
+
+ Advances the iterator by \a j items. (If \a j is negative, the
+ iterator goes backward.)
+
+ \sa operator-=(), operator+()
+*/
+
+/*! \fn QLinkedList::iterator &QLinkedList::iterator::operator-=(int j)
+
+ Makes the iterator go back by \a j items. (If \a j is negative,
+ the iterator goes forward.)
+
+ \sa operator+=(), operator-()
+*/
+
+/*! \class QLinkedList::const_iterator
+ \brief The QLinkedList::const_iterator class provides an STL-style const iterator for QLinkedList.
+
+ QLinkedList features both \l{STL-style iterators} and
+ \l{Java-style iterators}. The STL-style iterators are more
+ low-level and more cumbersome to use; on the other hand, they are
+ slightly faster and, for developers who already know STL, have
+ the advantage of familiarity.
+
+ QLinkedList\<T\>::const_iterator allows you to iterate over a
+ QLinkedList\<T\>. If you want modify the QLinkedList as you iterate
+ over it, you must use QLinkedList::const_iterator instead. It is
+ generally good practice to use QLinkedList::const_iterator on a
+ non-const QLinkedList as well, unless you need to change the
+ QLinkedList through the iterator. Const iterators are slightly
+ faster, and can improve code readability.
+
+ The default QLinkedList::const_iterator constructor creates an
+ uninitialized iterator. You must initialize it using a function
+ like QLinkedList::constBegin(), QLinkedList::constEnd(), or
+ QLinkedList::insert() before you can start iterating. Here's a
+ typical loop that prints all the items stored in a list:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qlinkedlist.cpp 14
+
+ STL-style iterators can be used as arguments to \l{generic
+ algorithms}. For example, here's how to find an item in the list
+ using the qFind() algorithm:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qlinkedlist.cpp 15
+
+ Multiple iterators can be used on the same list. If you add items
+ to the list, existing iterators will remain valid. If you remove
+ items from the list, iterators that point to the removed items
+ will become dangling iterators.
+
+ \sa QLinkedList::iterator, QLinkedListIterator
+*/
+
+/*! \fn QLinkedList::const_iterator::const_iterator()
+
+ Constructs an uninitialized iterator.
+
+ Functions like operator*() and operator++() should not be called
+ on an uninitialized iterartor. Use operator=() to assign a value
+ to it before using it.
+
+ \sa QLinkedList::constBegin() QLinkedList::constEnd()
+*/
+
+/*! \fn QLinkedList::const_iterator::const_iterator(Node *node)
+
+ \internal
+*/
+
+/*! \typedef QLinkedList::const_iterator::iterator_category
+
+ \internal
+*/
+
+/*! \typedef QLinkedList::const_iterator::difference_type
+
+ \internal
+*/
+
+/*! \typedef QLinkedList::const_iterator::value_type
+
+ \internal
+*/
+
+/*! \typedef QLinkedList::const_iterator::pointer
+
+ \internal
+*/
+
+/*! \typedef QLinkedList::const_iterator::reference
+
+ \internal
+*/
+
+/*! \fn QLinkedList::const_iterator::const_iterator(const const_iterator &other)
+
+ Constructs a copy of \a other.
+*/
+
+/*! \fn QLinkedList::const_iterator::const_iterator(iterator other)
+
+ Constructs a copy of \a other.
+*/
+
+/*! \fn QLinkedList::const_iterator &QLinkedList::const_iterator::operator=( \
+ const const_iterator &other)
+
+ Assigns \a other to this iterator.
+*/
+
+/*! \fn const T &QLinkedList::const_iterator::operator*() const
+
+ Returns a reference to the current item.
+
+ \sa operator->()
+*/
+
+/*! \fn const T *QLinkedList::const_iterator::operator->() const
+
+ Returns a pointer to the current item.
+
+ \sa operator*()
+*/
+
+/*! \fn bool QLinkedList::const_iterator::operator==(const const_iterator &other) const
+
+ Returns true if \a other points to the same item as this
+ iterator; otherwise returns false.
+
+ \sa operator!=()
+*/
+
+/*! \fn bool QLinkedList::const_iterator::operator!=(const const_iterator &other) const
+
+ Returns true if \a other points to a different item than this
+ iterator; otherwise returns false.
+
+ \sa operator==()
+*/
+
+/*! \fn QLinkedList::const_iterator &QLinkedList::const_iterator::operator++()
+
+ The prefix ++ operator (\c{++it}) advances the iterator to the
+ next item in the list and returns an iterator to the new current
+ item.
+
+ Calling this function on QLinkedList::constEnd() leads to
+ undefined results.
+
+ \sa operator--()
+*/
+
+/*! \fn QLinkedList::const_iterator QLinkedList::const_iterator::operator++(int)
+
+ \overload
+
+ The postfix ++ operator (\c{it++}) advances the iterator to the
+ next item in the list and returns an iterator to the previously
+ current item.
+*/
+
+/*! \fn QLinkedList::const_iterator &QLinkedList::const_iterator::operator--()
+
+ The prefix -- operator (\c{--it}) makes the preceding item
+ current and returns an iterator to the new current item.
+
+ Calling this function on QLinkedList::begin() leads to undefined
+ results.
+
+ \sa operator++()
+*/
+
+/*! \fn QLinkedList::const_iterator QLinkedList::const_iterator::operator--(int)
+
+ \overload
+
+ The postfix -- operator (\c{it--}) makes the preceding item
+ current and returns an iterator to the previously current item.
+*/
+
+/*! \fn QLinkedList::const_iterator QLinkedList::const_iterator::operator+(int j) const
+
+ Returns an iterator to the item at \a j positions forward from
+ this iterator. (If \a j is negative, the iterator goes backward.)
+
+ This operation can be slow for large \a j values.
+
+ \sa operator-()
+*/
+
+/*! \fn QLinkedList::const_iterator QLinkedList::const_iterator::operator-(int j) const
+
+ This function returns an iterator to the item at \a j positions backward from
+ this iterator. (If \a j is negative, the iterator goes forward.)
+
+ This operation can be slow for large \a j values.
+
+ \sa operator+()
+*/
+
+/*! \fn QLinkedList::const_iterator &QLinkedList::const_iterator::operator+=(int j)
+
+ Advances the iterator by \a j items. (If \a j is negative, the
+ iterator goes backward.)
+
+ This operation can be slow for large \a j values.
+
+ \sa operator-=(), operator+()
+*/
+
+/*! \fn QLinkedList::const_iterator &QLinkedList::const_iterator::operator-=(int j)
+
+ Makes the iterator go back by \a j items. (If \a j is negative,
+ the iterator goes forward.)
+
+ This operation can be slow for large \a j values.
+
+ \sa operator+=(), operator-()
+*/
+
+/*! \fn QDataStream &operator<<(QDataStream &out, const QLinkedList<T> &list)
+ \relates QLinkedList
+
+ Writes the linked list \a list to stream \a out.
+
+ This function requires the value type to implement \c
+ operator<<().
+
+ \sa \link datastreamformat.html Format of the QDataStream operators \endlink
+*/
+
+/*! \fn QDataStream &operator>>(QDataStream &in, QLinkedList<T> &list)
+ \relates QLinkedList
+
+ Reads a linked list from stream \a in into \a list.
+
+ This function requires the value type to implement \c operator>>().
+
+ \sa \link datastreamformat.html Format of the QDataStream operators \endlink
+*/
+
+/*!
+ \fn iterator QLinkedList::remove(iterator pos)
+
+ Use erase() instead.
+*/
+
+/*!
+ \fn int QLinkedList::findIndex(const T& t) const
+
+ If you need indexes then QList or QVector are better choices than
+ QLinkedList.
+
+ \oldcode
+ int index = list->findIndex(value);
+ \newcode
+ int index = 0;
+ bool found = false;
+ for (const_iterator i = list->begin(); i != list->end(); ++i; ++index)
+ if (*i == value) {
+ found = true;
+ break;
+ }
+ if (!found)
+ index = -1;
+ \endcode
+*/
+
+/*!
+ \fn iterator QLinkedList::find(iterator from, const T& t)
+
+ If you need random access to a data structure then QList, QVector,
+ QMap, or QHash, are all better choices than QLinkedList.
+
+ \oldcode
+ QLinkedList::iterator i = list->find(from, value);
+ \newcode
+ QLinkedList::iterator i = from;
+ while (i != list->end() && *i != value)
+ ++i;
+ \endcode
+*/
+
+/*!
+ \fn iterator QLinkedList::find(const T& t)
+
+ If you need random access to a data structure then QList, QVector,
+ QMap, or QHash, are all better choices than QLinkedList.
+
+ \oldcode
+ QLinkedList::iterator i = list->find(value);
+ \newcode
+ QLinkedList::iterator i = list->begin();
+ while (i != list->end() && *i != value)
+ ++i;
+ \endcode
+*/
+
+/*!
+ \fn const_iterator QLinkedList::find(const_iterator from, const T& t) const
+
+ If you need random access to a data structure then QList, QVector,
+ QMap, or QHash, are all better choices than QLinkedList.
+
+ \oldcode
+ QLinkedList::const_iterator i = list->find(from, value);
+ \newcode
+ QLinkedList::const_iterator i = from;
+ while (i != list->end() && *i != value)
+ ++i;
+ \endcode
+*/
+
+/*!
+ \fn const_iterator QLinkedList::find(const T& t) const
+
+ If you need random access to a data structure then QList, QVector,
+ QMap, or QHash, are all better choices than QLinkedList.
+
+ \oldcode
+ QLinkedList::const_iterator i = list->find(value);
+ \newcode
+ QLinkedList::const_iterator i = list->begin();
+ while (i != list->end() && *i != value)
+ ++i;
+ \endcode
+*/
+
+/*!
+ \since 4.1
+ \fn QLinkedList<T> QLinkedList<T>::fromStdList(const std::list<T> &list)
+
+ Returns a QLinkedList object with the data contained in \a list.
+ The order of the elements in the QLinkedList is the same as in \a
+ list.
+
+ Example:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qlinkedlist.cpp 16
+
+ \sa toStdList()
+*/
+
+/*!
+ \since 4.1
+ \fn std::list<T> QLinkedList<T>::toStdList() const
+
+ Returns a std::list object with the data contained in this
+ QLinkedList. Example:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qlinkedlist.cpp 17
+
+ \sa fromStdList()
+*/
+
+QT_END_NAMESPACE
diff --git a/src/corelib/tools/qlinkedlist.h b/src/corelib/tools/qlinkedlist.h
new file mode 100644
index 0000000000..6a8538625b
--- /dev/null
+++ b/src/corelib/tools/qlinkedlist.h
@@ -0,0 +1,504 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QLINKEDLIST_H
+#define QLINKEDLIST_H
+
+#include <QtCore/qiterator.h>
+#include <QtCore/qatomic.h>
+
+#ifndef QT_NO_STL
+#include <iterator>
+#include <list>
+#endif
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Core)
+
+struct Q_CORE_EXPORT QLinkedListData
+{
+ QLinkedListData *n, *p;
+ QBasicAtomicInt ref;
+ int size;
+ uint sharable : 1;
+
+ static QLinkedListData shared_null;
+};
+
+template <typename T>
+struct QLinkedListNode
+{
+ inline QLinkedListNode(const T &arg): t(arg) { }
+ QLinkedListNode *n, *p;
+ T t;
+};
+
+template <class T>
+class QLinkedList
+{
+ typedef QLinkedListNode<T> Node;
+ union { QLinkedListData *d; QLinkedListNode<T> *e; };
+
+public:
+ inline QLinkedList() : d(&QLinkedListData::shared_null) { d->ref.ref(); }
+ inline QLinkedList(const QLinkedList<T> &l) : d(l.d) { d->ref.ref(); if (!d->sharable) detach(); }
+ ~QLinkedList();
+ QLinkedList<T> &operator=(const QLinkedList<T> &);
+ bool operator==(const QLinkedList<T> &l) const;
+ inline bool operator!=(const QLinkedList<T> &l) const { return !(*this == l); }
+
+ inline int size() const { return d->size; }
+ inline void detach()
+ { if (d->ref != 1) detach_helper(); }
+ inline bool isDetached() const { return d->ref == 1; }
+ inline void setSharable(bool sharable) { if (!sharable) detach(); d->sharable = sharable; }
+
+ inline bool isEmpty() const { return d->size == 0; }
+
+ void clear();
+
+ void append(const T &);
+ void prepend(const T &);
+ T takeFirst();
+ T takeLast();
+ int removeAll(const T &t);
+ bool removeOne(const T &t);
+ bool contains(const T &t) const;
+ int count(const T &t) const;
+
+ class const_iterator;
+
+ class iterator
+ {
+ public:
+ typedef std::bidirectional_iterator_tag iterator_category;
+ typedef ptrdiff_t difference_type;
+ typedef T value_type;
+ typedef T *pointer;
+ typedef T &reference;
+ Node *i;
+ inline iterator() : i(0) {}
+ inline iterator(Node *n) : i(n) {}
+ inline iterator(const iterator &o) : i(o.i) {}
+ inline iterator &operator=(const iterator &o) { i = o.i; return *this; }
+ inline T &operator*() const { return i->t; }
+ inline T *operator->() const { return &i->t; }
+ inline bool operator==(const iterator &o) const { return i == o.i; }
+ inline bool operator!=(const iterator &o) const { return i != o.i; }
+ inline bool operator==(const const_iterator &o) const
+ { return i == o.i; }
+ inline bool operator!=(const const_iterator &o) const
+ { return i != o.i; }
+ inline iterator &operator++() { i = i->n; return *this; }
+ inline iterator operator++(int) { Node *n = i; i = i->n; return n; }
+ inline iterator &operator--() { i = i->p; return *this; }
+ inline iterator operator--(int) { Node *n = i; i = i->p; return n; }
+ inline iterator operator+(int j) const
+ { Node *n = i; if (j > 0) while (j--) n = n->n; else while (j++) n = n->p; return n; }
+ inline iterator operator-(int j) const { return operator+(-j); }
+ inline iterator &operator+=(int j) { return *this = *this + j; }
+ inline iterator &operator-=(int j) { return *this = *this - j; }
+ };
+ friend class iterator;
+
+ class const_iterator
+ {
+ public:
+ typedef std::bidirectional_iterator_tag iterator_category;
+ typedef ptrdiff_t difference_type;
+ typedef T value_type;
+ typedef const T *pointer;
+ typedef const T &reference;
+ Node *i;
+ inline const_iterator() : i(0) {}
+ inline const_iterator(Node *n) : i(n) {}
+ inline const_iterator(const const_iterator &o) : i(o.i){}
+ inline const_iterator(iterator ci) : i(ci.i){}
+ inline const_iterator &operator=(const const_iterator &o) { i = o.i; return *this; }
+ inline const T &operator*() const { return i->t; }
+ inline const T *operator->() const { return &i->t; }
+ inline bool operator==(const const_iterator &o) const { return i == o.i; }
+ inline bool operator!=(const const_iterator &o) const { return i != o.i; }
+ inline const_iterator &operator++() { i = i->n; return *this; }
+ inline const_iterator operator++(int) { Node *n = i; i = i->n; return n; }
+ inline const_iterator &operator--() { i = i->p; return *this; }
+ inline const_iterator operator--(int) { Node *n = i; i = i->p; return n; }
+ inline const_iterator operator+(int j) const
+ { Node *n = i; if (j > 0) while (j--) n = n->n; else while (j++) n = n->p; return n; }
+ inline const_iterator operator-(int j) const { return operator+(-j); }
+ inline const_iterator &operator+=(int j) { return *this = *this + j; }
+ inline const_iterator &operator-=(int j) { return *this = *this - j; }
+ };
+ friend class const_iterator;
+
+ // stl style
+ inline iterator begin() { detach(); return e->n; }
+ inline const_iterator begin() const { return e->n; }
+ inline const_iterator constBegin() const { return e->n; }
+ inline iterator end() { detach(); return e; }
+ inline const_iterator end() const { return e; }
+ inline const_iterator constEnd() const { return e; }
+ iterator insert(iterator before, const T &t);
+ iterator erase(iterator pos);
+ iterator erase(iterator first, iterator last);
+
+ // more Qt
+ typedef iterator Iterator;
+ typedef const_iterator ConstIterator;
+ inline int count() const { return d->size; }
+ inline T& first() { Q_ASSERT(!isEmpty()); return *begin(); }
+ inline const T& first() const { Q_ASSERT(!isEmpty()); return *begin(); }
+ T& last() { Q_ASSERT(!isEmpty()); return *(--end()); }
+ const T& last() const { Q_ASSERT(!isEmpty()); return *(--end()); }
+ inline void removeFirst() { Q_ASSERT(!isEmpty()); erase(begin()); }
+ inline void removeLast() { Q_ASSERT(!isEmpty()); erase(--end()); }
+ inline bool startsWith(const T &t) const { return !isEmpty() && first() == t; }
+ inline bool endsWith(const T &t) const { return !isEmpty() && last() == t; }
+
+ // stl compatibility
+ inline void push_back(const T &t) { append(t); }
+ inline void push_front(const T &t) { prepend(t); }
+ inline T& front() { return first(); }
+ inline const T& front() const { return first(); }
+ inline T& back() { return last(); }
+ inline const T& back() const { return last(); }
+ inline void pop_front() { removeFirst(); }
+ inline void pop_back() { removeLast(); }
+ inline bool empty() const { return isEmpty(); }
+ typedef int size_type;
+ typedef T value_type;
+ typedef value_type *pointer;
+ typedef const value_type *const_pointer;
+ typedef value_type &reference;
+ typedef const value_type &const_reference;
+ typedef ptrdiff_t difference_type;
+
+#ifndef QT_NO_STL
+ static inline QLinkedList<T> fromStdList(const std::list<T> &list)
+ { QLinkedList<T> tmp; qCopy(list.begin(), list.end(), std::back_inserter(tmp)); return tmp; }
+ inline std::list<T> toStdList() const
+ { std::list<T> tmp; qCopy(constBegin(), constEnd(), std::back_inserter(tmp)); return tmp; }
+#endif
+
+#ifdef QT3_SUPPORT
+ // compatibility
+ inline QT3_SUPPORT iterator remove(iterator pos) { return erase(pos); }
+ inline QT3_SUPPORT int findIndex(const T& t) const
+ { int i=0; for (const_iterator it = begin(); it != end(); ++it, ++i) if(*it == t) return i; return -1;}
+ inline QT3_SUPPORT iterator find(iterator from, const T& t)
+ { while (from != end() && !(*from == t)) ++from; return from; }
+ inline QT3_SUPPORT iterator find(const T& t)
+ { return find(begin(), t); }
+ inline QT3_SUPPORT const_iterator find(const_iterator from, const T& t) const
+ { while (from != end() && !(*from == t)) ++from; return from; }
+ inline QT3_SUPPORT const_iterator find(const T& t) const
+ { return find(begin(), t); }
+#endif
+
+ // comfort
+ QLinkedList<T> &operator+=(const QLinkedList<T> &l);
+ QLinkedList<T> operator+(const QLinkedList<T> &l) const;
+ inline QLinkedList<T> &operator+=(const T &t) { append(t); return *this; }
+ inline QLinkedList<T> &operator<< (const T &t) { append(t); return *this; }
+ inline QLinkedList<T> &operator<<(const QLinkedList<T> &l) { *this += l; return *this; }
+
+private:
+ void detach_helper();
+ void free(QLinkedListData*);
+};
+
+template <typename T>
+inline QLinkedList<T>::~QLinkedList()
+{
+ if (!d)
+ return;
+ if (!d->ref.deref())
+ free(d);
+}
+
+template <typename T>
+void QLinkedList<T>::detach_helper()
+{
+ union { QLinkedListData *d; Node *e; } x;
+ x.d = new QLinkedListData;
+ x.d->ref = 1;
+ x.d->size = d->size;
+ x.d->sharable = true;
+ Node *i = e->n, *j = x.e;
+ while (i != e) {
+ j->n = new Node(i->t);
+ j->n->p = j;
+ i = i->n;
+ j = j->n;
+ }
+ j->n = x.e;
+ x.e->p = j;
+ if (!d->ref.deref())
+ free(d);
+ d = x.d;
+}
+
+template <typename T>
+void QLinkedList<T>::free(QLinkedListData *x)
+{
+ Node *y = reinterpret_cast<Node*>(x);
+ Node *i = y->n;
+ if (x->ref == 0) {
+ while(i != y) {
+ Node *n = i;
+ i = i->n;
+ delete n;
+ }
+ delete x;
+ }
+}
+
+template <typename T>
+void QLinkedList<T>::clear()
+{
+ *this = QLinkedList<T>();
+}
+
+template <typename T>
+QLinkedList<T> &QLinkedList<T>::operator=(const QLinkedList<T> &l)
+{
+ if (d != l.d) {
+ l.d->ref.ref();
+ if (!d->ref.deref())
+ free(d);
+ d = l.d;
+ if (!d->sharable)
+ detach_helper();
+ }
+ return *this;
+}
+
+template <typename T>
+bool QLinkedList<T>::operator== (const QLinkedList<T> &l) const
+{
+ if (d->size != l.d->size)
+ return false;
+ if (e == l.e)
+ return true;
+ Node *i = e->n;
+ Node *il = l.e->n;
+ while (i != e) {
+ if (! (i->t == il->t))
+ return false;
+ i = i->n;
+ il = il->n;
+ }
+ return true;
+}
+
+template <typename T>
+void QLinkedList<T>::append(const T &t)
+{
+ detach();
+ Node *i = new Node(t);
+ i->n = e;
+ i->p = e->p;
+ i->p->n = i;
+ e->p = i;
+ d->size++;
+}
+
+template <typename T>
+void QLinkedList<T>::prepend(const T &t)
+{
+ detach();
+ Node *i = new Node(t);
+ i->n = e->n;
+ i->p = e;
+ i->n->p = i;
+ e->n = i;
+ d->size++;
+}
+
+template <typename T>
+int QLinkedList<T>::removeAll(const T &_t)
+{
+ detach();
+ const T t = _t;
+ Node *i = e->n;
+ int c = 0;
+ while (i != e) {
+ if (i->t == t) {
+ Node *n = i;
+ i->n->p = i->p;
+ i->p->n = i->n;
+ i = i->n;
+ delete n;
+ c++;
+ } else {
+ i = i->n;
+ }
+ }
+ d->size-=c;
+ return c;
+}
+
+template <typename T>
+bool QLinkedList<T>::removeOne(const T &_t)
+{
+ detach();
+ iterator it = qFind(begin(), end(), _t);
+ if (it != end()) {
+ erase(it);
+ return true;
+ }
+ return false;
+}
+
+template <typename T>
+inline T QLinkedList<T>::takeFirst()
+{
+ T t = first();
+ removeFirst();
+ return t;
+}
+
+template <typename T>
+inline T QLinkedList<T>::takeLast()
+{
+ T t = last();
+ removeLast();
+ return t;
+}
+
+template <typename T>
+bool QLinkedList<T>::contains(const T &t) const
+{
+ Node *i = e;
+ while ((i = i->n) != e)
+ if (i->t == t)
+ return true;
+ return false;
+}
+
+template <typename T>
+int QLinkedList<T>::count(const T &t) const
+{
+ Node *i = e;
+ int c = 0;
+ while ((i = i->n) != e)
+ if (i->t == t)
+ c++;
+ return c;
+}
+
+
+template <typename T>
+typename QLinkedList<T>::iterator QLinkedList<T>::insert(iterator before, const T &t)
+{
+ Node *i = before.i;
+ Node *m = new Node(t);
+ m->n = i;
+ m->p = i->p;
+ m->p->n = m;
+ i->p = m;
+ d->size++;
+ return m;
+}
+
+template <typename T>
+typename QLinkedList<T>::iterator QLinkedList<T>::erase(typename QLinkedList<T>::iterator afirst,
+ typename QLinkedList<T>::iterator alast)
+{
+ while (afirst != alast)
+ erase(afirst++);
+ return alast;
+}
+
+
+template <typename T>
+typename QLinkedList<T>::iterator QLinkedList<T>::erase(iterator pos)
+{
+ detach();
+ Node *i = pos.i;
+ if (i != e) {
+ Node *n = i;
+ i->n->p = i->p;
+ i->p->n = i->n;
+ i = i->n;
+ delete n;
+ d->size--;
+ }
+ return i;
+}
+
+template <typename T>
+QLinkedList<T> &QLinkedList<T>::operator+=(const QLinkedList<T> &l)
+{
+ detach();
+ int n = l.d->size;
+ d->size += n;
+ Node *o = l.e->n;
+ while (n--) {
+ Node *i = new Node(o->t);
+ o = o->n;
+ i->n = e;
+ i->p = e->p;
+ i->p->n = i;
+ e->p = i;
+ }
+ return *this;
+}
+
+template <typename T>
+QLinkedList<T> QLinkedList<T>::operator+(const QLinkedList<T> &l) const
+{
+ QLinkedList<T> n = *this;
+ n += l;
+ return n;
+}
+
+Q_DECLARE_SEQUENTIAL_ITERATOR(LinkedList)
+Q_DECLARE_MUTABLE_SEQUENTIAL_ITERATOR(LinkedList)
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QLINKEDLIST_H
diff --git a/src/corelib/tools/qlist.h b/src/corelib/tools/qlist.h
new file mode 100644
index 0000000000..3c21ec12a2
--- /dev/null
+++ b/src/corelib/tools/qlist.h
@@ -0,0 +1,691 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QLIST_H
+#define QLIST_H
+
+#include <QtCore/qiterator.h>
+#include <QtCore/qatomic.h>
+#include <QtCore/qalgorithms.h>
+
+#ifndef QT_NO_STL
+#include <iterator>
+#include <list>
+#endif
+
+#include <new>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Core)
+
+template <typename T> class QVector;
+template <typename T> class QSet;
+
+struct Q_CORE_EXPORT QListData {
+ struct Data {
+ QBasicAtomicInt ref;
+ int alloc, begin, end;
+ uint sharable : 1;
+ void *array[1];
+ };
+ enum { DataHeaderSize = sizeof(Data) - sizeof(void *) };
+
+ Data *detach(); // remove in 5.0
+ Data *detach2();
+ void realloc(int alloc);
+ static Data shared_null;
+ Data *d;
+ void **erase(void **xi);
+ void **append();
+ void **append(const QListData &l);
+ void **prepend();
+ void **insert(int i);
+ void remove(int i);
+ void remove(int i, int n);
+ void move(int from, int to);
+ inline int size() const { return d->end - d->begin; }
+ inline bool isEmpty() const { return d->end == d->begin; }
+ inline void **at(int i) const { return d->array + d->begin + i; }
+ inline void **begin() const { return d->array + d->begin; }
+ inline void **end() const { return d->array + d->end; }
+};
+
+template <typename T>
+class QList
+{
+ struct Node { void *v;
+#if defined(Q_CC_BOR)
+ Q_INLINE_TEMPLATE T &t();
+#else
+ Q_INLINE_TEMPLATE T &t()
+ { return *reinterpret_cast<T*>(QTypeInfo<T>::isLarge || QTypeInfo<T>::isStatic
+ ? v : this); }
+#endif
+ };
+
+ union { QListData p; QListData::Data *d; };
+
+public:
+ inline QList() : d(&QListData::shared_null) { d->ref.ref(); }
+ inline QList(const QList<T> &l) : d(l.d) { d->ref.ref(); if (!d->sharable) detach_helper(); }
+ ~QList();
+ QList<T> &operator=(const QList<T> &l);
+ bool operator==(const QList<T> &l) const;
+ inline bool operator!=(const QList<T> &l) const { return !(*this == l); }
+
+ inline int size() const { return p.size(); }
+
+ inline void detach() { if (d->ref != 1) detach_helper(); }
+ inline bool isDetached() const { return d->ref == 1; }
+ inline void setSharable(bool sharable) { if (!sharable) detach(); d->sharable = sharable; }
+
+ inline bool isEmpty() const { return p.isEmpty(); }
+
+ void clear();
+
+ const T &at(int i) const;
+ const T &operator[](int i) const;
+ T &operator[](int i);
+
+ void append(const T &t);
+ void append(const QList<T> &t);
+ void prepend(const T &t);
+ void insert(int i, const T &t);
+ void replace(int i, const T &t);
+ void removeAt(int i);
+ int removeAll(const T &t);
+ bool removeOne(const T &t);
+ T takeAt(int i);
+ T takeFirst();
+ T takeLast();
+ void move(int from, int to);
+ void swap(int i, int j);
+ int indexOf(const T &t, int from = 0) const;
+ int lastIndexOf(const T &t, int from = -1) const;
+ QBool contains(const T &t) const;
+ int count(const T &t) const;
+
+ class const_iterator;
+
+ class iterator {
+ public:
+ Node *i;
+ typedef std::random_access_iterator_tag iterator_category;
+ typedef ptrdiff_t difference_type;
+ typedef T value_type;
+ typedef T *pointer;
+ typedef T &reference;
+
+ inline iterator() : i(0) {}
+ inline iterator(Node *n) : i(n) {}
+ inline iterator(const iterator &o): i(o.i){}
+ inline T &operator*() const { return i->t(); }
+ inline T *operator->() const { return &i->t(); }
+ inline T &operator[](int j) const { return i[j].t(); }
+ inline bool operator==(const iterator &o) const { return i == o.i; }
+ inline bool operator!=(const iterator &o) const { return i != o.i; }
+ inline bool operator<(const iterator& other) const { return i < other.i; }
+ inline bool operator<=(const iterator& other) const { return i <= other.i; }
+ inline bool operator>(const iterator& other) const { return i > other.i; }
+ inline bool operator>=(const iterator& other) const { return i >= other.i; }
+#ifndef QT_STRICT_ITERATORS
+ inline bool operator==(const const_iterator &o) const
+ { return i == o.i; }
+ inline bool operator!=(const const_iterator &o) const
+ { return i != o.i; }
+ inline bool operator<(const const_iterator& other) const
+ { return i < other.i; }
+ inline bool operator<=(const const_iterator& other) const
+ { return i <= other.i; }
+ inline bool operator>(const const_iterator& other) const
+ { return i > other.i; }
+ inline bool operator>=(const const_iterator& other) const
+ { return i >= other.i; }
+#endif
+ inline iterator &operator++() { ++i; return *this; }
+ inline iterator operator++(int) { Node *n = i; ++i; return n; }
+ inline iterator &operator--() { i--; return *this; }
+ inline iterator operator--(int) { Node *n = i; i--; return n; }
+ inline iterator &operator+=(int j) { i+=j; return *this; }
+ inline iterator &operator-=(int j) { i-=j; return *this; }
+ inline iterator operator+(int j) const { return iterator(i+j); }
+ inline iterator operator-(int j) const { return iterator(i-j); }
+ inline int operator-(iterator j) const { return i - j.i; }
+ };
+ friend class iterator;
+
+ class const_iterator {
+ public:
+ Node *i;
+ typedef std::random_access_iterator_tag iterator_category;
+ typedef ptrdiff_t difference_type;
+ typedef T value_type;
+ typedef const T *pointer;
+ typedef const T &reference;
+
+ inline const_iterator() : i(0) {}
+ inline const_iterator(Node *n) : i(n) {}
+ inline const_iterator(const const_iterator &o): i(o.i) {}
+#ifdef QT_STRICT_ITERATORS
+ inline explicit const_iterator(const iterator &o): i(o.i) {}
+#else
+ inline const_iterator(const iterator &o): i(o.i) {}
+#endif
+ inline const T &operator*() const { return i->t(); }
+ inline const T *operator->() const { return &i->t(); }
+ inline const T &operator[](int j) const { return i[j].t(); }
+ inline bool operator==(const const_iterator &o) const { return i == o.i; }
+ inline bool operator!=(const const_iterator &o) const { return i != o.i; }
+ inline bool operator<(const const_iterator& other) const { return i < other.i; }
+ inline bool operator<=(const const_iterator& other) const { return i <= other.i; }
+ inline bool operator>(const const_iterator& other) const { return i > other.i; }
+ inline bool operator>=(const const_iterator& other) const { return i >= other.i; }
+ inline const_iterator &operator++() { ++i; return *this; }
+ inline const_iterator operator++(int) { Node *n = i; ++i; return n; }
+ inline const_iterator &operator--() { i--; return *this; }
+ inline const_iterator operator--(int) { Node *n = i; i--; return n; }
+ inline const_iterator &operator+=(int j) { i+=j; return *this; }
+ inline const_iterator &operator-=(int j) { i-=j; return *this; }
+ inline const_iterator operator+(int j) const { return const_iterator(i+j); }
+ inline const_iterator operator-(int j) const { return const_iterator(i-j); }
+ inline int operator-(const_iterator j) const { return i - j.i; }
+ };
+ friend class const_iterator;
+
+ // stl style
+ inline iterator begin() { detach(); return reinterpret_cast<Node *>(p.begin()); }
+ inline const_iterator begin() const { return reinterpret_cast<Node *>(p.begin()); }
+ inline const_iterator constBegin() const { return reinterpret_cast<Node *>(p.begin()); }
+ inline iterator end() { detach(); return reinterpret_cast<Node *>(p.end()); }
+ inline const_iterator end() const { return reinterpret_cast<Node *>(p.end()); }
+ inline const_iterator constEnd() const { return reinterpret_cast<Node *>(p.end()); }
+ iterator insert(iterator before, const T &t);
+ iterator erase(iterator pos);
+ iterator erase(iterator first, iterator last);
+
+ // more Qt
+ typedef iterator Iterator;
+ typedef const_iterator ConstIterator;
+ inline int count() const { return p.size(); }
+ inline int length() const { return p.size(); } // Same as count()
+ inline T& first() { Q_ASSERT(!isEmpty()); return *begin(); }
+ inline const T& first() const { Q_ASSERT(!isEmpty()); return *begin(); }
+ T& last() { Q_ASSERT(!isEmpty()); return *(--end()); }
+ const T& last() const { Q_ASSERT(!isEmpty()); return *(--end()); }
+ inline void removeFirst() { Q_ASSERT(!isEmpty()); erase(begin()); }
+ inline void removeLast() { Q_ASSERT(!isEmpty()); erase(--end()); }
+ inline bool startsWith(const T &t) const { return !isEmpty() && first() == t; }
+ inline bool endsWith(const T &t) const { return !isEmpty() && last() == t; }
+ QList<T> mid(int pos, int length = -1) const;
+
+ T value(int i) const;
+ T value(int i, const T &defaultValue) const;
+
+ // stl compatibility
+ inline void push_back(const T &t) { append(t); }
+ inline void push_front(const T &t) { prepend(t); }
+ inline T& front() { return first(); }
+ inline const T& front() const { return first(); }
+ inline T& back() { return last(); }
+ inline const T& back() const { return last(); }
+ inline void pop_front() { removeFirst(); }
+ inline void pop_back() { removeLast(); }
+ inline bool empty() const { return isEmpty(); }
+ typedef int size_type;
+ typedef T value_type;
+ typedef value_type *pointer;
+ typedef const value_type *const_pointer;
+ typedef value_type &reference;
+ typedef const value_type &const_reference;
+ typedef ptrdiff_t difference_type;
+
+#ifdef QT3_SUPPORT
+ inline QT3_SUPPORT iterator remove(iterator pos) { return erase(pos); }
+ inline QT3_SUPPORT int remove(const T &t) { return removeAll(t); }
+ inline QT3_SUPPORT int findIndex(const T& t) const { return indexOf(t); }
+ inline QT3_SUPPORT iterator find(const T& t)
+ { int i = indexOf(t); return (i == -1 ? end() : (begin()+i)); }
+ inline QT3_SUPPORT const_iterator find (const T& t) const
+ { int i = indexOf(t); return (i == -1 ? end() : (begin()+i)); }
+ inline QT3_SUPPORT iterator find(iterator from, const T& t)
+ { int i = indexOf(t, from - begin()); return i == -1 ? end() : begin()+i; }
+ inline QT3_SUPPORT const_iterator find(const_iterator from, const T& t) const
+ { int i = indexOf(t, from - begin()); return i == -1 ? end() : begin()+i; }
+#endif
+
+ // comfort
+ QList<T> &operator+=(const QList<T> &l);
+ inline QList<T> operator+(const QList<T> &l) const
+ { QList n = *this; n += l; return n; }
+ inline QList<T> &operator+=(const T &t)
+ { append(t); return *this; }
+ inline QList<T> &operator<< (const T &t)
+ { append(t); return *this; }
+ inline QList<T> &operator<<(const QList<T> &l)
+ { *this += l; return *this; }
+
+ QVector<T> toVector() const;
+ QSet<T> toSet() const;
+
+ static QList<T> fromVector(const QVector<T> &vector);
+ static QList<T> fromSet(const QSet<T> &set);
+
+#ifndef QT_NO_STL
+ static inline QList<T> fromStdList(const std::list<T> &list)
+ { QList<T> tmp; qCopy(list.begin(), list.end(), std::back_inserter(tmp)); return tmp; }
+ inline std::list<T> toStdList() const
+ { std::list<T> tmp; qCopy(constBegin(), constEnd(), std::back_inserter(tmp)); return tmp; }
+#endif
+
+private:
+ void detach_helper();
+ void free(QListData::Data *d);
+
+ void node_construct(Node *n, const T &t);
+ void node_destruct(Node *n);
+ void node_copy(Node *from, Node *to, Node *src);
+ void node_destruct(Node *from, Node *to);
+};
+
+#if defined(Q_CC_BOR)
+template <typename T>
+Q_INLINE_TEMPLATE T &QList<T>::Node::t()
+{ return QTypeInfo<T>::isLarge || QTypeInfo<T>::isStatic ? *(T*)v:*(T*)this; }
+#endif
+
+template <typename T>
+Q_INLINE_TEMPLATE void QList<T>::node_construct(Node *n, const T &t)
+{
+ if (QTypeInfo<T>::isLarge || QTypeInfo<T>::isStatic) n->v = new T(t);
+ else if (QTypeInfo<T>::isComplex) new (n) T(t);
+ else *reinterpret_cast<T*>(n) = t;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE void QList<T>::node_destruct(Node *n)
+{
+ if (QTypeInfo<T>::isLarge || QTypeInfo<T>::isStatic) delete reinterpret_cast<T*>(n->v);
+ else if (QTypeInfo<T>::isComplex) reinterpret_cast<T*>(n)->~T();
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE void QList<T>::node_copy(Node *from, Node *to, Node *src)
+{
+ if (QTypeInfo<T>::isLarge || QTypeInfo<T>::isStatic)
+ while(from != to)
+ (from++)->v = new T(*reinterpret_cast<T*>((src++)->v));
+ else if (QTypeInfo<T>::isComplex)
+ while(from != to)
+ new (from++) T(*reinterpret_cast<T*>(src++));
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE void QList<T>::node_destruct(Node *from, Node *to)
+{
+ if (QTypeInfo<T>::isLarge || QTypeInfo<T>::isStatic)
+ while(from != to) --to, delete reinterpret_cast<T*>(to->v);
+ else if (QTypeInfo<T>::isComplex)
+ while (from != to) --to, reinterpret_cast<T*>(to)->~T();
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE QList<T> &QList<T>::operator=(const QList<T> &l)
+{
+ if (d != l.d) {
+ l.d->ref.ref();
+ if (!d->ref.deref())
+ free(d);
+ d = l.d;
+ if (!d->sharable)
+ detach_helper();
+ }
+ return *this;
+}
+template <typename T>
+inline typename QList<T>::iterator QList<T>::insert(iterator before, const T &t)
+{ Node *n = reinterpret_cast<Node *>(p.insert(before.i-reinterpret_cast<Node *>(p.begin())));
+ node_construct(n,t); return n; }
+template <typename T>
+inline typename QList<T>::iterator QList<T>::erase(iterator it)
+{ node_destruct(it.i);
+ return reinterpret_cast<Node *>(p.erase(reinterpret_cast<void**>(it.i))); }
+template <typename T>
+inline const T &QList<T>::at(int i) const
+{ Q_ASSERT_X(i >= 0 && i < p.size(), "QList<T>::at", "index out of range");
+ return reinterpret_cast<Node *>(p.at(i))->t(); }
+template <typename T>
+inline const T &QList<T>::operator[](int i) const
+{ Q_ASSERT_X(i >= 0 && i < p.size(), "QList<T>::operator[]", "index out of range");
+ return reinterpret_cast<Node *>(p.at(i))->t(); }
+template <typename T>
+inline T &QList<T>::operator[](int i)
+{ Q_ASSERT_X(i >= 0 && i < p.size(), "QList<T>::operator[]", "index out of range");
+ detach(); return reinterpret_cast<Node *>(p.at(i))->t(); }
+template <typename T>
+inline void QList<T>::removeAt(int i)
+{ if(i >= 0 && i < p.size()) { detach();
+ node_destruct(reinterpret_cast<Node *>(p.at(i))); p.remove(i); } }
+template <typename T>
+inline T QList<T>::takeAt(int i)
+{ Q_ASSERT_X(i >= 0 && i < p.size(), "QList<T>::take", "index out of range");
+ detach(); Node *n = reinterpret_cast<Node *>(p.at(i)); T t = n->t(); node_destruct(n);
+ p.remove(i); return t; }
+template <typename T>
+inline T QList<T>::takeFirst()
+{ T t = first(); removeFirst(); return t; }
+template <typename T>
+inline T QList<T>::takeLast()
+{ T t = last(); removeLast(); return t; }
+
+template <typename T>
+Q_OUTOFLINE_TEMPLATE void QList<T>::append(const T &t)
+{
+ detach();
+ if (QTypeInfo<T>::isLarge || QTypeInfo<T>::isStatic) {
+ node_construct(reinterpret_cast<Node *>(p.append()), t);
+ } else {
+ const T cpy(t);
+ node_construct(reinterpret_cast<Node *>(p.append()), cpy);
+ }
+}
+
+template <typename T>
+inline void QList<T>::prepend(const T &t)
+{
+ detach();
+ if (QTypeInfo<T>::isLarge || QTypeInfo<T>::isStatic) {
+ node_construct(reinterpret_cast<Node *>(p.prepend()), t);
+ } else {
+ const T cpy(t);
+ node_construct(reinterpret_cast<Node *>(p.prepend()), cpy);
+ }
+}
+
+template <typename T>
+inline void QList<T>::insert(int i, const T &t)
+{
+ detach();
+ if (QTypeInfo<T>::isLarge || QTypeInfo<T>::isStatic) {
+ node_construct(reinterpret_cast<Node *>(p.insert(i)), t);
+ } else {
+ const T cpy(t);
+ node_construct(reinterpret_cast<Node *>(p.insert(i)), cpy);
+ }
+}
+
+template <typename T>
+inline void QList<T>::replace(int i, const T &t)
+{
+ Q_ASSERT_X(i >= 0 && i < p.size(), "QList<T>::replace", "index out of range");
+ detach();
+ if (QTypeInfo<T>::isLarge || QTypeInfo<T>::isStatic) {
+ reinterpret_cast<Node *>(p.at(i))->t() = t;
+ } else {
+ const T cpy(t);
+ reinterpret_cast<Node *>(p.at(i))->t() = cpy;
+ }
+}
+
+template <typename T>
+inline void QList<T>::swap(int i, int j)
+{
+ Q_ASSERT_X(i >= 0 && i < p.size() && j >= 0 && j < p.size(),
+ "QList<T>::swap", "index out of range");
+ detach();
+ void *t = d->array[d->begin + i];
+ d->array[d->begin + i] = d->array[d->begin + j];
+ d->array[d->begin + j] = t;
+}
+
+template <typename T>
+inline void QList<T>::move(int from, int to)
+{
+ Q_ASSERT_X(from >= 0 && from < p.size() && to >= 0 && to < p.size(),
+ "QList<T>::move", "index out of range");
+ detach();
+ p.move(from, to);
+}
+
+template<typename T>
+Q_OUTOFLINE_TEMPLATE QList<T> QList<T>::mid(int pos, int alength) const
+{
+ if (alength < 0)
+ alength = size() - pos;
+ if (pos == 0 && alength == size())
+ return *this;
+ QList<T> cpy;
+ if (pos + alength > size())
+ alength = size() - pos;
+ for (int i = pos; i < pos + alength; ++i)
+ cpy += at(i);
+ return cpy;
+}
+
+template<typename T>
+Q_OUTOFLINE_TEMPLATE T QList<T>::value(int i) const
+{
+ if (i < 0 || i >= p.size()) {
+ return T();
+ }
+ return reinterpret_cast<Node *>(p.at(i))->t();
+}
+
+template<typename T>
+Q_OUTOFLINE_TEMPLATE T QList<T>::value(int i, const T& defaultValue) const
+{
+ return ((i < 0 || i >= p.size()) ? defaultValue : reinterpret_cast<Node *>(p.at(i))->t());
+}
+
+template <typename T>
+Q_OUTOFLINE_TEMPLATE void QList<T>::detach_helper()
+{
+ Node *n = reinterpret_cast<Node *>(p.begin());
+ QListData::Data *x = p.detach2();
+ node_copy(reinterpret_cast<Node *>(p.begin()), reinterpret_cast<Node *>(p.end()), n);
+ if (!x->ref.deref())
+ free(x);
+}
+
+template <typename T>
+Q_OUTOFLINE_TEMPLATE QList<T>::~QList()
+{
+ if (d && !d->ref.deref())
+ free(d);
+}
+
+template <typename T>
+Q_OUTOFLINE_TEMPLATE bool QList<T>::operator==(const QList<T> &l) const
+{
+ if (p.size() != l.p.size())
+ return false;
+ if (d == l.d)
+ return true;
+ Node *i = reinterpret_cast<Node *>(p.end());
+ Node *b = reinterpret_cast<Node *>(p.begin());
+ Node *li = reinterpret_cast<Node *>(l.p.end());
+ while (i != b) {
+ --i; --li;
+ if (!(i->t() == li->t()))
+ return false;
+ }
+ return true;
+}
+
+// ### Qt 5: rename freeData() to avoid confusion with std::free()
+template <typename T>
+Q_OUTOFLINE_TEMPLATE void QList<T>::free(QListData::Data *data)
+{
+ node_destruct(reinterpret_cast<Node *>(data->array + data->begin),
+ reinterpret_cast<Node *>(data->array + data->end));
+ if (data->ref == 0)
+ qFree(data);
+}
+
+
+template <typename T>
+Q_OUTOFLINE_TEMPLATE void QList<T>::clear()
+{
+ *this = QList<T>();
+}
+
+template <typename T>
+Q_OUTOFLINE_TEMPLATE int QList<T>::removeAll(const T &_t)
+{
+ detach();
+ const T t = _t;
+ int removedCount=0, i=0;
+ Node *n;
+ while (i < p.size())
+ if ((n = reinterpret_cast<Node *>(p.at(i)))->t() == t) {
+ node_destruct(n);
+ p.remove(i);
+ ++removedCount;
+ } else {
+ ++i;
+ }
+ return removedCount;
+}
+
+template <typename T>
+Q_OUTOFLINE_TEMPLATE bool QList<T>::removeOne(const T &_t)
+{
+ detach();
+ int index = indexOf(_t);
+ if (index != -1) {
+ removeAt(index);
+ return true;
+ }
+ return false;
+}
+
+template <typename T>
+Q_OUTOFLINE_TEMPLATE typename QList<T>::iterator QList<T>::erase(typename QList<T>::iterator afirst,
+ typename QList<T>::iterator alast)
+{
+ for (Node *n = afirst.i; n < alast.i; ++n)
+ node_destruct(n);
+ int idx = afirst - begin();
+ p.remove(idx, alast - afirst);
+ return begin() + idx;
+}
+
+template <typename T>
+Q_OUTOFLINE_TEMPLATE QList<T> &QList<T>::operator+=(const QList<T> &l)
+{
+ detach();
+ Node *n = reinterpret_cast<Node *>(p.append(l.p));
+ node_copy(n, reinterpret_cast<Node *>(p.end()), reinterpret_cast<Node *>(l.p.begin()));
+ return *this;
+}
+
+template <typename T>
+inline void QList<T>::append(const QList<T> &t)
+{
+ *this += t;
+}
+
+template <typename T>
+Q_OUTOFLINE_TEMPLATE int QList<T>::indexOf(const T &t, int from) const
+{
+ if (from < 0)
+ from = qMax(from + p.size(), 0);
+ if (from < p.size()) {
+ Node *n = reinterpret_cast<Node *>(p.at(from -1));
+ Node *e = reinterpret_cast<Node *>(p.end());
+ while (++n != e)
+ if (n->t() == t)
+ return n - reinterpret_cast<Node *>(p.begin());
+ }
+ return -1;
+}
+
+template <typename T>
+Q_OUTOFLINE_TEMPLATE int QList<T>::lastIndexOf(const T &t, int from) const
+{
+ if (from < 0)
+ from += p.size();
+ else if (from >= p.size())
+ from = p.size()-1;
+ if (from >= 0) {
+ Node *b = reinterpret_cast<Node *>(p.begin());
+ Node *n = reinterpret_cast<Node *>(p.at(from + 1));
+ while (n-- != b) {
+ if (n->t() == t)
+ return n - b;
+ }
+ }
+ return -1;
+}
+
+template <typename T>
+Q_OUTOFLINE_TEMPLATE QBool QList<T>::contains(const T &t) const
+{
+ Node *b = reinterpret_cast<Node *>(p.begin());
+ Node *i = reinterpret_cast<Node *>(p.end());
+ while (i-- != b)
+ if (i->t() == t)
+ return QBool(true);
+ return QBool(false);
+}
+
+template <typename T>
+Q_OUTOFLINE_TEMPLATE int QList<T>::count(const T &t) const
+{
+ int c = 0;
+ Node *b = reinterpret_cast<Node *>(p.begin());
+ Node *i = reinterpret_cast<Node *>(p.end());
+ while (i-- != b)
+ if (i->t() == t)
+ ++c;
+ return c;
+}
+
+Q_DECLARE_SEQUENTIAL_ITERATOR(List)
+Q_DECLARE_MUTABLE_SEQUENTIAL_ITERATOR(List)
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QLIST_H
diff --git a/src/corelib/tools/qlistdata.cpp b/src/corelib/tools/qlistdata.cpp
new file mode 100644
index 0000000000..2b1c086776
--- /dev/null
+++ b/src/corelib/tools/qlistdata.cpp
@@ -0,0 +1,1742 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qlist.h"
+#include "qtools_p.h"
+#include <string.h>
+
+QT_BEGIN_NAMESPACE
+
+/*
+ QList as an array-list combines the easy-of-use of a random
+ access interface with fast list operations and the low memory
+ management overhead of an array. Accessing elements by index,
+ appending, prepending, and removing elements from both the front
+ and the back all happen in constant time O(1). Inserting or
+ removing elements at random index positions \ai happens in linear
+ time, or more precisly in O(min{i,n-i}) <= O(n/2), with n being
+ the number of elements in the list.
+*/
+
+QListData::Data QListData::shared_null = { Q_BASIC_ATOMIC_INITIALIZER(1), 0, 0, 0, true, { 0 } };
+
+static int grow(int size)
+{
+ // dear compiler: don't optimize me out.
+ volatile int x = qAllocMore(size * sizeof(void *), QListData::DataHeaderSize) / sizeof(void *);
+ return x;
+}
+
+#if QT_VERSION >= 0x050000
+# error "Remove QListData::detach(), it is only required for binary compatibility for 4.0.x to 4.2.x"
+#endif
+QListData::Data *QListData::detach()
+{
+ Data *x = static_cast<Data *>(qMalloc(DataHeaderSize + d->alloc * sizeof(void *)));
+ if (!x)
+ qFatal("QList: Out of memory");
+
+ ::memcpy(x, d, DataHeaderSize + d->alloc * sizeof(void *));
+ x->alloc = d->alloc;
+ x->ref = 1;
+ x->sharable = true;
+ if (!x->alloc)
+ x->begin = x->end = 0;
+
+ qSwap(d, x);
+ if (!x->ref.deref())
+ return x;
+ return 0;
+}
+
+// Returns the old (shared) data, it is up to the caller to deref() and free()
+QListData::Data *QListData::detach2()
+{
+ Data *x = d;
+ d = static_cast<Data *>(qMalloc(DataHeaderSize + x->alloc * sizeof(void *)));
+ if (!d)
+ qFatal("QList: Out of memory");
+
+ ::memcpy(d, x, DataHeaderSize + x->alloc * sizeof(void *));
+ d->alloc = x->alloc;
+ d->ref = 1;
+ d->sharable = true;
+ if (!d->alloc)
+ d->begin = d->end = 0;
+
+ return x;
+}
+
+void QListData::realloc(int alloc)
+{
+ Q_ASSERT(d->ref == 1);
+ Data *x = static_cast<Data *>(qRealloc(d, DataHeaderSize + alloc * sizeof(void *)));
+ if (!x)
+ qFatal("QList: Out of memory");
+
+ d = x;
+ d->alloc = alloc;
+ if (!alloc)
+ d->begin = d->end = 0;
+}
+
+void **QListData::append()
+{
+ Q_ASSERT(d->ref == 1);
+ if (d->end == d->alloc) {
+ int n = d->end - d->begin;
+ if (d->begin > 2 * d->alloc / 3) {
+ ::memcpy(d->array + n, d->array + d->begin, n * sizeof(void *));
+ d->begin = n;
+ d->end = n * 2;
+ } else {
+ realloc(grow(d->alloc + 1));
+ }
+ }
+ return d->array + d->end++;
+}
+
+void **QListData::append(const QListData& l)
+{
+ Q_ASSERT(d->ref == 1);
+ int e = d->end;
+ int n = l.d->end - l.d->begin;
+ if (n) {
+ if (e + n > d->alloc)
+ realloc(grow(e + l.d->end - l.d->begin));
+ ::memcpy(d->array + d->end, l.d->array + l.d->begin, n * sizeof(void*));
+ d->end += n;
+ }
+ return d->array + e;
+}
+
+void **QListData::prepend()
+{
+ Q_ASSERT(d->ref == 1);
+ if (d->begin == 0) {
+ if (d->end >= d->alloc / 3)
+ realloc(grow(d->alloc + 1));
+
+ if (d->end < d->alloc / 3)
+ d->begin = d->alloc - 2 * d->end;
+ else
+ d->begin = d->alloc - d->end;
+
+ ::memmove(d->array + d->begin, d->array, d->end * sizeof(void *));
+ d->end += d->begin;
+ }
+ return d->array + --d->begin;
+}
+
+void **QListData::insert(int i)
+{
+ Q_ASSERT(d->ref == 1);
+ if (i <= 0)
+ return prepend();
+ if (i >= d->end - d->begin)
+ return append();
+
+ bool leftward = false;
+ int size = d->end - d->begin;
+
+ if (d->begin == 0) {
+ if (d->end == d->alloc) {
+ // If the array is full, we expand it and move some items rightward
+ realloc(grow(d->alloc + 1));
+ } else {
+ // If there is free space at the end of the array, we move some items rightward
+ }
+ } else {
+ if (d->end == d->alloc) {
+ // If there is free space at the beginning of the array, we move some items leftward
+ leftward = true;
+ } else {
+ // If there is free space at both ends, we move as few items as possible
+ leftward = (i < size - i);
+ }
+ }
+
+ if (leftward) {
+ --d->begin;
+ ::memmove(d->array + d->begin, d->array + d->begin + 1, i * sizeof(void *));
+ } else {
+ ::memmove(d->array + d->begin + i + 1, d->array + d->begin + i,
+ (size - i) * sizeof(void *));
+ ++d->end;
+ }
+ return d->array + d->begin + i;
+}
+
+void QListData::remove(int i)
+{
+ Q_ASSERT(d->ref == 1);
+ i += d->begin;
+ if (i - d->begin < d->end - i) {
+ if (int offset = i - d->begin)
+ ::memmove(d->array + d->begin + 1, d->array + d->begin, offset * sizeof(void *));
+ d->begin++;
+ } else {
+ if (int offset = d->end - i - 1)
+ ::memmove(d->array + i, d->array + i + 1, offset * sizeof(void *));
+ d->end--;
+ }
+}
+
+void QListData::remove(int i, int n)
+{
+ Q_ASSERT(d->ref == 1);
+ i += d->begin;
+ int middle = i + n/2;
+ if (middle - d->begin < d->end - middle) {
+ ::memmove(d->array + d->begin + n, d->array + d->begin,
+ (i - d->begin) * sizeof(void*));
+ d->begin += n;
+ } else {
+ ::memmove(d->array + i, d->array + i + n,
+ (d->end - i - n) * sizeof(void*));
+ d->end -= n;
+ }
+}
+
+void QListData::move(int from, int to)
+{
+ Q_ASSERT(d->ref == 1);
+ if (from == to)
+ return;
+
+ from += d->begin;
+ to += d->begin;
+ void *t = d->array[from];
+
+ if (from < to) {
+ if (d->end == d->alloc || 3 * (to - from) < 2 * (d->end - d->begin)) {
+ ::memmove(d->array + from, d->array + from + 1, (to - from) * sizeof(void *));
+ } else {
+ // optimization
+ if (int offset = from - d->begin)
+ ::memmove(d->array + d->begin + 1, d->array + d->begin, offset * sizeof(void *));
+ if (int offset = d->end - (to + 1))
+ ::memmove(d->array + to + 2, d->array + to + 1, offset * sizeof(void *));
+ ++d->begin;
+ ++d->end;
+ ++to;
+ }
+ } else {
+ if (d->begin == 0 || 3 * (from - to) < 2 * (d->end - d->begin)) {
+ ::memmove(d->array + to + 1, d->array + to, (from - to) * sizeof(void *));
+ } else {
+ // optimization
+ if (int offset = to - d->begin)
+ ::memmove(d->array + d->begin - 1, d->array + d->begin, offset * sizeof(void *));
+ if (int offset = d->end - (from + 1))
+ ::memmove(d->array + from, d->array + from + 1, offset * sizeof(void *));
+ --d->begin;
+ --d->end;
+ --to;
+ }
+ }
+ d->array[to] = t;
+}
+
+void **QListData::erase(void **xi)
+{
+ Q_ASSERT(d->ref == 1);
+ int i = xi - (d->array + d->begin);
+ remove(i);
+ return d->array + d->begin + i;
+}
+
+/*! \class QList
+ \brief The QList class is a template class that provides lists.
+
+ \ingroup tools
+ \ingroup shared
+ \mainclass
+ \reentrant
+
+ QList\<T\> is one of Qt's generic \l{container classes}. It
+ stores a list of values and provides fast index-based access as
+ well as fast insertions and removals.
+
+ QList\<T\>, QLinkedList\<T\>, and QVector\<T\> provide similar
+ functionality. Here's an overview:
+
+ \list
+ \i For most purposes, QList is the right class to use. Its
+ index-based API is more convenient than QLinkedList's
+ iterator-based API, and it is usually faster than
+ QVector because of the way it stores its items in
+ memory. It also expands to less code in your executable.
+ \i If you need a real linked list, with guarantees of \l{constant
+ time} insertions in the middle of the list and iterators to
+ items rather than indexes, use QLinkedList.
+ \i If you want the items to occupy adjacent memory positions,
+ use QVector.
+ \endlist
+
+
+ Internally, QList\<T\> is represented as an array of pointers to
+ items of type T. If T is itself a pointer type or a basic type
+ that is no larger than a pointer, or if T is one of Qt's \l{shared
+ classes}, then QList\<T\> stores the items directly in the pointer
+ array. For lists under a thousand items, this array representation
+ allows for very fast insertions in the middle, and it allows
+ index-based access. Furthermore, operations like prepend() and
+ append() are very fast, because QList preallocates memory at both
+ ends of its internal array. (See \l{Algorithmic Complexity} for
+ details.) Note, however, that for unshared list items that are
+ larger than a pointer, each append or insert of a new item
+ requires allocating the new item on the heap, and this per item
+ allocation might make QVector a better choice in cases that do
+ lots of appending or inserting, since QVector allocates memory for
+ its items in a single heap allocation.
+
+ Note that the internal array only ever gets bigger over the life
+ of the list. It never shrinks. The internal array is deallocated
+ by the destructor and by the assignment operator, when one list
+ is assigned to another.
+
+ Here's an example of a QList that stores integers and
+ a QList that stores QDate values:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qlistdata.cpp 0
+
+ Qt includes a QStringList class that inherits QList\<QString\>
+ and adds a few convenience functions, such as QStringList::join()
+ and QStringList::find(). (QString::split() creates QStringLists
+ from strings.)
+
+ QList stores a list of items. The default constructor creates an
+ empty list. To insert items into the list, you can use
+ operator<<():
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qlistdata.cpp 1
+
+ QList provides these basic functions to add, move, and remove
+ items: insert(), replace(), removeAt(), move(), and swap(). In
+ addition, it provides the following convenience functions:
+ append(), prepend(), removeFirst(), and removeLast().
+
+ QList uses 0-based indexes, just like C++ arrays. To access the
+ item at a particular index position, you can use operator[](). On
+ non-const lists, operator[]() returns a reference to the item and
+ can be used on the left side of an assignment:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qlistdata.cpp 2
+
+ Because QList is implemented as an array of pointers, this
+ operation is very fast (\l{constant time}). For read-only access,
+ an alternative syntax is to use at():
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qlistdata.cpp 3
+
+ at() can be faster than operator[](), because it never causes a
+ \l{deep copy} to occur.
+
+ A common requirement is to remove an item from a list and do
+ something with it. For this, QList provides takeAt(), takeFirst(),
+ and takeLast(). Here's a loop that removes the items from a list
+ one at a time and calls \c delete on them:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qlistdata.cpp 4
+
+ Inserting and removing items at either ends of the list is very
+ fast (\l{constant time} in most cases), because QList
+ preallocates extra space on both sides of its internal buffer to
+ allow for fast growth at both ends of the list.
+
+ If you want to find all occurrences of a particular value in a
+ list, use indexOf() or lastIndexOf(). The former searches forward
+ starting from a given index position, the latter searches
+ backward. Both return the index of a matching item if they find
+ it; otherwise, they return -1. For example:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qlistdata.cpp 5
+
+ If you simply want to check whether a list contains a particular
+ value, use contains(). If you want to find out how many times a
+ particular value occurs in the list, use count(). If you want to
+ replace all occurrences of a particular value with another, use
+ replace().
+
+ QList's value type must be an \l{assignable data type}. This
+ covers most data types that are commonly used, but the compiler
+ won't let you, for example, store a QWidget as a value; instead,
+ store a QWidget *. A few functions have additional requirements;
+ for example, indexOf() and lastIndexOf() expect the value type to
+ support \c operator==(). These requirements are documented on a
+ per-function basis.
+
+ Like the other container classes, QList provides \l{Java-style
+ iterators} (QListIterator and QMutableListIterator) and
+ \l{STL-style iterators} (QList::const_iterator and
+ QList::iterator). In practice, these are rarely used, because you
+ can use indexes into the QList. QList is implemented in such a way
+ that direct index-based access is just as fast as using iterators.
+
+ QList does \e not support inserting, prepending, appending or
+ replacing with references to its own values. Doing so will cause
+ your application to abort with an error message.
+
+ To make QList as efficient as possible, its member functions don't
+ validate their input before using it. Except for isEmpty(), member
+ functions always assume the list is \e not empty. Member functions
+ that take index values as parameters always assume their index
+ value parameters are in the valid range. This means QList member
+ functions can fail. If you define QT_NO_DEBUG when you compile,
+ failures will not be detected. If you \e don't define QT_NO_DEBUG,
+ failures will be detected using Q_ASSERT() or Q_ASSERT_X() with an
+ appropriate message.
+
+ To avoid failures when your list can be empty, call isEmpty()
+ before calling other member functions. If you must pass an index
+ value that might not be in the valid range, check that it is less
+ than the value returned by size() but \e not less than 0.
+
+ \sa QListIterator, QMutableListIterator, QLinkedList, QVector
+*/
+
+/*!
+ \fn QList<T> QList<T>::mid(int pos, int length) const
+
+ Returns a list whose elements are copied from this list,
+ starting at position \a pos. If \a length is -1 (the default), all
+ elements from \a pos are copied; otherwise \a length elements (or
+ all remaining elements if there are less than \a length elements)
+ are copied.
+*/
+
+/*! \fn QList::QList()
+
+ Constructs an empty list.
+*/
+
+/*! \fn QList::QList(const QList<T> &other)
+
+ Constructs a copy of \a other.
+
+ This operation takes \l{constant time}, because QList is
+ \l{implicitly shared}. This makes returning a QList from a
+ function very fast. If a shared instance is modified, it will be
+ copied (copy-on-write), and that takes \l{linear time}.
+
+ \sa operator=()
+*/
+
+/*! \fn QList::~QList()
+
+ Destroys the list. References to the values in the list and all
+ iterators of this list become invalid.
+*/
+
+/*! \fn QList<T> &QList::operator=(const QList<T> &other)
+
+ Assigns \a other to this list and returns a reference to this
+ list.
+*/
+
+/*! \fn bool QList::operator==(const QList<T> &other) const
+
+ Returns true if \a other is equal to this list; otherwise returns
+ false.
+
+ Two lists are considered equal if they contain the same values in
+ the same order.
+
+ This function requires the value type to have an implementation of
+ \c operator==().
+
+ \sa operator!=()
+*/
+
+/*! \fn bool QList::operator!=(const QList<T> &other) const
+
+ Returns true if \a other is not equal to this list; otherwise
+ returns false.
+
+ Two lists are considered equal if they contain the same values in
+ the same order.
+
+ This function requires the value type to have an implementation of
+ \c operator==().
+
+ \sa operator==()
+*/
+
+/*!
+ \fn int QList::size() const
+
+ Returns the number of items in the list.
+
+ \sa isEmpty(), count()
+*/
+
+/*! \fn void QList::detach()
+
+ \internal
+*/
+
+/*! \fn bool QList::isDetached() const
+
+ \internal
+*/
+
+/*! \fn void QList::setSharable(bool sharable)
+
+ \internal
+*/
+
+/*! \fn bool QList::isEmpty() const
+
+ Returns true if the list contains no items; otherwise returns
+ false.
+
+ \sa size()
+*/
+
+/*! \fn void QList::clear()
+
+ Removes all items from the list.
+
+ \sa removeAll()
+*/
+
+/*! \fn const T &QList::at(int i) const
+
+ Returns the item at index position \a i in the list. \a i must be
+ a valid index position in the list (i.e., 0 <= \a i < size()).
+
+ This function is very fast (\l{constant time}).
+
+ \sa value(), operator[]()
+*/
+
+/*! \fn T &QList::operator[](int i)
+
+ Returns the item at index position \a i as a modifiable reference.
+ \a i must be a valid index position in the list (i.e., 0 <= \a i <
+ size()).
+
+ This function is very fast (\l{constant time}).
+
+ \sa at(), value()
+*/
+
+/*! \fn const T &QList::operator[](int i) const
+
+ \overload
+
+ Same as at().
+*/
+
+/*! \fn void QList::append(const T &value)
+
+ Inserts \a value at the end of the list.
+
+ Example:
+ \snippet doc/src/snippets/code/src_corelib_tools_qlistdata.cpp 6
+
+ This is the same as list.insert(size(), \a value).
+
+ This operation is typically very fast (\l{constant time}),
+ because QList preallocates extra space on both sides of its
+ internal buffer to allow for fast growth at both ends of the
+ list.
+
+ \sa operator<<(), prepend(), insert()
+*/
+
+/*! \fn void QList::append(const QList<T> &value)
+
+ \overload
+
+ \since 4.5
+
+ Appends the items of the \a value list to this list.
+
+ \sa operator<<(), operator+=()
+*/
+
+/*! \fn void QList::prepend(const T &value)
+
+ Inserts \a value at the beginning of the list.
+
+ Example:
+ \snippet doc/src/snippets/code/src_corelib_tools_qlistdata.cpp 7
+
+ This is the same as list.insert(0, \a value).
+
+ This operation is usually very fast (\l{constant time}), because
+ QList preallocates extra space on both sides of its internal
+ buffer to allow for fast growth at both ends of the list.
+
+ \sa append(), insert()
+*/
+
+/*! \fn void QList::insert(int i, const T &value)
+
+ Inserts \a value at index position \a i in the list. If \a i
+ is 0, the value is prepended to the list. If \a i is size(), the
+ value is appended to the list.
+
+ Example:
+ \snippet doc/src/snippets/code/src_corelib_tools_qlistdata.cpp 8
+
+ \sa append(), prepend(), replace(), removeAt()
+*/
+
+/*! \fn QList::iterator QList::insert(iterator before, const T &value)
+
+ \overload
+
+ Inserts \a value in front of the item pointed to by the
+ iterator \a before. Returns an iterator pointing at the inserted
+ item. Note that the iterator passed to the function will be
+ invalid after the call; the returned iterator should be used
+ instead.
+*/
+
+/*! \fn void QList::replace(int i, const T &value)
+
+ Replaces the item at index position \a i with \a value. \a i must
+ be a valid index position in the list (i.e., 0 <= \a i < size()).
+
+ \sa operator[](), removeAt()
+*/
+
+/*!
+ \fn int QList::removeAll(const T &value)
+
+ Removes all occurrences of \a value in the list and returns the
+ number of entries removed.
+
+ Example:
+ \snippet doc/src/snippets/code/src_corelib_tools_qlistdata.cpp 9
+
+ This function requires the value type to have an implementation of
+ \c operator==().
+
+ \sa removeOne(), removeAt(), takeAt(), replace()
+*/
+
+/*!
+ \fn bool QList::removeOne(const T &value)
+ \since 4.4
+
+ Removes the first occurrence of \a value in the list and returns
+ true on success; otherwise returns false.
+
+ Example:
+ \snippet doc/src/snippets/code/src_corelib_tools_qlistdata.cpp 10
+
+ This function requires the value type to have an implementation of
+ \c operator==().
+
+ \sa removeAll(), removeAt(), takeAt(), replace()
+*/
+
+/*! \fn void QList::removeAt(int i)
+
+ Removes the item at index position \a i. \a i must be a valid
+ index position in the list (i.e., 0 <= \a i < size()).
+
+ \sa takeAt(), removeFirst(), removeLast(), removeOne()
+*/
+
+/*! \fn T QList::takeAt(int i)
+
+ Removes the item at index position \a i and returns it. \a i must
+ be a valid index position in the list (i.e., 0 <= \a i < size()).
+
+ If you don't use the return value, removeAt() is more efficient.
+
+ \sa removeAt(), takeFirst(), takeLast()
+*/
+
+/*! \fn T QList::takeFirst()
+
+ Removes the first item in the list and returns it. This is the
+ same as takeAt(0). This function assumes the list is not empty. To
+ avoid failure, call isEmpty() before calling this function.
+
+ This operation is very fast (\l{constant time}), because QList
+ preallocates extra space on both sides of its internal buffer to
+ allow for fast growth at both ends of the list.
+
+ If you don't use the return value, removeFirst() is more
+ efficient.
+
+ \sa takeLast(), takeAt(), removeFirst()
+*/
+
+/*! \fn T QList::takeLast()
+
+ Removes the last item in the list and returns it. This is the
+ same as takeAt(size() - 1). This function assumes the list is
+ not empty. To avoid failure, call isEmpty() before calling this
+ function.
+
+ This operation is very fast (\l{constant time}), because QList
+ preallocates extra space on both sides of its internal buffer to
+ allow for fast growth at both ends of the list.
+
+ If you don't use the return value, removeLast() is more
+ efficient.
+
+ \sa takeFirst(), takeAt(), removeLast()
+*/
+
+/*! \fn void QList::move(int from, int to)
+
+ Moves the item at index position \a from to index position \a to.
+
+ Example:
+ \snippet doc/src/snippets/code/src_corelib_tools_qlistdata.cpp 11
+
+ This is the same as insert(\a{to}, takeAt(\a{from})).This function
+ assumes that both \a from and \a to are at least 0 but less than
+ size(). To avoid failure, test that both \a from and \a to are at
+ least 0 and less than size().
+
+ \sa swap(), insert(), takeAt()
+*/
+
+/*! \fn void QList::swap(int i, int j)
+
+ Exchange the item at index position \a i with the item at index
+ position \a j. This function assumes that both \a i and \a j are
+ at least 0 but less than size(). To avoid failure, test that both
+ \a i and \a j are at least 0 and less than size().
+
+ Example:
+ \snippet doc/src/snippets/code/src_corelib_tools_qlistdata.cpp 12
+
+ \sa move()
+*/
+
+/*! \fn int QList::indexOf(const T &value, int from = 0) const
+
+ Returns the index position of the first occurrence of \a value in
+ the list, searching forward from index position \a from. Returns
+ -1 if no item matched.
+
+ Example:
+ \snippet doc/src/snippets/code/src_corelib_tools_qlistdata.cpp 13
+
+ This function requires the value type to have an implementation of
+ \c operator==().
+
+ \sa lastIndexOf(), contains()
+*/
+
+/*! \fn int QList::lastIndexOf(const T &value, int from = -1) const
+
+ Returns the index position of the last occurrence of \a value in
+ the list, searching backward from index position \a from. If \a
+ from is -1 (the default), the search starts at the last item.
+ Returns -1 if no item matched.
+
+ Example:
+ \snippet doc/src/snippets/code/src_corelib_tools_qlistdata.cpp 14
+
+ This function requires the value type to have an implementation of
+ \c operator==().
+
+ \sa indexOf()
+*/
+
+/*! \fn QBool QList::contains(const T &value) const
+
+ Returns true if the list contains an occurrence of \a value;
+ otherwise returns false.
+
+ This function requires the value type to have an implementation of
+ \c operator==().
+
+ \sa indexOf(), count()
+*/
+
+/*! \fn int QList::count(const T &value) const
+
+ Returns the number of occurrences of \a value in the list.
+
+ This function requires the value type to have an implementation of
+ \c operator==().
+
+ \sa contains(), indexOf()
+*/
+
+/*! \fn bool QList::startsWith(const T &value) const
+ \since 4.5
+
+ Returns true if this list is not empty and its first
+ item is equal to \a value; otherwise returns false.
+
+ \sa isEmpty(), contains()
+*/
+
+/*! \fn bool QList::endsWith(const T &value) const
+ \since 4.5
+
+ Returns true if this list is not empty and its last
+ item is equal to \a value; otherwise returns false.
+
+ \sa isEmpty(), contains()
+*/
+
+/*! \fn QList::iterator QList::begin()
+
+ Returns an \l{STL-style iterator} pointing to the first item in
+ the list.
+
+ \sa constBegin(), end()
+*/
+
+/*! \fn QList::const_iterator QList::begin() const
+
+ \overload
+*/
+
+/*! \fn QList::const_iterator QList::constBegin() const
+
+ Returns a const \l{STL-style iterator} pointing to the first item
+ in the list.
+
+ \sa begin(), constEnd()
+*/
+
+/*! \fn QList::iterator QList::end()
+
+ Returns an \l{STL-style iterator} pointing to the imaginary item
+ after the last item in the list.
+
+ \sa begin(), constEnd()
+*/
+
+/*! \fn const_iterator QList::end() const
+
+ \overload
+*/
+
+/*! \fn QList::const_iterator QList::constEnd() const
+
+ Returns a const \l{STL-style iterator} pointing to the imaginary
+ item after the last item in the list.
+
+ \sa constBegin(), end()
+*/
+
+/*! \fn QList::iterator QList::erase(iterator pos)
+
+ Removes the item associated with the iterator \a pos from the
+ list, and returns an iterator to the next item in the list (which
+ may be end()).
+
+ \sa insert(), removeAt()
+*/
+
+/*! \fn QList::iterator QList::erase(iterator begin, iterator end)
+
+ \overload
+
+ Removes all the items from \a begin up to (but not including) \a
+ end. Returns an iterator to the same item that \a end referred to
+ before the call.
+*/
+
+/*! \typedef QList::Iterator
+
+ Qt-style synonym for QList::iterator.
+*/
+
+/*! \typedef QList::ConstIterator
+
+ Qt-style synonym for QList::const_iterator.
+*/
+
+/*!
+ \typedef QList::size_type
+
+ Typedef for int. Provided for STL compatibility.
+*/
+
+/*!
+ \typedef QList::value_type
+
+ Typedef for T. Provided for STL compatibility.
+*/
+
+/*!
+ \typedef QList::difference_type
+
+ Typedef for ptrdiff_t. Provided for STL compatibility.
+*/
+
+/*!
+ \typedef QList::pointer
+
+ Typedef for T *. Provided for STL compatibility.
+*/
+
+/*!
+ \typedef QList::const_pointer
+
+ Typedef for const T *. Provided for STL compatibility.
+*/
+
+/*!
+ \typedef QList::reference
+
+ Typedef for T &. Provided for STL compatibility.
+*/
+
+/*!
+ \typedef QList::const_reference
+
+ Typedef for const T &. Provided for STL compatibility.
+*/
+
+/*! \fn int QList::count() const
+
+ Returns the number of items in the list. This is effectively the
+ same as size().
+*/
+
+/*! \fn int QList::length() const
+ \since 4.5
+
+ This function is identical to count().
+
+ \sa count()
+*/
+
+/*! \fn T& QList::first()
+
+ Returns a reference to the first item in the list. The list must
+ not be empty. If the list can be empty, call isEmpty() before
+ calling this function.
+
+ \sa last(), isEmpty()
+*/
+
+/*! \fn const T& QList::first() const
+
+ \overload
+*/
+
+/*! \fn T& QList::last()
+
+ Returns a reference to the last item in the list. The list must
+ not be empty. If the list can be empty, call isEmpty() before
+ calling this function.
+
+ \sa first(), isEmpty()
+*/
+
+/*! \fn const T& QList::last() const
+
+ \overload
+*/
+
+/*! \fn void QList::removeFirst()
+
+ Removes the first item in the list. Calling this function is
+ equivalent to calling removeAt(0). The list must not be empty. If
+ the list can be empty, call isEmpty() before calling this
+ function.
+
+ \sa removeAt(), takeFirst()
+*/
+
+/*! \fn void QList::removeLast()
+
+ Removes the last item in the list. Calling this function is
+ equivalent to calling removeAt(size() - 1). The list must not be
+ empty. If the list can be empty, call isEmpty() before calling
+ this function.
+
+ \sa removeAt(), takeLast()
+*/
+
+/*! \fn T QList::value(int i) const
+
+ Returns the value at index position \a i in the list.
+
+ If the index \a i is out of bounds, the function returns a
+ \l{default-constructed value}. If you are certain that the index
+ is going to be within bounds, you can use at() instead, which is
+ slightly faster.
+
+ \sa at(), operator[]()
+*/
+
+/*! \fn T QList::value(int i, const T &defaultValue) const
+
+ \overload
+
+ If the index \a i is out of bounds, the function returns
+ \a defaultValue.
+*/
+
+/*! \fn void QList::push_back(const T &value)
+
+ This function is provided for STL compatibility. It is equivalent
+ to \l{QList::append()}{append(\a value)}.
+*/
+
+/*! \fn void QList::push_front(const T &value)
+
+ This function is provided for STL compatibility. It is equivalent
+ to \l{QList::prepend()}{prepend(\a value)}.
+*/
+
+/*! \fn T& QList::front()
+
+ This function is provided for STL compatibility. It is equivalent
+ to first(). The list must not be empty. If the list can be empty,
+ call isEmpty() before calling this function.
+*/
+
+/*! \fn const T& QList::front() const
+
+ \overload
+*/
+
+/*! \fn T& QList::back()
+
+ This function is provided for STL compatibility. It is equivalent
+ to last(). The list must not be empty. If the list can be empty,
+ call isEmpty() before calling this function.
+*/
+
+/*! \fn const T& QList::back() const
+
+ \overload
+*/
+
+/*! \fn void QList::pop_front()
+
+ This function is provided for STL compatibility. It is equivalent
+ to removeFirst(). The list must not be empty. If the list can be
+ empty, call isEmpty() before calling this function.
+*/
+
+/*! \fn void QList::pop_back()
+
+ This function is provided for STL compatibility. It is equivalent
+ to removeLast(). The list must not be empty. If the list can be
+ empty, call isEmpty() before calling this function.
+*/
+
+/*! \fn bool QList::empty() const
+
+ This function is provided for STL compatibility. It is equivalent
+ to isEmpty() and returns true if the list is empty.
+*/
+
+/*! \fn QList<T> &QList::operator+=(const QList<T> &other)
+
+ Appends the items of the \a other list to this list and returns a
+ reference to this list.
+
+ \sa operator+(), append()
+*/
+
+/*! \fn void QList::operator+=(const T &value)
+
+ \overload
+
+ Appends \a value to the list.
+
+ \sa append(), operator<<()
+*/
+
+/*! \fn QList<T> QList::operator+(const QList<T> &other) const
+
+ Returns a list that contains all the items in this list followed
+ by all the items in the \a other list.
+
+ \sa operator+=()
+*/
+
+/*! \fn QList<T> &QList::operator<<(const QList<T> &other)
+
+ Appends the items of the \a other list to this list and returns a
+ reference to this list.
+
+ \sa operator+=(), append()
+*/
+
+/*! \fn void QList::operator<<(const T &value)
+
+ \overload
+
+ Appends \a value to the list.
+*/
+
+/*! \class QList::iterator
+ \brief The QList::iterator class provides an STL-style non-const iterator for QList and QQueue.
+
+ QList features both \l{STL-style iterators} and \l{Java-style
+ iterators}. The STL-style iterators are more low-level and more
+ cumbersome to use; on the other hand, they are slightly faster
+ and, for developers who already know STL, have the advantage of
+ familiarity.
+
+ QList\<T\>::iterator allows you to iterate over a QList\<T\> (or
+ QQueue\<T\>) and to modify the list item associated with the
+ iterator. If you want to iterate over a const QList, use
+ QList::const_iterator instead. It is generally good practice to
+ use QList::const_iterator on a non-const QList as well, unless
+ you need to change the QList through the iterator. Const
+ iterators are slightly faster, and can improve code readability.
+
+ The default QList::iterator constructor creates an uninitialized
+ iterator. You must initialize it using a QList function like
+ QList::begin(), QList::end(), or QList::insert() before you can
+ start iterating. Here's a typical loop that prints all the items
+ stored in a list:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qlistdata.cpp 15
+
+ Let's see a few examples of things we can do with a
+ QList::iterator that we cannot do with a QList::const_iterator.
+ Here's an example that increments every value stored in a
+ QList\<int\> by 2:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qlistdata.cpp 16
+
+ Most QList functions accept an integer index rather than an
+ iterator. For that reason, iterators are rarely useful in
+ connection with QList. One place where STL-style iterators do
+ make sense is as arguments to \l{generic algorithms}.
+
+ For example, here's how to delete all the widgets stored in a
+ QList\<QWidget *\>:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qlistdata.cpp 17
+
+ Multiple iterators can be used on the same list. However, be
+ aware that any non-const function call performed on the QList
+ will render all existing iterators undefined. If you need to keep
+ iterators over a long period of time, we recommend that you use
+ QLinkedList rather than QList.
+
+ \sa QList::const_iterator, QMutableListIterator
+*/
+
+/*! \typedef QList::iterator::iterator_category
+
+ \internal
+*/
+
+/*! \typedef QList::iterator::difference_type
+
+ \internal
+*/
+
+/*! \typedef QList::iterator::value_type
+
+ \internal
+*/
+
+/*! \typedef QList::iterator::pointer
+
+ \internal
+*/
+
+/*! \typedef QList::iterator::reference
+
+ \internal
+*/
+
+/*! \fn QList::iterator::iterator()
+
+ Constructs an uninitialized iterator.
+
+ Functions like operator*() and operator++() should not be called
+ on an uninitialized iterartor. Use operator=() to assign a value
+ to it before using it.
+
+ \sa QList::begin() QList::end()
+*/
+
+/*! \fn QList::iterator::iterator(Node *node)
+
+ \internal
+*/
+
+/*! \fn QList::iterator::iterator(const iterator &other)
+
+ Constructs a copy of \a other.
+*/
+
+/*! \fn T &QList::iterator::operator*() const
+
+ Returns a modifiable reference to the current item.
+
+ You can change the value of an item by using operator*() on the
+ left side of an assignment, for example:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qlistdata.cpp 18
+
+ \sa operator->()
+*/
+
+/*! \fn T *QList::iterator::operator->() const
+
+ Returns a pointer to the current item.
+
+ \sa operator*()
+*/
+
+/*! \fn T &QList::iterator::operator[](int j) const
+
+ Returns a modifiable reference to the item at position *this +
+ \a{j}.
+
+ This function is provided to make QList iterators behave like C++
+ pointers.
+
+ \sa operator+()
+*/
+
+/*!
+ \fn bool QList::iterator::operator==(const iterator &other) const
+ \fn bool QList::iterator::operator==(const const_iterator &other) const
+
+ Returns true if \a other points to the same item as this
+ iterator; otherwise returns false.
+
+ \sa operator!=()
+*/
+
+/*!
+ \fn bool QList::iterator::operator!=(const iterator &other) const
+ \fn bool QList::iterator::operator!=(const const_iterator &other) const
+
+ Returns true if \a other points to a different item than this
+ iterator; otherwise returns false.
+
+ \sa operator==()
+*/
+
+/*!
+ \fn bool QList::iterator::operator<(const iterator& other) const
+ \fn bool QList::iterator::operator<(const const_iterator& other) const
+
+ Returns true if the item pointed to by this iterator is less than
+ the item pointed to by the \a other iterator.
+*/
+
+/*!
+ \fn bool QList::iterator::operator<=(const iterator& other) const
+ \fn bool QList::iterator::operator<=(const const_iterator& other) const
+
+ Returns true if the item pointed to by this iterator is less than
+ or equal to the item pointed to by the \a other iterator.
+*/
+
+/*!
+ \fn bool QList::iterator::operator>(const iterator& other) const
+ \fn bool QList::iterator::operator>(const const_iterator& other) const
+
+ Returns true if the item pointed to by this iterator is greater
+ than the item pointed to by the \a other iterator.
+*/
+
+/*!
+ \fn bool QList::iterator::operator>=(const iterator& other) const
+ \fn bool QList::iterator::operator>=(const const_iterator& other) const
+
+ Returns true if the item pointed to by this iterator is greater
+ than or equal to the item pointed to by the \a other iterator.
+*/
+
+/*! \fn QList::iterator &QList::iterator::operator++()
+
+ The prefix ++ operator (\c{++it}) advances the iterator to the
+ next item in the list and returns an iterator to the new current
+ item.
+
+ Calling this function on QList::end() leads to undefined results.
+
+ \sa operator--()
+*/
+
+/*! \fn QList::iterator QList::iterator::operator++(int)
+
+ \overload
+
+ The postfix ++ operator (\c{it++}) advances the iterator to the
+ next item in the list and returns an iterator to the previously
+ current item.
+*/
+
+/*! \fn QList::iterator &QList::iterator::operator--()
+
+ The prefix -- operator (\c{--it}) makes the preceding item
+ current and returns an iterator to the new current item.
+
+ Calling this function on QList::begin() leads to undefined results.
+
+ \sa operator++()
+*/
+
+/*! \fn QList::iterator QList::iterator::operator--(int)
+
+ \overload
+
+ The postfix -- operator (\c{it--}) makes the preceding item
+ current and returns an iterator to the previously current item.
+*/
+
+/*! \fn QList::iterator &QList::iterator::operator+=(int j)
+
+ Advances the iterator by \a j items. (If \a j is negative, the
+ iterator goes backward.)
+
+ \sa operator-=(), operator+()
+*/
+
+/*! \fn QList::iterator &QList::iterator::operator-=(int j)
+
+ Makes the iterator go back by \a j items. (If \a j is negative,
+ the iterator goes forward.)
+
+ \sa operator+=(), operator-()
+*/
+
+/*! \fn QList::iterator QList::iterator::operator+(int j) const
+
+ Returns an iterator to the item at \a j positions forward from
+ this iterator. (If \a j is negative, the iterator goes backward.)
+
+ \sa operator-(), operator+=()
+*/
+
+/*! \fn QList::iterator QList::iterator::operator-(int j) const
+
+ Returns an iterator to the item at \a j positions backward from
+ this iterator. (If \a j is negative, the iterator goes forward.)
+
+ \sa operator+(), operator-=()
+*/
+
+/*! \fn int QList::iterator::operator-(iterator other) const
+
+ Returns the number of items between the item pointed to by \a
+ other and the item pointed to by this iterator.
+*/
+
+/*! \class QList::const_iterator
+ \brief The QList::const_iterator class provides an STL-style const iterator for QList and QQueue.
+
+ QList provides both \l{STL-style iterators} and \l{Java-style
+ iterators}. The STL-style iterators are more low-level and more
+ cumbersome to use; on the other hand, they are slightly faster
+ and, for developers who already know STL, have the advantage of
+ familiarity.
+
+ QList\<T\>::const_iterator allows you to iterate over a
+ QList\<T\> (or a QQueue\<T\>). If you want to modify the QList as
+ you iterate over it, use QList::iterator instead. It is generally
+ good practice to use QList::const_iterator on a non-const QList
+ as well, unless you need to change the QList through the
+ iterator. Const iterators are slightly faster, and can improve
+ code readability.
+
+ The default QList::const_iterator constructor creates an
+ uninitialized iterator. You must initialize it using a QList
+ function like QList::constBegin(), QList::constEnd(), or
+ QList::insert() before you can start iterating. Here's a typical
+ loop that prints all the items stored in a list:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qlistdata.cpp 19
+
+ Most QList functions accept an integer index rather than an
+ iterator. For that reason, iterators are rarely useful in
+ connection with QList. One place where STL-style iterators do
+ make sense is as arguments to \l{generic algorithms}.
+
+ For example, here's how to delete all the widgets stored in a
+ QList\<QWidget *\>:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qlistdata.cpp 20
+
+ Multiple iterators can be used on the same list. However, be
+ aware that any non-const function call performed on the QList
+ will render all existing iterators undefined. If you need to keep
+ iterators over a long period of time, we recommend that you use
+ QLinkedList rather than QList.
+
+ \sa QList::iterator, QListIterator
+*/
+
+/*! \fn QList::const_iterator::const_iterator()
+
+ Constructs an uninitialized iterator.
+
+ Functions like operator*() and operator++() should not be called
+ on an uninitialized iterartor. Use operator=() to assign a value
+ to it before using it.
+
+ \sa QList::constBegin() QList::constEnd()
+*/
+
+/*! \typedef QList::const_iterator::iterator_category
+
+ \internal
+*/
+
+/*! \typedef QList::const_iterator::difference_type
+
+ \internal
+*/
+
+/*! \typedef QList::const_iterator::value_type
+
+ \internal
+*/
+
+/*! \typedef QList::const_iterator::pointer
+
+ \internal
+*/
+
+/*! \typedef QList::const_iterator::reference
+
+ \internal
+*/
+
+/*! \fn QList::const_iterator::const_iterator(Node *node)
+
+ \internal
+*/
+
+/*! \fn QList::const_iterator::const_iterator(const const_iterator &other)
+
+ Constructs a copy of \a other.
+*/
+
+/*! \fn QList::const_iterator::const_iterator(const iterator &other)
+
+ Constructs a copy of \a other.
+*/
+
+/*! \fn const T &QList::const_iterator::operator*() const
+
+ Returns the current item.
+
+ \sa operator->()
+*/
+
+/*! \fn const T *QList::const_iterator::operator->() const
+
+ Returns a pointer to the current item.
+
+ \sa operator*()
+*/
+
+/*! \fn const T &QList::const_iterator::operator[](int j) const
+
+ Returns the item at position *this + \a{j}.
+
+ This function is provided to make QList iterators behave like C++
+ pointers.
+
+ \sa operator+()
+*/
+
+/*! \fn bool QList::const_iterator::operator==(const const_iterator &other) const
+
+ Returns true if \a other points to the same item as this
+ iterator; otherwise returns false.
+
+ \sa operator!=()
+*/
+
+/*! \fn bool QList::const_iterator::operator!=(const const_iterator &other) const
+
+ Returns true if \a other points to a different item than this
+ iterator; otherwise returns false.
+
+ \sa operator==()
+*/
+
+/*!
+ \fn bool QList::const_iterator::operator<(const const_iterator& other) const
+
+ Returns true if the item pointed to by this iterator is less than
+ the item pointed to by the \a other iterator.
+*/
+
+/*!
+ \fn bool QList::const_iterator::operator<=(const const_iterator& other) const
+
+ Returns true if the item pointed to by this iterator is less than
+ or equal to the item pointed to by the \a other iterator.
+*/
+
+/*!
+ \fn bool QList::const_iterator::operator>(const const_iterator& other) const
+
+ Returns true if the item pointed to by this iterator is greater
+ than the item pointed to by the \a other iterator.
+*/
+
+/*!
+ \fn bool QList::const_iterator::operator>=(const const_iterator& other) const
+
+ Returns true if the item pointed to by this iterator is greater
+ than or equal to the item pointed to by the \a other iterator.
+*/
+
+/*! \fn QList::const_iterator &QList::const_iterator::operator++()
+
+ The prefix ++ operator (\c{++it}) advances the iterator to the
+ next item in the list and returns an iterator to the new current
+ item.
+
+ Calling this function on QList::end() leads to undefined results.
+
+ \sa operator--()
+*/
+
+/*! \fn QList::const_iterator QList::const_iterator::operator++(int)
+
+ \overload
+
+ The postfix ++ operator (\c{it++}) advances the iterator to the
+ next item in the list and returns an iterator to the previously
+ current item.
+*/
+
+/*! \fn QList::const_iterator &QList::const_iterator::operator--()
+
+ The prefix -- operator (\c{--it}) makes the preceding item
+ current and returns an iterator to the new current item.
+
+ Calling this function on QList::begin() leads to undefined results.
+
+ \sa operator++()
+*/
+
+/*! \fn QList::const_iterator QList::const_iterator::operator--(int)
+
+ \overload
+
+ The postfix -- operator (\c{it--}) makes the preceding item
+ current and returns an iterator to the previously current item.
+*/
+
+/*! \fn QList::const_iterator &QList::const_iterator::operator+=(int j)
+
+ Advances the iterator by \a j items. (If \a j is negative, the
+ iterator goes backward.)
+
+ \sa operator-=(), operator+()
+*/
+
+/*! \fn QList::const_iterator &QList::const_iterator::operator-=(int j)
+
+ Makes the iterator go back by \a j items. (If \a j is negative,
+ the iterator goes forward.)
+
+ \sa operator+=(), operator-()
+*/
+
+/*! \fn QList::const_iterator QList::const_iterator::operator+(int j) const
+
+ Returns an iterator to the item at \a j positions forward from
+ this iterator. (If \a j is negative, the iterator goes backward.)
+
+ \sa operator-(), operator+=()
+*/
+
+/*! \fn QList::const_iterator QList::const_iterator::operator-(int j) const
+
+ Returns an iterator to the item at \a j positions backward from
+ this iterator. (If \a j is negative, the iterator goes forward.)
+
+ \sa operator+(), operator-=()
+*/
+
+/*! \fn int QList::const_iterator::operator-(const_iterator other) const
+
+ Returns the number of items between the item pointed to by \a
+ other and the item pointed to by this iterator.
+*/
+
+/*! \fn QDataStream &operator<<(QDataStream &out, const QList<T> &list)
+ \relates QList
+
+ Writes the list \a list to stream \a out.
+
+ This function requires the value type to implement \c
+ operator<<().
+
+ \sa \link datastreamformat.html Format of the QDataStream operators \endlink
+*/
+
+/*! \fn QDataStream &operator>>(QDataStream &in, QList<T> &list)
+ \relates QList
+
+ Reads a list from stream \a in into \a list.
+
+ This function requires the value type to implement \c
+ operator>>().
+
+ \sa \link datastreamformat.html Format of the QDataStream operators \endlink
+*/
+
+/*!
+ \fn iterator QList::remove(iterator pos)
+
+ Use erase() instead.
+*/
+
+/*!
+ \fn int QList::remove(const T &t)
+
+ Use removeAll() instead.
+*/
+
+/*!
+ \fn int QList::findIndex(const T& t) const
+
+ Use indexOf() instead.
+*/
+
+/*!
+ \fn iterator QList::find(const T& t)
+
+ Use indexOf() instead.
+*/
+
+/*!
+ \fn const_iterator QList::find (const T& t) const
+
+ Use indexOf() instead.
+*/
+
+/*!
+ \fn iterator QList::find(iterator from, const T& t)
+
+ Use indexOf() instead.
+*/
+
+/*!
+ \fn const_iterator QList::find(const_iterator from, const T& t) const
+
+ Use indexOf() instead.
+*/
+
+/*! \fn QList<T> QList<T>::fromVector(const QVector<T> &vector)
+
+ Returns a QList object with the data contained in \a vector.
+
+ Example:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qlistdata.cpp 21
+
+ \sa fromSet(), toVector(), QVector::toList()
+*/
+
+/*! \fn QVector<T> QList<T>::toVector() const
+
+ Returns a QVector object with the data contained in this QList.
+
+ Example:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qlistdata.cpp 22
+
+ \sa toSet(), fromVector(), QVector::fromList()
+*/
+
+/*! \fn QList<T> QList<T>::fromSet(const QSet<T> &set)
+
+ Returns a QList object with the data contained in \a set. The
+ order of the elements in the QList is undefined.
+
+ Example:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qlistdata.cpp 23
+
+ \sa fromVector(), toSet(), QSet::toList(), qSort()
+*/
+
+/*! \fn QSet<T> QList<T>::toSet() const
+
+ Returns a QSet object with the data contained in this QList.
+ Since QSet doesn't allow duplicates, the resulting QSet might be
+ smaller than the original list was.
+
+ Example:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qlistdata.cpp 24
+
+ \sa toVector(), fromSet(), QSet::fromList()
+*/
+
+/*! \fn QList<T> QList<T>::fromStdList(const std::list<T> &list)
+
+ Returns a QList object with the data contained in \a list. The
+ order of the elements in the QList is the same as in \a list.
+
+ Example:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qlistdata.cpp 25
+
+ \sa toStdList(), QVector::fromStdVector()
+*/
+
+/*! \fn std::list<T> QList<T>::toStdList() const
+
+ Returns a std::list object with the data contained in this QList.
+ Example:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qlistdata.cpp 26
+
+ \sa fromStdList(), QVector::toStdVector()
+*/
+
+QT_END_NAMESPACE
diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp
new file mode 100644
index 0000000000..db2fc26409
--- /dev/null
+++ b/src/corelib/tools/qlocale.cpp
@@ -0,0 +1,7220 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qglobal.h"
+
+#ifndef QT_NO_SYSTEMLOCALE
+#define QLOCALE_CPP
+QT_BEGIN_NAMESPACE
+class QSystemLocale;
+static QSystemLocale *QSystemLocale_globalSystemLocale();
+QT_END_NAMESPACE
+#endif
+
+#include "qplatformdefs.h"
+
+#include "qdatastream.h"
+#include "qstring.h"
+#include "qlocale.h"
+#include "qlocale_p.h"
+#include "qdatetime_p.h"
+#include "qnamespace.h"
+#include "qdatetime.h"
+#include "qstringlist.h"
+#include "qvariant.h"
+#if defined(Q_WS_WIN)
+# include "qt_windows.h"
+# include <time.h>
+#endif
+#if !defined(QWS) && defined(Q_OS_MAC)
+# include "private/qcore_mac_p.h"
+# include <CoreFoundation/CoreFoundation.h>
+#endif
+#include "private/qnumeric_p.h"
+
+#include <ctype.h>
+#include <float.h>
+#include <limits.h>
+#include <math.h>
+#include <stdlib.h>
+#include <qdebug.h>
+#include <time.h>
+
+#if defined(Q_OS_LINUX) && !defined(__UCLIBC__)
+# include <fenv.h>
+#endif
+
+#if !defined(QT_QLOCALE_NEEDS_VOLATILE)
+# if defined(Q_CC_GNU)
+# if __GNUC__ == 4
+# define QT_QLOCALE_NEEDS_VOLATILE
+# elif defined(Q_OS_WIN)
+# define QT_QLOCALE_NEEDS_VOLATILE
+# endif
+# endif
+#endif
+
+#if defined(QT_QLOCALE_NEEDS_VOLATILE)
+# define NEEDS_VOLATILE volatile
+#else
+# define NEEDS_VOLATILE
+#endif
+
+// Sizes as defined by the ISO C99 standard - fallback
+#ifndef LLONG_MAX
+# define LLONG_MAX Q_INT64_C(0x7fffffffffffffff)
+#endif
+#ifndef LLONG_MIN
+# define LLONG_MIN (-LLONG_MAX - Q_INT64_C(1))
+#endif
+#ifndef ULLONG_MAX
+# define ULLONG_MAX Q_UINT64_C(0xffffffffffffffff)
+#endif
+
+#define CONVERSION_BUFF_SIZE 255
+
+QT_BEGIN_NAMESPACE
+
+#ifndef QT_QLOCALE_USES_FCVT
+static char *_qdtoa( NEEDS_VOLATILE double d, int mode, int ndigits, int *decpt,
+ int *sign, char **rve, char **digits_str);
+#endif
+Q_CORE_EXPORT char *qdtoa(double d, int mode, int ndigits, int *decpt,
+ int *sign, char **rve, char **digits_str);
+Q_CORE_EXPORT double qstrtod(const char *s00, char const **se, bool *ok);
+Q_CORE_EXPORT qlonglong qstrtoll(const char *nptr, const char **endptr, register int base, bool *ok);
+static qulonglong qstrtoull(const char *nptr, const char **endptr, register int base, bool *ok);
+
+/******************************************************************************
+** Helpers for accessing Qt locale database
+*/
+
+QT_BEGIN_INCLUDE_NAMESPACE
+#include "qlocale_data_p.h"
+QT_END_INCLUDE_NAMESPACE
+
+QLocale::MeasurementSystem QLocalePrivate::measurementSystem() const
+{
+ for (int i = 0; i < ImperialMeasurementSystemsCount; ++i) {
+ if (ImperialMeasurementSystems[i].languageId == m_language_id
+ && ImperialMeasurementSystems[i].countryId == m_country_id) {
+ return QLocale::ImperialSystem;
+ }
+ }
+ return QLocale::MetricSystem;
+}
+
+// Assumes that code is a
+// QChar code[3];
+// If the code is two-digit the third digit must be 0
+static QLocale::Language codeToLanguage(const QChar *code)
+{
+ ushort uc1 = code[0].unicode();
+ ushort uc2 = code[1].unicode();
+ ushort uc3 = code[2].unicode();
+
+ if (uc1 == 'n' && uc2 == 'o' && uc3 == 0)
+ uc2 = 'b';
+
+ 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);
+ }
+
+ return QLocale::C;
+}
+
+// Assumes that code is a
+// QChar code[2];
+static QLocale::Country codeToCountry(const QChar *code)
+{
+ ushort uc1 = code[0].unicode();
+ ushort uc2 = code[1].unicode();
+
+ const unsigned char *c = country_code_list;
+ for (; *c != 0; c += 2) {
+ if (uc1 == c[0] && uc2 == c[1])
+ return QLocale::Country((c - country_code_list)/2);
+ }
+
+ return QLocale::AnyCountry;
+}
+
+static QString languageToCode(QLocale::Language language)
+{
+ if (language == QLocale::C)
+ return QLatin1String("C");
+
+ const unsigned char *c = language_code_list + 3*(uint(language));
+
+ QString code;
+ code.resize(c[2] == 0 ? 2 : 3);
+
+ code[0] = ushort(c[0]);
+ code[1] = ushort(c[1]);
+ if (c[2] != 0)
+ code[2] = ushort(c[2]);
+
+ return code;
+}
+
+static QString countryToCode(QLocale::Country country)
+{
+ if (country == QLocale::AnyCountry)
+ return QString();
+
+ QString code;
+ code.resize(2);
+ const unsigned char *c = country_code_list + 2*(uint(country));
+ code[0] = ushort(c[0]);
+ code[1] = ushort(c[1]);
+ return code;
+}
+
+static const QLocalePrivate *findLocale(QLocale::Language language, QLocale::Country country)
+{
+ unsigned language_id = language;
+ unsigned country_id = country;
+
+ uint idx = locale_index[language_id];
+
+ const QLocalePrivate *d = locale_data + idx;
+
+ if (idx == 0) // default language has no associated country
+ return d;
+
+ if (country == QLocale::AnyCountry)
+ return d;
+
+ Q_ASSERT(d->languageId() == language_id);
+
+ while (d->languageId() == language_id
+ && d->countryId() != country_id)
+ ++d;
+
+ if (d->countryId() == country_id
+ && d->languageId() == language_id)
+ return d;
+
+ return locale_data + idx;
+}
+
+static bool splitLocaleName(const QString &name, QChar *lang_begin, QChar *cntry_begin)
+{
+ for (int i = 0; i < 3; ++i)
+ lang_begin[i] = 0;
+ for (int i = 0; i < 2; ++i)
+ cntry_begin[i] = 0;
+
+ int l = name.length();
+
+ QChar *lang = lang_begin;
+ QChar *cntry = cntry_begin;
+
+ int state = 0;
+ const QChar *uc = name.unicode();
+ for (int i = 0; i < l; ++i) {
+ if (uc->unicode() == '.' || uc->unicode() == '@')
+ break;
+
+ switch (state) {
+ case 0:
+ // parsing language
+ if (uc->unicode() == '_') {
+ state = 1;
+ break;
+ }
+ if (lang - lang_begin == 3)
+ return false;
+ if (uc->unicode() < 'a' || uc->unicode() > 'z')
+ return false;
+
+ *lang = *uc;
+ ++lang;
+ break;
+ case 1:
+ // parsing country
+ if (cntry - cntry_begin == 2) {
+ cntry_begin[0] = 0;
+ break;
+ }
+
+ *cntry = *uc;
+ ++cntry;
+ break;
+ }
+
+ ++uc;
+ }
+
+ int lang_len = lang - lang_begin;
+
+ return lang_len == 2 || lang_len == 3;
+}
+
+static void getLangAndCountry(const QString &name, QLocale::Language &lang, QLocale::Country &cntry)
+{
+ lang = QLocale::C;
+ cntry = QLocale::AnyCountry;
+
+ QChar lang_code[3];
+ QChar cntry_code[2];
+ if (!splitLocaleName(name, lang_code, cntry_code))
+ return;
+
+ lang = codeToLanguage(lang_code);
+ if (lang == QLocale::C)
+ return;
+
+ if (cntry_code[0].unicode() != 0)
+ cntry = codeToCountry(cntry_code);
+}
+
+static const QLocalePrivate *findLocale(const QString &name)
+{
+ QLocale::Language lang;
+ QLocale::Country cntry;
+ getLangAndCountry(name, lang, cntry);
+
+ return findLocale(lang, cntry);
+}
+static QString readEscapedFormatString(const QString &format, int *idx)
+{
+ int &i = *idx;
+
+ Q_ASSERT(format.at(i).unicode() == '\'');
+ ++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;
+}
+
+static int repeatCount(const QString &s, int i)
+{
+ QChar c = s.at(i);
+ int j = i + 1;
+ while (j < s.size() && s.at(j) == c)
+ ++j;
+ return j - i;
+}
+
+static const QLocalePrivate *default_lp = 0;
+static uint default_number_options = 0;
+
+#ifndef QT_NO_SYSTEMLOCALE
+static QByteArray envVarLocale()
+{
+ static QByteArray lang = 0;
+#ifdef Q_OS_UNIX
+ lang = qgetenv("LC_ALL");
+ if (lang.isNull())
+ lang = qgetenv("LC_NUMERIC");
+ if (lang.isNull())
+#endif
+ lang = qgetenv("LANG");
+ return lang;
+}
+
+
+#if defined(Q_OS_WIN)
+/******************************************************************************
+** Wrappers for Windows locale system functions
+*/
+
+static const char *winLangCodeToIsoName(int code);
+static QString winIso639LangName(LCID id = LOCALE_USER_DEFAULT);
+static QString winIso3116CtryName(LCID id = LOCALE_USER_DEFAULT);
+
+static QString getWinLocaleInfo(LCTYPE type)
+{
+ int cnt = 0;
+
+ LCID id = GetUserDefaultLCID();
+
+ QT_WA({
+ cnt = GetLocaleInfoW(id, type, 0, 0)*2;
+ } , {
+ cnt = GetLocaleInfoA(id, type, 0, 0);
+ });
+
+ if (cnt == 0) {
+ qWarning("QLocale: empty windows locale info (%d)", (int)type);
+ return QString();
+ }
+
+ QByteArray buff(cnt, 0);
+
+ QT_WA({
+ cnt = GetLocaleInfoW(id, type,
+ reinterpret_cast<wchar_t*>(buff.data()),
+ buff.size()/2);
+ } , {
+ cnt = GetLocaleInfoA(id, type,
+ buff.data(), buff.size());
+ });
+
+ if (cnt == 0) {
+ qWarning("QLocale: empty windows locale info (%d)", (int)type);
+ return QString();
+ }
+
+ QString result;
+ QT_WA({
+ result = QString::fromUtf16(reinterpret_cast<ushort*>(buff.data()));
+ } , {
+ result = QString::fromLocal8Bit(buff.data());
+ });
+ return result;
+}
+
+QByteArray getWinLocaleName(LCID id = LOCALE_USER_DEFAULT)
+{
+ QByteArray result;
+ if (id == LOCALE_USER_DEFAULT) {
+ result = envVarLocale();
+ QChar lang[3];
+ QChar cntry[2];
+ if ( result == "C" || !result.isEmpty()
+ && splitLocaleName(QString::fromLocal8Bit(result), lang, cntry) ) {
+ long id = 0;
+ bool ok = false;
+ id = qstrtoll(result.data(), 0, 0, &ok);
+ if ( !ok || id == 0 || id < INT_MIN || id > INT_MAX )
+ return result;
+ else
+ return winLangCodeToIsoName( (int)id );
+ }
+ }
+
+ if (QSysInfo::WindowsVersion == QSysInfo::WV_95
+ || (QSysInfo::WindowsVersion & QSysInfo::WV_CE_based)) {
+ result = winLangCodeToIsoName(id != LOCALE_USER_DEFAULT ? id : GetUserDefaultLCID());
+ } else {
+ if (id == LOCALE_USER_DEFAULT)
+ id = GetUserDefaultLCID();
+ QString resultuage = winIso639LangName(id);
+ QString country = winIso3116CtryName(id);
+ result = resultuage.toLatin1();
+ if (!country.isEmpty()) {
+ result += '_';
+ result += country.toLatin1();
+ }
+ }
+
+ return result;
+}
+
+Q_CORE_EXPORT QLocale qt_localeFromLCID(LCID id)
+{
+ return QLocale(QString::fromLatin1(getWinLocaleName(id)));
+}
+
+static QString winToQtFormat(const QString &sys_fmt)
+{
+ QString result;
+ int i = 0;
+
+ while (i < sys_fmt.size()) {
+ if (sys_fmt.at(i).unicode() == QLatin1Char('\'')) {
+ QString text = readEscapedFormatString(sys_fmt, &i);
+ if (text == QLatin1String("'"))
+ result += QLatin1String("''");
+ else
+ result += QLatin1Char('\'') + text + QLatin1Char('\'');
+ continue;
+ }
+
+ QChar c = sys_fmt.at(i);
+ int repeat = repeatCount(sys_fmt, i);
+
+ switch (c.unicode()) {
+ // Date
+ case 'y':
+ if (repeat > 5)
+ repeat = 5;
+ else if (repeat == 3)
+ repeat = 2;
+ switch (repeat) {
+ case 1:
+ result += QLatin1String("yy"); // "y" unsupported by Qt, use "yy"
+ break;
+ case 5:
+ result += QLatin1String("yyyy"); // "yyyyy" same as "yyyy" on Windows
+ break;
+ default:
+ result += QString(repeat, QLatin1Char('y'));
+ break;
+ }
+ break;
+ case 'g':
+ if (repeat > 2)
+ repeat = 2;
+ switch (repeat) {
+ case 2:
+ break; // no equivalent of "gg" in Qt
+ default:
+ result += QLatin1Char('g');
+ break;
+ }
+ break;
+ case 't':
+ if (repeat > 2)
+ repeat = 2;
+ result += QLatin1String("AP"); // "t" unsupported, use "AP"
+ break;
+ default:
+ result += QString(repeat, c);
+ break;
+ }
+
+ i += repeat;
+ }
+
+ return result;
+}
+
+
+
+static QString winDateToString(const QDate &date, DWORD flags)
+{
+ SYSTEMTIME st;
+ memset(&st, 0, sizeof(SYSTEMTIME));
+ st.wYear = date.year();
+ st.wMonth = date.month();
+ st.wDay = date.day();
+
+ LCID id = GetUserDefaultLCID();
+
+ QT_WA({
+ TCHAR buf[255];
+ if (GetDateFormatW(id, flags, &st, 0, buf, 255))
+ return QString::fromUtf16((ushort*)buf);
+ } , {
+ char buf[255];
+ if (GetDateFormatA(id, flags, &st, 0, (char*)&buf, 255))
+ return QString::fromLocal8Bit(buf);
+ });
+
+ return QString();
+}
+
+static QString winTimeToString(const QTime &time)
+{
+ SYSTEMTIME st;
+ memset(&st, 0, sizeof(SYSTEMTIME));
+ st.wHour = time.hour();
+ st.wMinute = time.minute();
+ st.wSecond = time.second();
+ st.wMilliseconds = 0;
+
+ DWORD flags = 0;
+ LCID id = GetUserDefaultLCID();
+
+ QT_WA({
+ TCHAR buf[255];
+ if (GetTimeFormatW(id, flags, &st, 0, buf, 255))
+ return QString::fromUtf16((ushort*)buf);
+ } , {
+ char buf[255];
+ if (GetTimeFormatA(id, flags, &st, 0, (char*)&buf, 255))
+ return QString::fromLocal8Bit(buf);
+ });
+
+ return QString();
+}
+
+static QString winDayName(int day, bool short_format)
+{
+ static const LCTYPE short_day_map[]
+ = { LOCALE_SABBREVDAYNAME1, LOCALE_SABBREVDAYNAME2,
+ LOCALE_SABBREVDAYNAME3, LOCALE_SABBREVDAYNAME4, LOCALE_SABBREVDAYNAME5,
+ LOCALE_SABBREVDAYNAME6, LOCALE_SABBREVDAYNAME7 };
+
+ static const LCTYPE long_day_map[]
+ = { LOCALE_SDAYNAME1, LOCALE_SDAYNAME2,
+ LOCALE_SDAYNAME3, LOCALE_SDAYNAME4, LOCALE_SDAYNAME5,
+ LOCALE_SDAYNAME6, LOCALE_SDAYNAME7 };
+
+ day -= 1;
+
+ LCTYPE type = short_format
+ ? short_day_map[day] : long_day_map[day];
+ return getWinLocaleInfo(type);
+}
+
+static QString winMonthName(int month, bool short_format)
+{
+ static const LCTYPE short_month_map[]
+ = { LOCALE_SABBREVMONTHNAME1, LOCALE_SABBREVMONTHNAME2, LOCALE_SABBREVMONTHNAME3,
+ LOCALE_SABBREVMONTHNAME4, LOCALE_SABBREVMONTHNAME5, LOCALE_SABBREVMONTHNAME6,
+ LOCALE_SABBREVMONTHNAME7, LOCALE_SABBREVMONTHNAME8, LOCALE_SABBREVMONTHNAME9,
+ LOCALE_SABBREVMONTHNAME10, LOCALE_SABBREVMONTHNAME11, LOCALE_SABBREVMONTHNAME12 };
+
+ static const LCTYPE long_month_map[]
+ = { LOCALE_SMONTHNAME1, LOCALE_SMONTHNAME2, LOCALE_SMONTHNAME3,
+ LOCALE_SMONTHNAME4, LOCALE_SMONTHNAME5, LOCALE_SMONTHNAME6,
+ LOCALE_SMONTHNAME7, LOCALE_SMONTHNAME8, LOCALE_SMONTHNAME9,
+ LOCALE_SMONTHNAME10, LOCALE_SMONTHNAME11, LOCALE_SMONTHNAME12 };
+
+ month -= 1;
+ if (month < 0 || month > 11)
+ return QString();
+
+ LCTYPE type = short_format ? short_month_map[month] : long_month_map[month];
+ return getWinLocaleInfo(type);
+}
+
+static QLocale::MeasurementSystem winSystemMeasurementSystem()
+{
+ LCID id = GetUserDefaultLCID();
+ TCHAR output[2];
+
+ if (GetLocaleInfo(id, LOCALE_IMEASURE, output, 2)) {
+ QString iMeasure = QT_WA_INLINE(
+ QString::fromUtf16(reinterpret_cast<ushort*>(output)),
+ QString::fromLocal8Bit(reinterpret_cast<char*>(output)));
+ if (iMeasure == QString::fromLatin1("1")) {
+ return QLocale::ImperialSystem;
+ }
+ }
+
+ return QLocale::MetricSystem;
+}
+
+static QString winSystemAMText()
+{
+ LCID id = GetUserDefaultLCID();
+ TCHAR output[15]; // maximum length including terminating zero character for Win2003+
+
+ if (GetLocaleInfo(id, LOCALE_S1159, output, 15)) {
+ return QT_WA_INLINE(
+ QString::fromUtf16(reinterpret_cast<ushort*>(output)),
+ QString::fromLocal8Bit(reinterpret_cast<char*>(output)));
+ }
+
+ return QString();
+}
+
+static QString winSystemPMText()
+{
+ LCID id = GetUserDefaultLCID();
+ TCHAR output[15]; // maximum length including terminating zero character for Win2003+
+
+ if (GetLocaleInfo(id, LOCALE_S2359, output, 15)) {
+ return QT_WA_INLINE(
+ QString::fromUtf16(reinterpret_cast<ushort*>(output)),
+ QString::fromLocal8Bit(reinterpret_cast<char*>(output)));
+ }
+
+ return QString();
+}
+
+QLocale QSystemLocale::fallbackLocale() const
+{
+ return QLocale(QString::fromLatin1(getWinLocaleName()));
+}
+
+QVariant QSystemLocale::query(QueryType type, QVariant in = QVariant()) const
+{
+ LCTYPE locale_info = 0;
+ bool format_string = false;
+
+ switch(type) {
+// case Name:
+// return getWinLocaleName();
+ case DecimalPoint:
+ locale_info = LOCALE_SDECIMAL;
+ break;
+ case GroupSeparator:
+ locale_info = LOCALE_STHOUSAND;
+ break;
+ case NegativeSign:
+ locale_info = LOCALE_SNEGATIVESIGN;
+ break;
+ case PositiveSign:
+ locale_info = LOCALE_SPOSITIVESIGN;
+ break;
+ case DateFormatLong:
+ locale_info = LOCALE_SLONGDATE;
+ format_string = true;
+ break;
+ case DateFormatShort:
+ locale_info = LOCALE_SSHORTDATE;
+ format_string = true;
+ break;
+ case TimeFormatLong:
+ case TimeFormatShort:
+ locale_info = LOCALE_STIMEFORMAT;
+ format_string = true;
+ break;
+
+ case DateTimeFormatLong:
+ case DateTimeFormatShort:
+ return query(type == DateTimeFormatLong ? DateFormatLong : DateFormatShort).toString()
+ + QLatin1Char(' ') + query(type == DateTimeFormatLong ? TimeFormatLong : TimeFormatShort).toString();
+ case DayNameLong:
+ case DayNameShort:
+ return winDayName(in.toInt(), (type == DayNameShort));
+ case MonthNameLong:
+ case MonthNameShort:
+ return winMonthName(in.toInt(), (type == MonthNameShort));
+ case DateToStringShort:
+ case DateToStringLong:
+ return winDateToString(in.toDate(), type == DateToStringShort ? DATE_SHORTDATE : DATE_LONGDATE);
+ case TimeToStringShort:
+ case TimeToStringLong:
+ return winTimeToString(in.toTime());
+ case DateTimeToStringShort:
+ case DateTimeToStringLong: {
+ const QDateTime dt = in.toDateTime();
+ return winDateToString(dt.date(), type == DateTimeToStringShort ? DATE_SHORTDATE : DATE_LONGDATE)
+ + QLatin1Char(' ') + winTimeToString(dt.time()); }
+
+ case ZeroDigit:
+ locale_info = LOCALE_SNATIVEDIGITS;
+ break;
+
+ case LanguageId:
+ case CountryId: {
+ QString locale = QString::fromLatin1(getWinLocaleName());
+ QLocale::Language lang;
+ QLocale::Country cntry;
+ getLangAndCountry(locale, lang, cntry);
+ if (type == LanguageId)
+ return lang;
+ if (cntry == QLocale::AnyCountry)
+ return fallbackLocale().country();
+ return cntry;
+ }
+
+ case MeasurementSystem:
+ return QVariant(static_cast<int>(winSystemMeasurementSystem()));
+
+ case AMText:
+ return QVariant(winSystemAMText());
+ case PMText:
+ return QVariant(winSystemPMText());
+ default:
+ break;
+ }
+ if (locale_info) {
+ QString result = getWinLocaleInfo(locale_info);
+ if (format_string)
+ result = winToQtFormat(result);
+ if (!result.isEmpty())
+ return result;
+ }
+ return QVariant();
+}
+
+/* Win95 doesn't have a function to return the ISO lang/country name of the user's locale.
+ Instead it can return a "Windows code". This maps windows codes to ISO country names. */
+
+struct WindowsToISOListElt {
+ int windows_code;
+ char iso_name[6];
+};
+
+static const WindowsToISOListElt windows_to_iso_list[] = {
+ { 0x0401, "ar_SA" },
+ { 0x0402, "bg\0 " },
+ { 0x0403, "ca\0 " },
+ { 0x0404, "zh_TW" },
+ { 0x0405, "cs\0 " },
+ { 0x0406, "da\0 " },
+ { 0x0407, "de\0 " },
+ { 0x0408, "el\0 " },
+ { 0x0409, "en_US" },
+ { 0x040a, "es\0 " },
+ { 0x040b, "fi\0 " },
+ { 0x040c, "fr\0 " },
+ { 0x040d, "he\0 " },
+ { 0x040e, "hu\0 " },
+ { 0x040f, "is\0 " },
+ { 0x0410, "it\0 " },
+ { 0x0411, "ja\0 " },
+ { 0x0412, "ko\0 " },
+ { 0x0413, "nl\0 " },
+ { 0x0414, "no\0 " },
+ { 0x0415, "pl\0 " },
+ { 0x0416, "pt_BR" },
+ { 0x0418, "ro\0 " },
+ { 0x0419, "ru\0 " },
+ { 0x041a, "hr\0 " },
+ { 0x041c, "sq\0 " },
+ { 0x041d, "sv\0 " },
+ { 0x041e, "th\0 " },
+ { 0x041f, "tr\0 " },
+ { 0x0420, "ur\0 " },
+ { 0x0421, "in\0 " },
+ { 0x0422, "uk\0 " },
+ { 0x0423, "be\0 " },
+ { 0x0425, "et\0 " },
+ { 0x0426, "lv\0 " },
+ { 0x0427, "lt\0 " },
+ { 0x0429, "fa\0 " },
+ { 0x042a, "vi\0 " },
+ { 0x042d, "eu\0 " },
+ { 0x042f, "mk\0 " },
+ { 0x0436, "af\0 " },
+ { 0x0438, "fo\0 " },
+ { 0x0439, "hi\0 " },
+ { 0x043e, "ms\0 " },
+ { 0x0458, "mt\0 " },
+ { 0x0801, "ar_IQ" },
+ { 0x0804, "zh_CN" },
+ { 0x0807, "de_CH" },
+ { 0x0809, "en_GB" },
+ { 0x080a, "es_MX" },
+ { 0x080c, "fr_BE" },
+ { 0x0810, "it_CH" },
+ { 0x0812, "ko\0 " },
+ { 0x0813, "nl_BE" },
+ { 0x0814, "no\0 " },
+ { 0x0816, "pt\0 " },
+ { 0x081a, "sr\0 " },
+ { 0x081d, "sv_FI" },
+ { 0x0c01, "ar_EG" },
+ { 0x0c04, "zh_HK" },
+ { 0x0c07, "de_AT" },
+ { 0x0c09, "en_AU" },
+ { 0x0c0a, "es\0 " },
+ { 0x0c0c, "fr_CA" },
+ { 0x0c1a, "sr\0 " },
+ { 0x1001, "ar_LY" },
+ { 0x1004, "zh_SG" },
+ { 0x1007, "de_LU" },
+ { 0x1009, "en_CA" },
+ { 0x100a, "es_GT" },
+ { 0x100c, "fr_CH" },
+ { 0x1401, "ar_DZ" },
+ { 0x1407, "de_LI" },
+ { 0x1409, "en_NZ" },
+ { 0x140a, "es_CR" },
+ { 0x140c, "fr_LU" },
+ { 0x1801, "ar_MA" },
+ { 0x1809, "en_IE" },
+ { 0x180a, "es_PA" },
+ { 0x1c01, "ar_TN" },
+ { 0x1c09, "en_ZA" },
+ { 0x1c0a, "es_DO" },
+ { 0x2001, "ar_OM" },
+ { 0x2009, "en_JM" },
+ { 0x200a, "es_VE" },
+ { 0x2401, "ar_YE" },
+ { 0x2409, "en\0 " },
+ { 0x240a, "es_CO" },
+ { 0x2801, "ar_SY" },
+ { 0x2809, "en_BZ" },
+ { 0x280a, "es_PE" },
+ { 0x2c01, "ar_JO" },
+ { 0x2c09, "en_TT" },
+ { 0x2c0a, "es_AR" },
+ { 0x3001, "ar_LB" },
+ { 0x300a, "es_EC" },
+ { 0x3401, "ar_KW" },
+ { 0x340a, "es_CL" },
+ { 0x3801, "ar_AE" },
+ { 0x380a, "es_UY" },
+ { 0x3c01, "ar_BH" },
+ { 0x3c0a, "es_PY" },
+ { 0x4001, "ar_QA" },
+ { 0x400a, "es_BO" },
+ { 0x440a, "es_SV" },
+ { 0x480a, "es_HN" },
+ { 0x4c0a, "es_NI" },
+ { 0x500a, "es_PR" }
+};
+
+static const int windows_to_iso_count
+ = sizeof(windows_to_iso_list)/sizeof(WindowsToISOListElt);
+
+static const char *winLangCodeToIsoName(int code)
+{
+ int cmp = code - windows_to_iso_list[0].windows_code;
+ if (cmp < 0)
+ return 0;
+
+ if (cmp == 0)
+ return windows_to_iso_list[0].iso_name;
+
+ int begin = 0;
+ int end = windows_to_iso_count;
+
+ while (end - begin > 1) {
+ uint mid = (begin + end)/2;
+
+ const WindowsToISOListElt *elt = windows_to_iso_list + mid;
+ int cmp = code - elt->windows_code;
+ if (cmp < 0)
+ end = mid;
+ else if (cmp > 0)
+ begin = mid;
+ else
+ return elt->iso_name;
+ }
+
+ return 0;
+
+}
+
+static QString winIso639LangName(LCID id)
+{
+ QString result;
+
+ // Windows returns the wrong ISO639 for some languages, we need to detect them here using
+ // the language code
+ QString lang_code;
+ QT_WA({
+ TCHAR out[256];
+ if (GetLocaleInfoW(id, LOCALE_ILANGUAGE, out, 255))
+ lang_code = QString::fromUtf16((ushort*)out);
+ } , {
+ char out[256];
+ if (GetLocaleInfoA(id, LOCALE_ILANGUAGE, out, 255))
+ lang_code = QString::fromLocal8Bit(out);
+ });
+
+ if (!lang_code.isEmpty()) {
+ const char *endptr;
+ bool ok;
+ QByteArray latin1_lang_code = lang_code.toLatin1();
+ int i = qstrtoull(latin1_lang_code, &endptr, 16, &ok);
+ if (ok && *endptr == '\0') {
+ switch (i) {
+ case 0x814:
+ result = QLatin1String("nn"); // Nynorsk
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ if (!result.isEmpty())
+ return result;
+
+ // not one of the problematic languages - do the usual lookup
+ QT_WA({
+ TCHAR out[256];
+ if (GetLocaleInfoW(id, LOCALE_SISO639LANGNAME , out, 255))
+ result = QString::fromUtf16((ushort*)out);
+ } , {
+ char out[256];
+ if (GetLocaleInfoA(id, LOCALE_SISO639LANGNAME, out, 255))
+ result = QString::fromLocal8Bit(out);
+ });
+
+ return result;
+}
+
+static QString winIso3116CtryName(LCID id)
+{
+ QString result;
+
+ QT_WA({
+ TCHAR out[256];
+ if (GetLocaleInfoW(id, LOCALE_SISO3166CTRYNAME, out, 255))
+ result = QString::fromUtf16((ushort*)out);
+ } , {
+ char out[256];
+ if (GetLocaleInfoA(id, LOCALE_SISO3166CTRYNAME, out, 255))
+ result = QString::fromLocal8Bit(out);
+ });
+
+ return result;
+}
+
+
+#elif defined(Q_OS_MAC)
+/******************************************************************************
+** Wrappers for Mac locale system functions
+*/
+
+static QByteArray getMacLocaleName()
+{
+ QByteArray result = envVarLocale();
+
+ QChar lang[3];
+ QChar cntry[2];
+ if (result.isEmpty() || result != "C"
+ && !splitLocaleName(QString::fromLocal8Bit(result), lang, cntry)) {
+ QCFType<CFLocaleRef> l = CFLocaleCopyCurrent();
+ CFStringRef locale = CFLocaleGetIdentifier(l);
+ result = QCFString::toQString(locale).toUtf8();
+ }
+ return result;
+}
+
+static QString macMonthName(int month, bool short_format)
+{
+ month -= 1;
+ if (month < 0 || month > 11)
+ return QString();
+
+#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4)
+ if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_4) {
+ QCFType<CFDateFormatterRef> formatter
+ = CFDateFormatterCreate(0, QCFType<CFLocaleRef>(CFLocaleCopyCurrent()),
+ kCFDateFormatterNoStyle, kCFDateFormatterNoStyle);
+ QCFType<CFArrayRef> values
+ = static_cast<CFArrayRef>(CFDateFormatterCopyProperty(formatter,
+ short_format ? kCFDateFormatterShortMonthSymbols
+ : kCFDateFormatterMonthSymbols));
+ if (values != 0) {
+ CFStringRef cfstring = static_cast<CFStringRef>(CFArrayGetValueAtIndex(values, month));
+ return QCFString::toQString(cfstring);
+ }
+ }
+#endif
+ return QString();
+}
+
+
+static QString macDayName(int day, bool short_format)
+{
+ if (day < 1 || day > 7)
+ return QString();
+
+#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4)
+ if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_4) {
+ QCFType<CFDateFormatterRef> formatter
+ = CFDateFormatterCreate(0, QCFType<CFLocaleRef>(CFLocaleCopyCurrent()),
+ kCFDateFormatterNoStyle, kCFDateFormatterNoStyle);
+ QCFType<CFArrayRef> values = static_cast<CFArrayRef>(CFDateFormatterCopyProperty(formatter,
+ short_format ? kCFDateFormatterShortWeekdaySymbols
+ : kCFDateFormatterWeekdaySymbols));
+ if (values != 0) {
+ CFStringRef cfstring = static_cast<CFStringRef>(CFArrayGetValueAtIndex(values, day % 7));
+ return QCFString::toQString(cfstring);
+ }
+ }
+#endif
+ return QString();
+}
+
+static QString macDateToString(const QDate &date, bool short_format)
+{
+ CFGregorianDate macGDate;
+ macGDate.year = date.year();
+ macGDate.month = date.month();
+ macGDate.day = date.day();
+ macGDate.hour = 0;
+ macGDate.minute = 0;
+ macGDate.second = 0.0;
+ QCFType<CFDateRef> myDate
+ = CFDateCreate(0, CFGregorianDateGetAbsoluteTime(macGDate,
+ QCFType<CFTimeZoneRef>(CFTimeZoneCopyDefault())));
+ QCFType<CFLocaleRef> mylocale = CFLocaleCopyCurrent();
+ CFDateFormatterStyle style = short_format ? kCFDateFormatterShortStyle : kCFDateFormatterLongStyle;
+ QCFType<CFDateFormatterRef> myFormatter
+ = CFDateFormatterCreate(kCFAllocatorDefault,
+ mylocale, style,
+ kCFDateFormatterNoStyle);
+ return QCFString(CFDateFormatterCreateStringWithDate(0, myFormatter, myDate));
+}
+
+static QString macTimeToString(const QTime &time, bool short_format)
+{
+ CFGregorianDate macGDate;
+ // Assume this is local time and the current date
+ QDate dt = QDate::currentDate();
+ macGDate.year = dt.year();
+ macGDate.month = dt.month();
+ macGDate.day = dt.day();
+ macGDate.hour = time.hour();
+ macGDate.minute = time.minute();
+ macGDate.second = time.second();
+ QCFType<CFDateRef> myDate
+ = CFDateCreate(0, CFGregorianDateGetAbsoluteTime(macGDate,
+ QCFType<CFTimeZoneRef>(CFTimeZoneCopyDefault())));
+
+ QCFType<CFLocaleRef> mylocale = CFLocaleCopyCurrent();
+ CFDateFormatterStyle style = short_format ? kCFDateFormatterShortStyle : kCFDateFormatterLongStyle;
+ QCFType<CFDateFormatterRef> myFormatter = CFDateFormatterCreate(kCFAllocatorDefault,
+ mylocale,
+ kCFDateFormatterNoStyle,
+ style);
+ return QCFString(CFDateFormatterCreateStringWithDate(0, myFormatter, myDate));
+}
+
+static QString macToQtFormat(const QString &sys_fmt)
+{
+ QString result;
+ int i = 0;
+
+ while (i < sys_fmt.size()) {
+ if (sys_fmt.at(i).unicode() == '\'') {
+ QString text = readEscapedFormatString(sys_fmt, &i);
+ if (text == QLatin1String("'"))
+ result += QLatin1String("''");
+ else
+ result += QLatin1Char('\'') + text + QLatin1Char('\'');
+ continue;
+ }
+
+ QChar c = sys_fmt.at(i);
+ int repeat = repeatCount(sys_fmt, i);
+
+ switch (c.unicode()) {
+ case 'G': // Qt doesn't support these :(
+ case 'Y':
+ case 'D':
+ case 'F':
+ case 'w':
+ case 'W':
+ case 'g':
+ break;
+
+ case 'u': // extended year - use 'y'
+ if (repeat < 4)
+ result += QLatin1String("yy");
+ else
+ result += QLatin1String("yyyy");
+ break;
+ case 'S': // fractional second
+ if (repeat < 3)
+ result += QLatin1String("z");
+ else
+ result += QLatin1String("zzz");
+ break;
+ case 'E':
+ if (repeat <= 3)
+ result += QLatin1String("ddd");
+ else
+ result += QLatin1String("dddd");
+ break;
+ case 'e':
+ if (repeat >= 2)
+ result += QLatin1String("dd");
+ else
+ result += QLatin1String("d");
+ break;
+ case 'a':
+ result += QLatin1String("AP");
+ break;
+ case 'k':
+ result += QString(repeat, QLatin1Char('H'));
+ break;
+ case 'K':
+ result += QString(repeat, QLatin1Char('h'));
+ break;
+ case 'z':
+ case 'Z':
+ case 'v':
+ result += QLatin1Char('t');
+ break;
+ default:
+ result += QString(repeat, c);
+ break;
+ }
+
+ i += repeat;
+ }
+
+ return result;
+}
+
+QString getMacDateFormat(CFDateFormatterStyle style)
+{
+ QCFType<CFLocaleRef> l = CFLocaleCopyCurrent();
+ QCFType<CFDateFormatterRef> formatter = CFDateFormatterCreate(kCFAllocatorDefault,
+ l, style, kCFDateFormatterNoStyle);
+ return macToQtFormat(QCFString::toQString(CFDateFormatterGetFormat(formatter)));
+}
+
+static QString getMacTimeFormat(CFDateFormatterStyle style)
+{
+ QCFType<CFLocaleRef> l = CFLocaleCopyCurrent();
+ QCFType<CFDateFormatterRef> formatter = CFDateFormatterCreate(kCFAllocatorDefault,
+ l, kCFDateFormatterNoStyle, style);
+ return macToQtFormat(QCFString::toQString(CFDateFormatterGetFormat(formatter)));
+}
+
+static QString getCFLocaleValue(CFStringRef key)
+{
+ QCFType<CFLocaleRef> locale = CFLocaleCopyCurrent();
+ CFTypeRef value = CFLocaleGetValue(locale, key);
+ return QCFString::toQString(CFStringRef(static_cast<CFTypeRef>(value)));
+}
+
+static QLocale::MeasurementSystem macMeasurementSystem()
+{
+ QCFType<CFLocaleRef> locale = CFLocaleCopyCurrent();
+ CFStringRef system = static_cast<CFStringRef>(CFLocaleGetValue(locale, kCFLocaleMeasurementSystem));
+ if (QCFString::toQString(system) == QLatin1String("Metric")) {
+ return QLocale::MetricSystem;
+ } else {
+ return QLocale::ImperialSystem;
+ }
+}
+
+QLocale QSystemLocale::fallbackLocale() const
+{
+ return QLocale(QString::fromUtf8(getMacLocaleName().constData()));
+}
+
+QVariant QSystemLocale::query(QueryType type, QVariant in = QVariant()) const
+{
+ switch(type) {
+// case Name:
+// return getMacLocaleName();
+ case DecimalPoint: {
+ QString value = getCFLocaleValue(kCFLocaleDecimalSeparator);
+ return value.isEmpty() ? QVariant() : value;
+ }
+ case GroupSeparator: {
+ QString value = getCFLocaleValue(kCFLocaleGroupingSeparator);
+ return value.isEmpty() ? QVariant() : value;
+ }
+ case DateFormatLong:
+ case DateFormatShort:
+ return macToQtFormat(getMacDateFormat(type == DateFormatShort
+ ? kCFDateFormatterShortStyle
+ : kCFDateFormatterLongStyle));
+ case TimeFormatLong:
+ case TimeFormatShort:
+ return macToQtFormat(getMacTimeFormat(type == TimeFormatShort
+ ? kCFDateFormatterShortStyle
+ : kCFDateFormatterLongStyle));
+ case DayNameLong:
+ case DayNameShort:
+ return macDayName(in.toInt(), (type == DayNameShort));
+ case MonthNameLong:
+ case MonthNameShort:
+ return macMonthName(in.toInt(), (type == MonthNameShort));
+ case DateToStringShort:
+ case DateToStringLong:
+ return macDateToString(in.toDate(), (type == DateToStringShort));
+ case TimeToStringShort:
+ case TimeToStringLong:
+ return macTimeToString(in.toTime(), (type == TimeToStringShort));
+
+ case NegativeSign:
+ case PositiveSign:
+ case ZeroDigit:
+ case LanguageId:
+ case CountryId:
+ break;
+
+ case MeasurementSystem:
+ return QVariant(static_cast<int>(macMeasurementSystem()));
+
+ case AMText:
+ case PMText:
+ break;
+ default:
+ break;
+ }
+ return QVariant();
+}
+
+#elif defined(Q_OS_UNIX)
+
+static uint unixGetSystemMeasurementSystem()
+{
+ QString meas_locale = QString::fromLocal8Bit(qgetenv("LC_ALL"));
+ if (meas_locale.isEmpty()) {
+ meas_locale = QString::fromLocal8Bit(qgetenv("LC_MEASUREMENT"));
+ }
+ if (meas_locale.isEmpty()) {
+ meas_locale = QString::fromLocal8Bit(qgetenv("LANG"));
+ }
+ if (meas_locale.isEmpty()) {
+ meas_locale = QString::fromLocal8Bit("C");
+ }
+
+ if (meas_locale.compare(QString::fromLocal8Bit("Metric"), Qt::CaseInsensitive) == 0)
+ return 0;
+ if (meas_locale.compare(QString::fromLocal8Bit("Other"), Qt::CaseInsensitive) == 0)
+ return 0;
+
+ const QLocalePrivate* locale = findLocale(meas_locale);
+ return locale->measurementSystem();
+}
+
+/*!
+ \internal
+*/
+QLocale QSystemLocale::fallbackLocale() const
+{
+ return QLocale(QLatin1String(envVarLocale()));
+}
+
+/*!
+ \internal
+*/
+QVariant QSystemLocale::query(QueryType type, QVariant /* in */) const
+{
+ if (type == MeasurementSystem) {
+ return QVariant(unixGetSystemMeasurementSystem());
+ } else {
+ return QVariant();
+ }
+}
+
+#else
+
+/*!
+ Returns a fallback locale, that will get used for everything that
+ is not explicitly overridden by the system locale.
+*/
+QLocale QSystemLocale::fallbackLocale() const
+{
+ return QLocale(QLatin1String(envVarLocale()));
+}
+
+/*!
+ Performs a query of the given \a type in the system locale for
+ customized values or conversion. If the method returns a null
+ QVariant, the conversion of the fallbackLocale() will be used.
+
+ \a in is unused for some of the query types.
+
+ \sa QSystemLocale::QueryType
+*/
+QVariant QSystemLocale::query(QueryType /* type */, QVariant /* in */) const
+{
+ return QVariant();
+}
+
+#endif
+
+#ifndef QT_NO_SYSTEMLOCALE
+static QSystemLocale *_systemLocale = 0;
+Q_GLOBAL_STATIC_WITH_ARGS(QSystemLocale, QSystemLocale_globalSystemLocale, (true))
+static QLocalePrivate *system_lp = 0;
+Q_GLOBAL_STATIC(QLocalePrivate, globalLocalePrivate)
+#endif
+
+/******************************************************************************
+** Default system locale behavior
+*/
+
+/*!
+ \class QSystemLocale
+ \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 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.
+*/
+
+/*!
+ Constructs a QSystemLocale object. The constructor will automatically
+ install this object as the system locale and remove any earlier installed
+ system locales.
+*/
+QSystemLocale::QSystemLocale()
+{
+ delete _systemLocale;
+ _systemLocale = this;
+
+ if (system_lp)
+ system_lp->m_language_id = 0;
+}
+
+/*! \internal */
+QSystemLocale::QSystemLocale(bool)
+{ }
+
+/*!
+ Deletes the object.
+*/
+QSystemLocale::~QSystemLocale()
+{
+ if (_systemLocale == this) {
+ _systemLocale = 0;
+
+ if (system_lp)
+ system_lp->m_language_id = 0;
+ }
+}
+
+static const QSystemLocale *systemLocale()
+{
+ if (_systemLocale)
+ return _systemLocale;
+ return QSystemLocale_globalSystemLocale();
+}
+
+void QLocalePrivate::updateSystemPrivate()
+{
+ const QSystemLocale *sys_locale = systemLocale();
+ if (!system_lp)
+ system_lp = globalLocalePrivate();
+ *system_lp = *sys_locale->fallbackLocale().d();
+
+ QVariant res = sys_locale->query(QSystemLocale::LanguageId, QVariant());
+ if (!res.isNull())
+ system_lp->m_language_id = res.toInt();
+ res = sys_locale->query(QSystemLocale::CountryId, QVariant());
+ if (!res.isNull())
+ system_lp->m_country_id = res.toInt();
+
+ res = sys_locale->query(QSystemLocale::DecimalPoint, QVariant());
+ if (!res.isNull())
+ system_lp->m_decimal = res.toString().at(0).unicode();
+
+ res = sys_locale->query(QSystemLocale::GroupSeparator, QVariant());
+ if (!res.isNull())
+ system_lp->m_group = res.toString().at(0).unicode();
+
+ res = sys_locale->query(QSystemLocale::ZeroDigit, QVariant());
+ if (!res.isNull())
+ system_lp->m_zero = res.toString().at(0).unicode();
+
+ res = sys_locale->query(QSystemLocale::NegativeSign, QVariant());
+ if (!res.isNull())
+ system_lp->m_minus = res.toString().at(0).unicode();
+
+ res = sys_locale->query(QSystemLocale::PositiveSign, QVariant());
+ if (!res.isNull())
+ system_lp->m_plus = res.toString().at(0).unicode();
+}
+#endif
+
+static const QLocalePrivate *systemPrivate()
+{
+#ifndef QT_NO_SYSTEMLOCALE
+ // copy over the information from the fallback locale and modify
+ if (!system_lp || system_lp->m_language_id == 0)
+ QLocalePrivate::updateSystemPrivate();
+
+ return system_lp;
+#else
+ return locale_data;
+#endif
+}
+
+static const QLocalePrivate *defaultPrivate()
+{
+ if (!default_lp)
+ default_lp = systemPrivate();
+ return default_lp;
+}
+
+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 QString::fromRawData(reinterpret_cast<const QChar*>(data), end-data);
+}
+
+static inline QString getLocaleData(const ushort *data, int size)
+{
+ return QString::fromRawData(reinterpret_cast<const QChar*>(data), size);
+}
+
+
+#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
+
+
+/*!
+ \class QLocale
+ \brief The QLocale class converts between numbers and their
+ string representations in various languages.
+
+ \reentrant
+ \ingroup i18n
+ \ingroup text
+ \ingroup shared
+ \mainclass
+
+ 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 doc/src/snippets/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
+ \i If a QLocale object is constructed with the default constructor,
+ it will use the default locale's settings.
+ \i QString::toInt(), QString::toDouble(), etc., interpret the
+ string according to the default locale. If this fails, it
+ falls back on the "C" locale.
+ \i 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 doc/src/snippets/code/src_corelib_tools_qlocale.cpp 1
+
+ When a language/country pair is specified in the constructor, one
+ of three things can happen:
+
+ \list
+ \i If the language/country pair is found in the database, it is used.
+ \i 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),
+ \i If neither the language nor the country are found, QLocale
+ defaults to the default locale (see setDefault()).
+ \endlist
+
+ The "C" locale is identical to \l{English}/\l{UnitedStates}.
+
+ 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 doc/src/snippets/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.
+
+ The double-to-string and string-to-double conversion functions are
+ covered by the following licenses:
+
+ \legalese
+ Copyright (c) 1991 by AT&T.
+
+ Permission to use, copy, modify, and distribute this software for any
+ purpose without fee is hereby granted, provided that this entire notice
+ is included in all copies of any software which is or includes a copy
+ or modification of this software and in all copies of the supporting
+ documentation for such software.
+
+ THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
+ WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR AT&T MAKES ANY
+ REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
+ OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
+
+ This product includes software developed by the University of
+ California, Berkeley and its contributors.
+
+ QLocale's data is based on Common Locale Data Repository v1.6.1.
+
+ \sa QString::arg(), QString::toInt(), QString::toDouble()
+*/
+
+/*!
+ \enum QLocale::Language
+
+ This enumerated type is used to specify a language.
+
+ \value C The "C" locale is English/UnitedStates.
+ \value Abkhazian
+ \value Afan
+ \value Afar
+ \value Afrikaans
+ \value Albanian
+ \value Amharic
+ \value Arabic
+ \value Armenian
+ \value Assamese
+ \value Aymara
+ \value Azerbaijani
+ \value Bashkir
+ \value Basque
+ \value Bengali
+ \value Bhutani
+ \value Bihari
+ \value Bislama
+ \value Bosnian
+ \value Breton
+ \value Bulgarian
+ \value Burmese
+ \value Byelorussian
+ \value Cambodian
+ \value Catalan
+ \value Chinese
+ \value Cornish
+ \value Corsican
+ \value Croatian
+ \value Czech
+ \value Danish
+ \value Divehi
+ \value Dutch
+ \value English
+ \value Esperanto
+ \value Estonian
+ \value Faroese
+ \value FijiLanguage
+ \value Finnish
+ \value French
+ \value Frisian
+ \value Gaelic
+ \value Galician
+ \value Georgian
+ \value German
+ \value Greek
+ \value Greenlandic
+ \value Guarani
+ \value Gujarati
+ \value Hausa
+ \value Hebrew
+ \value Hindi
+ \value Hungarian
+ \value Icelandic
+ \value Indonesian
+ \value Interlingua
+ \value Interlingue
+ \value Inuktitut
+ \value Inupiak
+ \value Irish
+ \value Italian
+ \value Japanese
+ \value Javanese
+ \value Kannada
+ \value Kashmiri
+ \value Kazakh
+ \value Kinyarwanda
+ \value Kirghiz
+ \value Korean
+ \value Kurdish
+ \value Kurundi
+ \value Laothian
+ \value Latin
+ \value Latvian
+ \value Lingala
+ \value Lithuanian
+ \value Macedonian
+ \value Malagasy
+ \value Malay
+ \value Malayalam
+ \value Maltese
+ \value Manx
+ \value Maori
+ \value Marathi
+ \value Moldavian
+ \value Mongolian
+ \value NauruLanguage
+ \value Nepali
+ \value Norwegian
+ \value NorwegianBokmal
+ \value Nynorsk Obsolete, please use NorwegianNynorsk
+ \value NorwegianNynorsk
+ \value Occitan
+ \value Oriya
+ \value Pashto
+ \value Persian
+ \value Polish
+ \value Portuguese
+ \value Punjabi
+ \value Quechua
+ \value RhaetoRomance
+ \value Romanian
+ \value Russian
+ \value Samoan
+ \value Sangho
+ \value Sanskrit
+ \value Serbian
+ \value SerboCroatian
+ \value Sesotho
+ \value Setswana
+ \value Shona
+ \value Sindhi
+ \value Singhalese
+ \value Siswati
+ \value Slovak
+ \value Slovenian
+ \value Somali
+ \value Spanish
+ \value Sundanese
+ \value Swahili
+ \value Swedish
+ \value Tagalog
+ \value Tajik
+ \value Tamil
+ \value Tatar
+ \value Telugu
+ \value Thai
+ \value Tibetan
+ \value Tigrinya
+ \value TongaLanguage
+ \value Tsonga
+ \value Turkish
+ \value Turkmen
+ \value Twi
+ \value Uigur
+ \value Ukrainian
+ \value Urdu
+ \value Uzbek
+ \value Vietnamese
+ \value Volapuk
+ \value Welsh
+ \value Wolof
+ \value Xhosa
+ \value Yiddish
+ \value Yoruba
+ \value Zhuang
+ \value Zulu
+ \value Bosnian
+ \value Divehi
+ \value Manx
+ \value Cornish
+ \value Akan
+ \value Konkani
+ \value Ga
+ \value Igbo
+ \value Kamba
+ \value Syriac
+ \value Blin
+ \value Geez
+ \value Koro
+ \value Sidamo
+ \value Atsam
+ \value Tigre
+ \value Jju
+ \value Friulian
+ \value Venda
+ \value Ewe
+ \value Walamo
+ \value Hawaiian
+ \value Tyap
+ \value Chewa
+ \omitvalue LastLanguage
+
+ \sa language()
+*/
+
+/*!
+ \enum QLocale::Country
+
+ This enumerated type is used to specify a country.
+
+ \value AnyCountry
+ \value Afghanistan
+ \value Albania
+ \value Algeria
+ \value AmericanSamoa
+ \value Andorra
+ \value Angola
+ \value Anguilla
+ \value Antarctica
+ \value AntiguaAndBarbuda
+ \value Argentina
+ \value Armenia
+ \value Aruba
+ \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 BosniaAndHerzegowina
+ \value Botswana
+ \value BouvetIsland
+ \value Brazil
+ \value BritishIndianOceanTerritory
+ \value BruneiDarussalam
+ \value Bulgaria
+ \value BurkinaFaso
+ \value Burundi
+ \value Cambodia
+ \value Cameroon
+ \value Canada
+ \value CapeVerde
+ \value CaymanIslands
+ \value CentralAfricanRepublic
+ \value Chad
+ \value Chile
+ \value China
+ \value ChristmasIsland
+ \value CocosIslands
+ \value Colombia
+ \value Comoros
+ \value DemocraticRepublicOfCongo
+ \value PeoplesRepublicOfCongo
+ \value CookIslands
+ \value CostaRica
+ \value IvoryCoast
+ \value Croatia
+ \value Cuba
+ \value Cyprus
+ \value CzechRepublic
+ \value Denmark
+ \value Djibouti
+ \value Dominica
+ \value DominicanRepublic
+ \value EastTimor
+ \value Ecuador
+ \value Egypt
+ \value ElSalvador
+ \value EquatorialGuinea
+ \value Eritrea
+ \value Estonia
+ \value Ethiopia
+ \value FalklandIslands
+ \value FaroeIslands
+ \value FijiCountry
+ \value Finland
+ \value France
+ \value MetropolitanFrance
+ \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 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 Israel
+ \value Italy
+ \value Jamaica
+ \value Japan
+ \value Jordan
+ \value Kazakhstan
+ \value Kenya
+ \value Kiribati
+ \value DemocraticRepublicOfKorea
+ \value RepublicOfKorea
+ \value Kuwait
+ \value Kyrgyzstan
+ \value Lao
+ \value Latvia
+ \value Lebanon
+ \value Lesotho
+ \value Liberia
+ \value LibyanArabJamahiriya
+ \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 Montserrat
+ \value Morocco
+ \value Mozambique
+ \value Myanmar
+ \value Namibia
+ \value NauruCountry
+ \value Nepal
+ \value Netherlands
+ \value NetherlandsAntilles
+ \value NewCaledonia
+ \value NewZealand
+ \value Nicaragua
+ \value Niger
+ \value Nigeria
+ \value Niue
+ \value NorfolkIsland
+ \value NorthernMarianaIslands
+ \value Norway
+ \value Oman
+ \value Pakistan
+ \value Palau
+ \value PalestinianTerritory
+ \value Panama
+ \value PapuaNewGuinea
+ \value Paraguay
+ \value Peru
+ \value Philippines
+ \value Pitcairn
+ \value Poland
+ \value Portugal
+ \value PuertoRico
+ \value Qatar
+ \value Reunion
+ \value Romania
+ \value RussianFederation
+ \value Rwanda
+ \value SaintKittsAndNevis
+ \value StLucia
+ \value StVincentAndTheGrenadines
+ \value Samoa
+ \value SanMarino
+ \value SaoTomeAndPrincipe
+ \value SaudiArabia
+ \value Senegal
+ \value SerbiaAndMontenegro
+ \value Seychelles
+ \value SierraLeone
+ \value Singapore
+ \value Slovakia
+ \value Slovenia
+ \value SolomonIslands
+ \value Somalia
+ \value SouthAfrica
+ \value SouthGeorgiaAndTheSouthSandwichIslands
+ \value Spain
+ \value SriLanka
+ \value StHelena
+ \value StPierreAndMiquelon
+ \value Sudan
+ \value Suriname
+ \value SvalbardAndJanMayenIslands
+ \value Swaziland
+ \value Sweden
+ \value Switzerland
+ \value SyrianArabRepublic
+ \value Taiwan
+ \value Tajikistan
+ \value Tanzania
+ \value Thailand
+ \value Togo
+ \value Tokelau
+ \value TongaCountry
+ \value TrinidadAndTobago
+ \value Tunisia
+ \value Turkey
+ \value Turkmenistan
+ \value TurksAndCaicosIslands
+ \value Tuvalu
+ \value Uganda
+ \value Ukraine
+ \value UnitedArabEmirates
+ \value UnitedKingdom
+ \value UnitedStates
+ \value UnitedStatesMinorOutlyingIslands
+ \value Uruguay
+ \value Uzbekistan
+ \value Vanuatu
+ \value VaticanCityState
+ \value Venezuela
+ \value VietNam
+ \value BritishVirginIslands
+ \value USVirginIslands
+ \value WallisAndFutunaIslands
+ \value WesternSahara
+ \value Yemen
+ \value Yugoslavia
+ \value Zambia
+ \value Zimbabwe
+ \omitvalue LastCountry
+
+ \sa country()
+*/
+
+/*!
+ \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.
+*/
+
+/*!
+ \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 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.
+
+ \sa setNumberOptions() numberOptions()
+*/
+
+/*!
+ \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 ImperialSystem This value indicates imperial units, such as inches and
+ miles. There are several distinct imperial systems in the world; this
+ value stands for the official United States imperial units.
+
+ \since 4.4
+*/
+
+
+/*!
+ \fn bool QLocale::operator==(const QLocale &other) const
+
+ Returns true if the QLocale object is the same as the \a other
+ locale specified; otherwise returns false.
+*/
+
+/*!
+ \fn bool QLocale::operator!=(const QLocale &other) const
+
+ Returns true if the QLocale object is not the same as the \a other
+ locale specified; otherwise returns false.
+*/
+
+static const int locale_data_size = sizeof(locale_data)/sizeof(QLocalePrivate) - 1;
+
+static const QLocalePrivate *dataPointerHelper(quint16 index)
+{
+#ifndef QT_NO_SYSTEMLOCALE
+ Q_ASSERT(index <= locale_data_size);
+ if (index == locale_data_size)
+ return system_lp;
+#else
+ Q_ASSERT(index < locale_data_size);
+#endif
+
+ return &locale_data[index];
+}
+
+static quint16 localePrivateIndex(const QLocalePrivate *p)
+{
+#ifndef QT_NO_SYSTEMLOCALE
+ Q_ASSERT((p >= locale_data && p - locale_data < locale_data_size)
+ || (p != 0 && p == system_lp));
+ quint16 index = p == system_lp ? locale_data_size : p - locale_data;
+#else
+ Q_ASSERT(p >= locale_data && p - locale_data < locale_data_size);
+ quint16 index = p - locale_data;
+#endif
+
+ return index;
+}
+
+/*!
+ Constructs a QLocale object with the specified \a name,
+ which has the format
+ "language[_country][.codeset][@modifier]" or "C", where:
+
+ \list
+ \i language is a lowercase, two-letter, ISO 639 language code,
+ \i territory is an uppercase, two-letter, ISO 3166 country code,
+ \i and codeset and modifier are ignored.
+ \endlist
+
+ If the string violates the locale format, or language is not
+ a valid ISO 369 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 and country codes are converted to their respective
+ \c Language and \c Country enums. After this conversion is
+ performed the constructor behaves exactly like QLocale(Country,
+ Language).
+
+ This constructor is much slower than QLocale(Country, Language).
+
+ \sa name()
+*/
+
+QLocale::QLocale(const QString &name)
+ : v(0)
+{
+ p.numberOptions = 0;
+ p.index = localePrivateIndex(findLocale(name));
+}
+
+/*!
+ Constructs a QLocale object initialized with the default locale. If
+ no default locale was set using setDefaultLocale(), this locale will
+ be the same as the one returned by system().
+
+ \sa setDefault()
+*/
+
+QLocale::QLocale()
+ : v(0)
+{
+ p.numberOptions = default_number_options;
+ p.index = localePrivateIndex(defaultPrivate());
+}
+
+/*!
+ Constructs a QLocale object with the specified \a language and \a
+ country.
+
+ \list
+ \i If the language/country pair is found in the database, it is used.
+ \i 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),
+ \i 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)
+ : v(0)
+{
+ const QLocalePrivate *d = findLocale(language, country);
+
+ // If not found, should default to system
+ if (d->languageId() == QLocale::C && language != QLocale::C) {
+ p.numberOptions = default_number_options;
+ p.index = localePrivateIndex(defaultPrivate());
+ } else {
+ p.numberOptions = 0;
+ p.index = localePrivateIndex(d);
+ }
+}
+
+/*!
+ Constructs a QLocale object as a copy of \a other.
+*/
+
+QLocale::QLocale(const QLocale &other)
+{
+ v = other.v;
+}
+
+const QLocalePrivate *QLocale::d() const
+{
+ return dataPointerHelper(p.index);
+}
+
+/*!
+ Assigns \a other to this QLocale object and returns a reference
+ to this QLocale object.
+*/
+
+QLocale &QLocale::operator=(const QLocale &other)
+{
+ v = other.v;
+ return *this;
+}
+
+/*!
+ \since 4.2
+
+ Sets the \a options related to number conversions for this
+ QLocale instance.
+*/
+void QLocale::setNumberOptions(NumberOptions options)
+{
+ p.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<NumberOption>(p.numberOptions);
+}
+
+/*!
+ \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_lp = locale.d();
+ default_number_options = locale.numberOptions();
+}
+
+/*!
+ Returns the language of this locale.
+
+ \sa country(), languageToString(), name()
+*/
+QLocale::Language QLocale::language() const
+{
+ return Language(d()->languageId());
+}
+
+/*!
+ Returns the country of this locale.
+
+ \sa language(), countryToString(), name()
+*/
+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-letter ISO 3166 country code.
+
+ \sa language(), country()
+*/
+
+QString QLocale::name() const
+{
+ Language l = language();
+
+ QString result = languageToCode(l);
+
+ if (l == C)
+ return result;
+
+ Country c = country();
+ if (c == AnyCountry)
+ return result;
+
+ result.append(QLatin1Char('_'));
+ result.append(countryToCode(c));
+
+ return result;
+}
+
+/*!
+ Returns a QString containing the name of \a language.
+
+ \sa countryToString(), name()
+*/
+
+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 country(), name()
+*/
+
+QString QLocale::countryToString(Country country)
+{
+ if (uint(country) > uint(QLocale::LastCountry))
+ return QLatin1String("Unknown");
+ return QLatin1String(country_name_list + country_name_index[country]);
+}
+
+/*!
+ Returns the short int represented by the localized string \a s,
+ using base \a base. If \a base is 0 the base is determined
+ automatically using the following rules: If the string 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.
+
+ If the conversion fails the function returns 0.
+
+ If \a ok is not 0, failure is reported by setting *ok to false, and
+ success by setting *ok to true.
+
+ This function ignores leading and trailing whitespace.
+
+ \sa toUShort(), toString()
+*/
+
+short QLocale::toShort(const QString &s, bool *ok, int base) const
+{
+ qlonglong i = toLongLong(s, ok, base);
+ if (i < SHRT_MIN || i > SHRT_MAX) {
+ if (ok != 0)
+ *ok = false;
+ return 0;
+ }
+ return short(i);
+}
+
+/*!
+ Returns the unsigned short int represented by the localized string
+ \a s, using base \a base. If \a base is 0 the base is determined
+ automatically using the following rules: If the string 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.
+
+ If the conversion fails the function returns 0.
+
+ If \a ok is not 0, failure is reported by setting *ok to false, and
+ success by setting *ok to true.
+
+ This function ignores leading and trailing whitespace.
+
+ \sa toShort(), toString()
+*/
+
+ushort QLocale::toUShort(const QString &s, bool *ok, int base) const
+{
+ qulonglong i = toULongLong(s, ok, base);
+ if (i > USHRT_MAX) {
+ if (ok != 0)
+ *ok = false;
+ return 0;
+ }
+ return ushort(i);
+}
+
+/*!
+ Returns the int represented by the localized string \a s, using
+ base \a base. If \a base is 0 the base is determined automatically
+ using the following rules: If the string 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.
+
+ If the conversion fails the function returns 0.
+
+ If \a ok is not 0, failure is reported by setting *ok to false, and
+ success by setting *ok to true.
+
+ This function ignores leading and trailing whitespace.
+
+ \sa toUInt(), toString()
+*/
+
+int QLocale::toInt(const QString &s, bool *ok, int base) const
+{
+ qlonglong i = toLongLong(s, ok, base);
+ if (i < INT_MIN || i > INT_MAX) {
+ if (ok != 0)
+ *ok = false;
+ return 0;
+ }
+ return int(i);
+}
+
+/*!
+ Returns the unsigned int represented by the localized string \a s,
+ using base \a base. If \a base is 0 the base is determined
+ automatically using the following rules: If the string 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.
+
+ If the conversion fails the function returns 0.
+
+ If \a ok is not 0, failure is reported by setting *ok to false, and
+ success by setting *ok to true.
+
+ This function ignores leading and trailing whitespace.
+
+ \sa toInt(), toString()
+*/
+
+uint QLocale::toUInt(const QString &s, bool *ok, int base) const
+{
+ qulonglong i = toULongLong(s, ok, base);
+ if (i > UINT_MAX) {
+ if (ok != 0)
+ *ok = false;
+ return 0;
+ }
+ return uint(i);
+}
+
+/*!
+ Returns the long long int represented by the localized string \a
+ s, using base \a base. If \a base is 0 the base is determined
+ automatically using the following rules: If the string 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.
+
+ If the conversion fails the function returns 0.
+
+ If \a ok is not 0, failure is reported by setting *ok to false, and
+ success by setting *ok to true.
+
+ This function ignores leading and trailing whitespace.
+
+ \sa toInt(), toULongLong(), toDouble(), toString()
+*/
+
+
+qlonglong QLocale::toLongLong(const QString &s, bool *ok, int base) const
+{
+ QLocalePrivate::GroupSeparatorMode mode
+ = p.numberOptions & RejectGroupSeparator
+ ? QLocalePrivate::FailOnGroupSeparators
+ : QLocalePrivate::ParseGroupSeparators;
+
+ return d()->stringToLongLong(s, base, ok, mode);
+}
+
+// ### Qt5: make the return type for toULongLong() qulonglong.
+
+/*!
+ Returns the unsigned long long int represented by the localized
+ string \a s, using base \a base. If \a base is 0 the base is
+ determined automatically using the following rules: If the string
+ 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.
+
+ If the conversion fails the function returns 0.
+
+ If \a ok is not 0, failure is reported by setting *ok to false, and
+ success by setting *ok to true.
+
+ This function ignores leading and trailing whitespace.
+
+ \sa toLongLong(), toInt(), toDouble(), toString()
+*/
+
+qlonglong QLocale::toULongLong(const QString &s, bool *ok, int base) const
+{
+ QLocalePrivate::GroupSeparatorMode mode
+ = p.numberOptions & RejectGroupSeparator
+ ? QLocalePrivate::FailOnGroupSeparators
+ : QLocalePrivate::ParseGroupSeparators;
+
+ return d()->stringToUnsLongLong(s, base, ok, mode);
+}
+
+/*!
+ Returns the float represented by the localized string \a s, or 0.0
+ if the conversion failed.
+
+ If \a ok is not 0, reports failure by setting
+ *ok to false and success by setting *ok to true.
+
+ This function ignores leading and trailing whitespace.
+
+ \sa toDouble(), toInt(), toString()
+*/
+
+#define QT_MAX_FLOAT 3.4028234663852886e+38
+
+float QLocale::toFloat(const QString &s, bool *ok) const
+{
+ bool myOk;
+ double d = toDouble(s, &myOk);
+ if (!myOk || d > QT_MAX_FLOAT || d < -QT_MAX_FLOAT) {
+ if (ok != 0)
+ *ok = false;
+ return 0.0;
+ }
+ if (ok != 0)
+ *ok = true;
+ return float(d);
+}
+
+/*!
+ Returns the double represented by the localized string \a s, or
+ 0.0 if the conversion failed.
+
+ If \a ok is not 0, reports failure by setting
+ *ok to false and success by setting *ok to true.
+
+ Unlike QString::toDouble(), this function does not fall back to
+ the "C" locale if the string cannot be interpreted in this
+ locale.
+
+ \snippet doc/src/snippets/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
+{
+ QLocalePrivate::GroupSeparatorMode mode
+ = p.numberOptions & RejectGroupSeparator
+ ? QLocalePrivate::FailOnGroupSeparators
+ : QLocalePrivate::ParseGroupSeparators;
+
+ return d()->stringToDouble(s, ok, mode);
+}
+
+/*!
+ Returns a localized string representation of \a i.
+
+ \sa toLongLong()
+*/
+
+QString QLocale::toString(qlonglong i) const
+{
+ int flags = p.numberOptions & OmitGroupSeparator
+ ? 0
+ : QLocalePrivate::ThousandsGroup;
+
+ return d()->longLongToString(i, -1, 10, -1, flags);
+}
+
+/*!
+ \overload
+
+ \sa toULongLong()
+*/
+
+QString QLocale::toString(qulonglong i) const
+{
+ int flags = p.numberOptions & OmitGroupSeparator
+ ? 0
+ : QLocalePrivate::ThousandsGroup;
+
+ return d()->unsLongLongToString(i, -1, 10, -1, flags);
+}
+
+/*!
+ 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.
+*/
+
+QString QLocale::toString(const QDate &date, const QString &format) const
+{
+ return d()->dateTimeToString(format, &date, 0, 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() == systemPrivate()) {
+ 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(const QString &format)
+{
+ int i = 0;
+ while (i < format.size()) {
+ if (format.at(i).unicode() == '\'') {
+ readEscapedFormatString(format, &i);
+ continue;
+ }
+
+ if (format.at(i).toLower().unicode() == 'a')
+ return true;
+
+ ++i;
+ }
+ return false;
+}
+
+static QString timeZone()
+{
+#if defined(Q_OS_WINCE)
+ TIME_ZONE_INFORMATION info;
+ DWORD res = GetTimeZoneInformation(&info);
+ if (res == TIME_ZONE_ID_UNKNOWN)
+ return QString();
+ return QString::fromUtf16(reinterpret_cast<const ushort *> (info.StandardName));
+#elif defined(Q_OS_WIN)
+ _tzset();
+# if defined(_MSC_VER) && _MSC_VER >= 1400
+ size_t returnSize = 0;
+ char timeZoneName[512];
+ if (_get_tzname(&returnSize, timeZoneName, 512, 1))
+ return QString();
+ return QString::fromLocal8Bit(timeZoneName);
+# else
+ return QString::fromLocal8Bit(_tzname[1]);
+# endif
+#else
+ tzset();
+ return QString::fromLocal8Bit(tzname[1]);
+#endif
+}
+
+/*!
+ 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.
+*/
+QString QLocale::toString(const QTime &time, const QString &format) const
+{
+ return d()->dateTimeToString(format, 0, &time, this);
+}
+
+/*!
+ \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.
+*/
+
+QString QLocale::toString(const QDateTime &dateTime, const QString &format) const
+{
+ const QDate dt = dateTime.date();
+ const QTime tm = dateTime.time();
+ return d()->dateTimeToString(format, &dt, &tm, 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() == systemPrivate()) {
+ 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() == systemPrivate()) {
+ 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() == systemPrivate()) {
+ 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_long_date_format_idx;
+ size = d()->m_long_date_format_size;
+ break;
+ default:
+ idx = d()->m_short_date_format_idx;
+ size = d()->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() == systemPrivate()) {
+ 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_long_time_format_idx;
+ size = d()->m_long_time_format_size;
+ break;
+ default:
+ idx = d()->m_short_time_format_idx;
+ size = d()->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() == systemPrivate()) {
+ 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()
+*/
+#ifndef QT_NO_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()
+*/
+#ifndef QT_NO_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()
+*/
+
+#ifndef QT_NO_DATESTRING
+QDateTime QLocale::toDateTime(const QString &string, FormatType format) const
+{
+ return toDateTime(string, dateFormat(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()
+*/
+#ifndef QT_NO_DATESTRING
+QTime QLocale::toTime(const QString &string, const QString &format) const
+{
+ QTime time;
+#ifndef QT_BOOTSTRAPPED
+ QDateTimeParser dt(QVariant::Time, QDateTimeParser::FromString);
+ dt.defaultLocale = *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()
+*/
+#ifndef QT_NO_DATESTRING
+QDate QLocale::toDate(const QString &string, const QString &format) const
+{
+ QDate date;
+#ifndef QT_BOOTSTRAPPED
+ QDateTimeParser dt(QVariant::Date, QDateTimeParser::FromString);
+ dt.defaultLocale = *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()
+*/
+#ifndef QT_NO_DATESTRING
+QDateTime QLocale::toDateTime(const QString &string, const QString &format) const
+{
+#ifndef QT_BOOTSTRAPPED
+ QTime time;
+ QDate date;
+
+ QDateTimeParser dt(QVariant::DateTime, QDateTimeParser::FromString);
+ dt.defaultLocale = *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
+{
+ QLocalePrivate::DoubleForm form = QLocalePrivate::DFDecimal;
+ uint flags = 0;
+
+ if (qIsUpper(f))
+ flags = QLocalePrivate::CapitalEorX;
+ f = qToLower(f);
+
+ switch (f) {
+ case 'f':
+ form = QLocalePrivate::DFDecimal;
+ break;
+ case 'e':
+ form = QLocalePrivate::DFExponent;
+ break;
+ case 'g':
+ form = QLocalePrivate::DFSignificantDigits;
+ break;
+ default:
+ break;
+ }
+
+ if (!(p.numberOptions & OmitGroupSeparator))
+ flags |= QLocalePrivate::ThousandsGroup;
+ return d()->doubleToString(i, prec, form, -1, flags);
+}
+
+/*!
+ \fn QLocale QLocale::c()
+
+ Returns a QLocale object initialized to the "C" locale.
+
+ \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 QTextCodec::locale() c()
+*/
+
+QLocale QLocale::system()
+{
+ QLocale result(C);
+ result.p.index = localePrivateIndex(systemPrivate());
+ return result;
+}
+
+/*!
+ \since 4.3
+
+ Returns the list of countries that have entires 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.
+*/
+QList<QLocale::Country> QLocale::countriesForLanguage(Language language)
+{
+ QList<Country> result;
+
+ unsigned language_id = language;
+ uint idx = locale_index[language_id];
+
+ if (language == C) {
+ result << AnyCountry;
+ return result;
+ }
+
+ const QLocalePrivate *d = locale_data + idx;
+
+ while (d->languageId() == language_id) {
+ result << static_cast<Country>(d->countryId());
+ ++d;
+ }
+
+ 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() == systemPrivate()) {
+ 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_long_month_names_idx;
+ size = d()->m_long_month_names_size;
+ break;
+ case QLocale::ShortFormat:
+ idx = d()->m_short_month_names_idx;
+ size = d()->m_short_month_names_size;
+ break;
+ case QLocale::NarrowFormat:
+ idx = d()->m_narrow_month_names_idx;
+ size = d()->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() == systemPrivate()) {
+ 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_standalone_long_month_names_idx;
+ size = d()->m_standalone_long_month_names_size;
+ break;
+ case QLocale::ShortFormat:
+ idx = d()->m_standalone_short_month_names_idx;
+ size = d()->m_standalone_short_month_names_size;
+ break;
+ case QLocale::NarrowFormat:
+ idx = d()->m_standalone_narrow_month_names_idx;
+ size = d()->m_standalone_narrow_month_names_size;
+ break;
+ default:
+ return QString();
+ }
+ QString name = getLocaleListData(standalone_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() == systemPrivate()) {
+ 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_long_day_names_idx;
+ size = d()->m_long_day_names_size;
+ break;
+ case QLocale::ShortFormat:
+ idx = d()->m_short_day_names_idx;
+ size = d()->m_short_day_names_size;
+ break;
+ case QLocale::NarrowFormat:
+ idx = d()->m_narrow_day_names_idx;
+ size = d()->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() == systemPrivate()) {
+ 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_standalone_long_day_names_idx;
+ size = d()->m_standalone_long_day_names_size;
+ break;
+ case QLocale::ShortFormat:
+ idx = d()->m_standalone_short_day_names_idx;
+ size = d()->m_standalone_short_day_names_size;
+ break;
+ case QLocale::NarrowFormat:
+ idx = d()->m_standalone_narrow_day_names_idx;
+ size = d()->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.4
+
+ Returns the measurement system for the locale.
+*/
+QLocale::MeasurementSystem QLocale::measurementSystem() const
+{
+ MeasurementSystem meas = MetricSystem;
+ bool found = false;
+
+#ifndef QT_NO_SYSTEMLOCALE
+ if (d() == systemPrivate()) {
+ QVariant res = systemLocale()->query(QSystemLocale::MeasurementSystem, QVariant());
+ if (!res.isNull()) {
+ meas = MeasurementSystem(res.toInt());
+ found = true;
+ }
+ }
+#endif
+
+ if (!found) {
+ meas = d()->measurementSystem();
+ found = true;
+ }
+
+ return meas;
+}
+
+/*!
+ \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() == systemPrivate()) {
+ QVariant res = systemLocale()->query(QSystemLocale::AMText, QVariant());
+ if (!res.isNull())
+ return res.toString();
+ }
+#endif
+ return getLocaleData(am_data + d()->m_am_idx, d()->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() == systemPrivate()) {
+ QVariant res = systemLocale()->query(QSystemLocale::PMText, QVariant());
+ if (!res.isNull())
+ return res.toString();
+ }
+#endif
+ return getLocaleData(pm_data + d()->m_pm_idx, d()->m_pm_size);
+}
+
+
+/*!
+\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()
+*/
+
+
+static QString qulltoa(qulonglong l, int base, const QLocalePrivate &locale)
+{
+ ushort buff[65]; // length of MAX_ULLONG in base 2
+ ushort *p = buff + 65;
+ const QChar _zero = locale.zero();
+
+ if (base != 10 || _zero.unicode() == '0') {
+ while (l != 0) {
+ int c = l % base;
+
+ --p;
+
+ if (c < 10)
+ *p = '0' + c;
+ else
+ *p = c - 10 + 'a';
+
+ l /= base;
+ }
+ }
+ else {
+ while (l != 0) {
+ int c = l % base;
+
+ *(--p) = _zero.unicode() + c;
+
+ l /= base;
+ }
+ }
+
+ return QString(reinterpret_cast<QChar *>(p), 65 - (p - buff));
+}
+
+static QString qlltoa(qlonglong l, int base, const QLocalePrivate &locale)
+{
+ return qulltoa(l < 0 ? -l : l, base, locale);
+}
+
+enum PrecisionMode {
+ PMDecimalDigits = 0x01,
+ PMSignificantDigits = 0x02,
+ PMChopTrailingZeros = 0x03
+};
+
+static QString &decimalForm(QString &digits, int decpt, uint precision,
+ PrecisionMode pm,
+ bool always_show_decpt,
+ bool thousands_group,
+ const QLocalePrivate &locale)
+{
+ if (decpt < 0) {
+ for (int i = 0; i < -decpt; ++i)
+ digits.prepend(locale.zero());
+ decpt = 0;
+ }
+ else if (decpt > digits.length()) {
+ for (int i = digits.length(); i < decpt; ++i)
+ digits.append(locale.zero());
+ }
+
+ if (pm == PMDecimalDigits) {
+ uint decimal_digits = digits.length() - decpt;
+ for (uint i = decimal_digits; i < precision; ++i)
+ digits.append(locale.zero());
+ }
+ else if (pm == PMSignificantDigits) {
+ for (uint i = digits.length(); i < precision; ++i)
+ digits.append(locale.zero());
+ }
+ else { // pm == PMChopTrailingZeros
+ }
+
+ if (always_show_decpt || decpt < digits.length())
+ digits.insert(decpt, locale.decimal());
+
+ if (thousands_group) {
+ for (int i = decpt - 3; i > 0; i -= 3)
+ digits.insert(i, locale.group());
+ }
+
+ if (decpt == 0)
+ digits.prepend(locale.zero());
+
+ return digits;
+}
+
+static QString &exponentForm(QString &digits, int decpt, uint precision,
+ PrecisionMode pm,
+ bool always_show_decpt,
+ const QLocalePrivate &locale)
+{
+ int exp = decpt - 1;
+
+ if (pm == PMDecimalDigits) {
+ for (uint i = digits.length(); i < precision + 1; ++i)
+ digits.append(locale.zero());
+ }
+ else if (pm == PMSignificantDigits) {
+ for (uint i = digits.length(); i < precision; ++i)
+ digits.append(locale.zero());
+ }
+ else { // pm == PMChopTrailingZeros
+ }
+
+ if (always_show_decpt || digits.length() > 1)
+ digits.insert(1, locale.decimal());
+
+ digits.append(locale.exponential());
+ digits.append(locale.longLongToString(exp, 2, 10,
+ -1, QLocalePrivate::AlwaysShowSign));
+
+ return digits;
+}
+
+static bool isZero(double d)
+{
+ uchar *ch = (uchar *)&d;
+#ifdef QT_ARMFPA
+ return !(ch[3] & 0x7F || ch[2] || ch[1] || ch[0] || ch[7] || ch[6] || ch[5] || ch[4]);
+#else
+ if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
+ return !(ch[0] & 0x7F || ch[1] || ch[2] || ch[3] || ch[4] || ch[5] || ch[6] || ch[7]);
+ } else {
+ return !(ch[7] & 0x7F || ch[6] || ch[5] || ch[4] || ch[3] || ch[2] || ch[1] || ch[0]);
+ }
+#endif
+}
+
+QString QLocalePrivate::dateTimeToString(const QString &format, const QDate *date, const QTime *time,
+ const QLocale *q) const
+{
+ Q_ASSERT(date || time);
+ if ((date && !date->isValid()) || (time && !time->isValid()))
+ return QString();
+ const bool format_am_pm = time && timeFormatContainsAP(format);
+
+ enum { AM, PM } am_pm = AM;
+ int hour12 = time ? time->hour() : -1;
+ if (time) {
+ if (hour12 == 0) {
+ am_pm = AM;
+ hour12 = 12;
+ } else if (hour12 < 12) {
+ am_pm = AM;
+ } else if (hour12 == 12) {
+ am_pm = PM;
+ } else {
+ am_pm = PM;
+ hour12 -= 12;
+ }
+ }
+
+ QString result;
+
+ int i = 0;
+ while (i < format.size()) {
+ if (format.at(i).unicode() == '\'') {
+ result.append(readEscapedFormatString(format, &i));
+ continue;
+ }
+
+ const QChar c = format.at(i);
+ int repeat = repeatCount(format, i);
+ bool used = false;
+ if (date) {
+ switch (c.unicode()) {
+ case 'y':
+ used = true;
+ if (repeat >= 4)
+ repeat = 4;
+ else if (repeat >= 2)
+ repeat = 2;
+
+ switch (repeat) {
+ case 4:
+ result.append(longLongToString(date->year()));
+ break;
+ case 2:
+ result.append(longLongToString(date->year() % 100, -1, 10, 2,
+ QLocalePrivate::ZeroPadded));
+ break;
+ default:
+ repeat = 1;
+ result.append(c);
+ break;
+ }
+ break;
+
+ case 'M':
+ used = true;
+ repeat = qMin(repeat, 4);
+ switch (repeat) {
+ case 1:
+ result.append(longLongToString(date->month()));
+ break;
+ case 2:
+ result.append(longLongToString(date->month(), -1, 10, 2, QLocalePrivate::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(longLongToString(date->day()));
+ break;
+ case 2:
+ result.append(longLongToString(date->day(), -1, 10, 2, QLocalePrivate::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 && time) {
+ switch (c.unicode()) {
+ case 'h': {
+ used = true;
+ repeat = qMin(repeat, 2);
+ const int hour = format_am_pm ? hour12 : time->hour();
+
+ switch (repeat) {
+ case 1:
+ result.append(longLongToString(hour));
+ break;
+ case 2:
+ result.append(longLongToString(hour, -1, 10, 2, QLocalePrivate::ZeroPadded));
+ break;
+ }
+ break;
+ }
+ case 'H':
+ used = true;
+ repeat = qMin(repeat, 2);
+ switch (repeat) {
+ case 1:
+ result.append(longLongToString(time->hour()));
+ break;
+ case 2:
+ result.append(longLongToString(time->hour(), -1, 10, 2, QLocalePrivate::ZeroPadded));
+ break;
+ }
+ break;
+
+ case 'm':
+ used = true;
+ repeat = qMin(repeat, 2);
+ switch (repeat) {
+ case 1:
+ result.append(longLongToString(time->minute()));
+ break;
+ case 2:
+ result.append(longLongToString(time->minute(), -1, 10, 2, QLocalePrivate::ZeroPadded));
+ break;
+ }
+ break;
+
+ case 's':
+ used = true;
+ repeat = qMin(repeat, 2);
+ switch (repeat) {
+ case 1:
+ result.append(longLongToString(time->second()));
+ break;
+ case 2:
+ result.append(longLongToString(time->second(), -1, 10, 2, QLocalePrivate::ZeroPadded));
+ break;
+ }
+ break;
+
+ case 'a':
+ used = true;
+ if (i + 1 < format.length() && format.at(i + 1).unicode() == 'p') {
+ repeat = 2;
+ } else {
+ repeat = 1;
+ }
+ result.append(am_pm == AM ? QLatin1String("am") : QLatin1String("pm"));
+ break;
+
+ case 'A':
+ used = true;
+ if (i + 1 < format.length() && format.at(i + 1).unicode() == 'P') {
+ repeat = 2;
+ } else {
+ repeat = 1;
+ }
+ result.append(am_pm == AM ? QLatin1String("AM") : QLatin1String("PM"));
+ break;
+
+ case 'z':
+ used = true;
+ if (repeat >= 3) {
+ repeat = 3;
+ } else {
+ repeat = 1;
+ }
+ switch (repeat) {
+ case 1:
+ result.append(longLongToString(time->msec()));
+ break;
+ case 3:
+ result.append(longLongToString(time->msec(), -1, 10, 3, QLocalePrivate::ZeroPadded));
+ break;
+ }
+ break;
+
+ case 't':
+ used = true;
+ repeat = 1;
+ result.append(timeZone());
+ break;
+ default:
+ break;
+ }
+ }
+ if (!used) {
+ result.append(QString(repeat, c));
+ }
+ i += repeat;
+ }
+
+ return result;
+}
+
+QString QLocalePrivate::doubleToString(double d,
+ int precision,
+ DoubleForm form,
+ int width,
+ unsigned flags) const
+{
+ if (precision == -1)
+ precision = 6;
+ if (width == -1)
+ width = 0;
+
+ bool negative = false;
+ bool special_number = false; // nan, +/-inf
+ QString num_str;
+
+ // Detect special numbers (nan, +/-inf)
+ if (qt_is_inf(d)) {
+ num_str = QString::fromLatin1("inf");
+ special_number = true;
+ negative = d < 0;
+ } else if (qt_is_nan(d)) {
+ num_str = QString::fromLatin1("nan");
+ special_number = true;
+ }
+
+ // Handle normal numbers
+ if (!special_number) {
+ int decpt, sign;
+ QString digits;
+
+#ifdef QT_QLOCALE_USES_FCVT
+ // NOT thread safe!
+ if (form == DFDecimal) {
+ digits = QLatin1String(fcvt(d, precision, &decpt, &sign));
+ } else {
+ int pr = precision;
+ if (form == DFExponent)
+ ++pr;
+ else if (form == DFSignificantDigits && pr == 0)
+ pr = 1;
+ digits = QLatin1String(ecvt(d, pr, &decpt, &sign));
+
+ // Chop trailing zeros
+ if (digits.length() > 0) {
+ int last_nonzero_idx = digits.length() - 1;
+ while (last_nonzero_idx > 0
+ && digits.unicode()[last_nonzero_idx] == QLatin1Char('0'))
+ --last_nonzero_idx;
+ digits.truncate(last_nonzero_idx + 1);
+ }
+
+ }
+
+#else
+ int mode;
+ if (form == DFDecimal)
+ mode = 3;
+ else
+ mode = 2;
+
+ /* This next bit is a bit quirky. In DFExponent form, the precision
+ is the number of digits after decpt. So that would suggest using
+ mode=3 for qdtoa. But qdtoa behaves strangely when mode=3 and
+ precision=0. So we get around this by using mode=2 and reasoning
+ that we want precision+1 significant digits, since the decimal
+ point in this mode is always after the first digit. */
+ int pr = precision;
+ if (form == DFExponent)
+ ++pr;
+
+ char *rve = 0;
+ char *buff = 0;
+ digits = QLatin1String(qdtoa(d, mode, pr, &decpt, &sign, &rve, &buff));
+ if (buff != 0)
+ free(buff);
+#endif // QT_QLOCALE_USES_FCVT
+
+ const QChar _zero = zero();
+
+ 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 & Alternate || flags & ForcePoint);
+ switch (form) {
+ case DFExponent: {
+ num_str = exponentForm(digits, decpt, precision, PMDecimalDigits,
+ always_show_decpt, *this);
+ break;
+ }
+ case DFDecimal: {
+ num_str = decimalForm(digits, decpt, precision, PMDecimalDigits,
+ always_show_decpt, flags & ThousandsGroup,
+ *this);
+ break;
+ }
+ case DFSignificantDigits: {
+ PrecisionMode mode = (flags & Alternate) ?
+ PMSignificantDigits : PMChopTrailingZeros;
+
+ if (decpt != digits.length() && (decpt <= -4 || decpt > precision))
+ num_str = exponentForm(digits, decpt, precision, mode,
+ always_show_decpt, *this);
+ else
+ num_str = decimalForm(digits, decpt, precision, mode,
+ always_show_decpt, flags & ThousandsGroup,
+ *this);
+ break;
+ }
+ }
+
+ negative = sign != 0 && !isZero(d);
+ }
+
+ // pad with zeros. LeftAdjusted overrides this flag). Also, we don't
+ // pad special numbers
+ if (flags & QLocalePrivate::ZeroPadded
+ && !(flags & QLocalePrivate::LeftAdjusted)
+ && !special_number) {
+ int num_pad_chars = width - num_str.length();
+ // leave space for the sign
+ if (negative
+ || flags & QLocalePrivate::AlwaysShowSign
+ || flags & QLocalePrivate::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 & QLocalePrivate::AlwaysShowSign)
+ num_str.prepend(plus());
+ else if (flags & QLocalePrivate::BlankBeforePositive)
+ num_str.prepend(QLatin1Char(' '));
+
+ if (flags & QLocalePrivate::CapitalEorX)
+ num_str = num_str.toUpper();
+
+ return num_str;
+}
+
+QString QLocalePrivate::longLongToString(qlonglong l, int precision,
+ int base, int width,
+ unsigned flags) const
+{
+ 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
+ }
+
+ QString num_str;
+ if (base == 10)
+ num_str = qlltoa(l, base, *this);
+ else
+ num_str = qulltoa(l, base, *this);
+
+ 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 & Alternate || 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 & Alternate || flags & ShowBase))
+ num_pad_chars -= 2;
+ // leave space for optional '0b' in binary form
+ else if (base == 2 && (flags & Alternate || 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 = num_str.toUpper();
+
+ if (base == 16 && (flags & Alternate || flags & ShowBase))
+ num_str.prepend(QLatin1String(flags & UppercaseBase ? "0X" : "0x"));
+ if (base == 2 && (flags & Alternate || 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 QLocalePrivate::unsLongLongToString(qulonglong l, int precision,
+ int base, int width,
+ unsigned flags) const
+{
+ bool precision_not_specified = false;
+ if (precision == -1) {
+ precision_not_specified = true;
+ precision = 1;
+ }
+
+ QString num_str = qulltoa(l, base, *this);
+
+ 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 & Alternate || 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 optional '0x' in hex form
+ if (base == 16 && flags & Alternate)
+ num_pad_chars -= 2;
+ // leave space for optional '0b' in binary form
+ else if (base == 2 && flags & Alternate)
+ 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 = num_str.toUpper();
+
+ if (base == 16 && (flags & Alternate || flags & ShowBase))
+ num_str.prepend(QLatin1String(flags & UppercaseBase ? "0X" : "0x"));
+ else if (base == 2 && (flags & Alternate || 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;
+}
+
+// Removes thousand-group separators in "C" locale.
+static bool removeGroupSeparators(QLocalePrivate::CharBuff *num)
+{
+ int group_cnt = 0; // counts number of group chars
+ int decpt_idx = -1;
+
+ char *data = num->data();
+ int l = qstrlen(data);
+
+ // Find the decimal point and check if there are any group chars
+ int i = 0;
+ for (; i < l; ++i) {
+ char c = data[i];
+
+ if (c == ',') {
+ if (i == 0 || data[i - 1] < '0' || data[i - 1] > '9')
+ return false;
+ if (i == l - 1 || data[i + 1] < '0' || data[i + 1] > '9')
+ return false;
+ ++group_cnt;
+ }
+ else if (c == '.') {
+ // Fail if more than one decimal points
+ if (decpt_idx != -1)
+ return false;
+ decpt_idx = i;
+ } else if (c == 'e' || c == 'E') {
+ // an 'e' or 'E' - if we have not encountered a decimal
+ // point, this is where it "is".
+ if (decpt_idx == -1)
+ decpt_idx = i;
+ }
+ }
+
+ // If no group chars, we're done
+ if (group_cnt == 0)
+ return true;
+
+ // No decimal point means that it "is" at the end of the string
+ if (decpt_idx == -1)
+ decpt_idx = l;
+
+ i = 0;
+ while (i < l && group_cnt > 0) {
+ char c = data[i];
+
+ if (c == ',') {
+ // Don't allow group chars after the decimal point
+ if (i > decpt_idx)
+ return false;
+
+ // Check that it is placed correctly relative to the decpt
+ if ((decpt_idx - i) % 4 != 0)
+ return false;
+
+ // Remove it
+ memmove(data + i, data + i + 1, l - i - 1);
+ data[--l] = '\0';
+
+ --group_cnt;
+ --decpt_idx;
+ } else {
+ // Check that we are not missing a separator
+ if (i < decpt_idx
+ && (decpt_idx - i) % 4 == 0
+ && !(i == 0 && c == '-')) // check for negative sign at start of string
+ return false;
+ ++i;
+ }
+ }
+
+ return true;
+}
+
+/*
+ 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 QLocalePrivate::numberToCLocale(const QString &num,
+ GroupSeparatorMode group_sep_mode,
+ CharBuff *result) const
+{
+ const QChar *uc = num.unicode();
+ int l = num.length();
+ int idx = 0;
+
+ // Skip whitespace
+ while (idx < l && uc[idx].isSpace())
+ ++idx;
+ if (idx == l)
+ return false;
+
+ const QChar _group = group();
+
+ while (idx < l) {
+ const QChar &in = uc[idx];
+
+ char out = digitToCLocale(in);
+ if (out == 0) {
+ if (in == list())
+ out = ';';
+ else if (in == 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;
+ }
+
+ result->append(out);
+
+ ++idx;
+ }
+
+ // Check trailing whitespace
+ for (; idx < l; ++idx) {
+ if (!uc[idx].isSpace())
+ return false;
+ }
+
+ result->append('\0');
+
+ // Check separators
+ if (group_sep_mode == ParseGroupSeparators
+ && !removeGroupSeparators(result))
+ return false;
+
+
+ return true;
+}
+
+bool QLocalePrivate::validateChars(const QString &str, NumberMode numMode, QByteArray *buff,
+ int decDigits) const
+{
+ buff->clear();
+ buff->reserve(str.length());
+
+ const bool scientific = numMode == DoubleScientificMode;
+ bool lastWasE = false;
+ int eCnt = 0;
+ int decPointCnt = 0;
+ bool dec = false;
+ int decDigitCnt = 0;
+
+ for (int i = 0; i < str.length(); ++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;
+ }
+ } 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 ',':
+ return false;
+
+ 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;
+ }
+ }
+
+ lastWasE = c == 'e';
+ buff->append(c);
+ }
+
+ return true;
+}
+
+double QLocalePrivate::stringToDouble(const QString &number, bool *ok,
+ GroupSeparatorMode group_sep_mode) const
+{
+ CharBuff buff;
+ if (!numberToCLocale(number, group_sep_mode, &buff)) {
+ if (ok != 0)
+ *ok = false;
+ return 0.0;
+ }
+ return bytearrayToDouble(buff.constData(), ok);
+}
+
+qlonglong QLocalePrivate::stringToLongLong(const QString &number, int base,
+ bool *ok, GroupSeparatorMode group_sep_mode) const
+{
+ CharBuff buff;
+ if (!numberToCLocale(number, group_sep_mode, &buff)) {
+ if (ok != 0)
+ *ok = false;
+ return 0;
+ }
+
+ return bytearrayToLongLong(buff.constData(), base, ok);
+}
+
+qulonglong QLocalePrivate::stringToUnsLongLong(const QString &number, int base,
+ bool *ok, GroupSeparatorMode group_sep_mode) const
+{
+ CharBuff buff;
+ if (!numberToCLocale(number, group_sep_mode, &buff)) {
+ if (ok != 0)
+ *ok = false;
+ return 0;
+ }
+
+ return bytearrayToUnsLongLong(buff.constData(), base, ok);
+}
+
+
+double QLocalePrivate::bytearrayToDouble(const char *num, bool *ok, bool *overflow)
+{
+ if (ok != 0)
+ *ok = true;
+ if (overflow != 0)
+ *overflow = false;
+
+ if (*num == '\0') {
+ if (ok != 0)
+ *ok = false;
+ return 0.0;
+ }
+
+ if (qstrcmp(num, "nan") == 0)
+ return qt_snan();
+
+ if (qstrcmp(num, "+inf") == 0 || qstrcmp(num, "inf") == 0)
+ return qt_inf();
+
+ if (qstrcmp(num, "-inf") == 0)
+ return -qt_inf();
+
+ bool _ok;
+ const char *endptr;
+ double d = qstrtod(num, &endptr, &_ok);
+
+ if (!_ok) {
+ // the only way strtod can fail with *endptr != '\0' on a non-empty
+ // input string is overflow
+ if (ok != 0)
+ *ok = false;
+ if (overflow != 0)
+ *overflow = *endptr != '\0';
+ return 0.0;
+ }
+
+ if (*endptr != '\0') {
+ // we stopped at a non-digit character after converting some digits
+ if (ok != 0)
+ *ok = false;
+ if (overflow != 0)
+ *overflow = false;
+ return 0.0;
+ }
+
+ if (ok != 0)
+ *ok = true;
+ if (overflow != 0)
+ *overflow = false;
+ return d;
+}
+
+qlonglong QLocalePrivate::bytearrayToLongLong(const char *num, int base, bool *ok, bool *overflow)
+{
+ bool _ok;
+ const char *endptr;
+
+ if (*num == '\0') {
+ if (ok != 0)
+ *ok = false;
+ if (overflow != 0)
+ *overflow = false;
+ return 0;
+ }
+
+ qlonglong l = qstrtoll(num, &endptr, base, &_ok);
+
+ if (!_ok) {
+ if (ok != 0)
+ *ok = false;
+ if (overflow != 0) {
+ // the only way qstrtoll can fail with *endptr != '\0' on a non-empty
+ // input string is overflow
+ *overflow = *endptr != '\0';
+ }
+ return 0;
+ }
+
+ if (*endptr != '\0') {
+ // we stopped at a non-digit character after converting some digits
+ if (ok != 0)
+ *ok = false;
+ if (overflow != 0)
+ *overflow = false;
+ return 0;
+ }
+
+ if (ok != 0)
+ *ok = true;
+ if (overflow != 0)
+ *overflow = false;
+ return l;
+}
+
+qulonglong QLocalePrivate::bytearrayToUnsLongLong(const char *num, int base, bool *ok)
+{
+ bool _ok;
+ const char *endptr;
+ qulonglong l = qstrtoull(num, &endptr, base, &_ok);
+
+ if (!_ok || *endptr != '\0') {
+ if (ok != 0)
+ *ok = false;
+ return 0;
+ }
+
+ if (ok != 0)
+ *ok = true;
+ return l;
+}
+
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgment:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+// static char sccsid[] = "@(#)strtouq.c 8.1 (Berkeley) 6/4/93";
+// "$FreeBSD: src/lib/libc/stdlib/strtoull.c,v 1.5.2.1 2001/03/02 09:45:20 obrien Exp $";
+
+/*
+ * Convert a string to an unsigned long long integer.
+ *
+ * Ignores `locale' stuff. Assumes that the upper and lower case
+ * alphabets and digits are each contiguous.
+ */
+static qulonglong qstrtoull(const char *nptr, const char **endptr, register int base, bool *ok)
+{
+ register const char *s = nptr;
+ register qulonglong acc;
+ register unsigned char c;
+ register qulonglong qbase, cutoff;
+ register int any, cutlim;
+
+ if (ok != 0)
+ *ok = true;
+
+ /*
+ * See strtoq for comments as to the logic used.
+ */
+ s = nptr;
+ do {
+ c = *s++;
+ } while (isspace(c));
+ if (c == '-') {
+ if (ok != 0)
+ *ok = false;
+ if (endptr != 0)
+ *endptr = s - 1;
+ return 0;
+ } else {
+ if (c == '+')
+ c = *s++;
+ }
+ if ((base == 0 || base == 16) &&
+ c == '0' && (*s == 'x' || *s == 'X')) {
+ c = s[1];
+ s += 2;
+ base = 16;
+ }
+ if (base == 0)
+ base = c == '0' ? 8 : 10;
+ qbase = unsigned(base);
+ cutoff = qulonglong(ULLONG_MAX) / qbase;
+ cutlim = qulonglong(ULLONG_MAX) % qbase;
+ for (acc = 0, any = 0;; c = *s++) {
+ if (!isascii(c))
+ break;
+ if (isdigit(c))
+ c -= '0';
+ else if (isalpha(c))
+ c -= isupper(c) ? 'A' - 10 : 'a' - 10;
+ else
+ break;
+ if (c >= base)
+ break;
+ if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
+ any = -1;
+ else {
+ any = 1;
+ acc *= qbase;
+ acc += c;
+ }
+ }
+ if (any == 0) {
+ if (ok != 0)
+ *ok = false;
+ } else if (any < 0) {
+ acc = ULLONG_MAX;
+ if (ok != 0)
+ *ok = false;
+ }
+ if (endptr != 0)
+ *endptr = (any ? s - 1 : nptr);
+ return acc;
+}
+
+
+// "$FreeBSD: src/lib/libc/stdlib/strtoll.c,v 1.5.2.1 2001/03/02 09:45:20 obrien Exp $";
+
+
+/*
+ * Convert a string to a long long integer.
+ *
+ * Ignores `locale' stuff. Assumes that the upper and lower case
+ * alphabets and digits are each contiguous.
+ */
+Q_CORE_EXPORT qlonglong qstrtoll(const char *nptr, const char **endptr, register int base, bool *ok)
+{
+ register const char *s;
+ register qulonglong acc;
+ register unsigned char c;
+ register qulonglong qbase, cutoff;
+ register int neg, any, cutlim;
+
+ /*
+ * Skip white space and pick up leading +/- sign if any.
+ * If base is 0, allow 0x for hex and 0 for octal, else
+ * assume decimal; if base is already 16, allow 0x.
+ */
+ s = nptr;
+ do {
+ c = *s++;
+ } while (isspace(c));
+ if (c == '-') {
+ neg = 1;
+ c = *s++;
+ } else {
+ neg = 0;
+ if (c == '+')
+ c = *s++;
+ }
+ if ((base == 0 || base == 16) &&
+ c == '0' && (*s == 'x' || *s == 'X')) {
+ c = s[1];
+ s += 2;
+ base = 16;
+ }
+ if (base == 0)
+ base = c == '0' ? 8 : 10;
+
+ /*
+ * Compute the cutoff value between legal numbers and illegal
+ * numbers. That is the largest legal value, divided by the
+ * base. An input number that is greater than this value, if
+ * followed by a legal input character, is too big. One that
+ * is equal to this value may be valid or not; the limit
+ * between valid and invalid numbers is then based on the last
+ * digit. For instance, if the range for quads is
+ * [-9223372036854775808..9223372036854775807] and the input base
+ * is 10, cutoff will be set to 922337203685477580 and cutlim to
+ * either 7 (neg==0) or 8 (neg==1), meaning that if we have
+ * accumulated a value > 922337203685477580, or equal but the
+ * next digit is > 7 (or 8), the number is too big, and we will
+ * return a range error.
+ *
+ * Set any if any `digits' consumed; make it negative to indicate
+ * overflow.
+ */
+ qbase = unsigned(base);
+ cutoff = neg ? qulonglong(0-(LLONG_MIN + LLONG_MAX)) + LLONG_MAX : LLONG_MAX;
+ cutlim = cutoff % qbase;
+ cutoff /= qbase;
+ for (acc = 0, any = 0;; c = *s++) {
+ if (!isascii(c))
+ break;
+ if (isdigit(c))
+ c -= '0';
+ else if (isalpha(c))
+ c -= isupper(c) ? 'A' - 10 : 'a' - 10;
+ else
+ break;
+ if (c >= base)
+ break;
+ if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
+ any = -1;
+ else {
+ any = 1;
+ acc *= qbase;
+ acc += c;
+ }
+ }
+ if (any < 0) {
+ acc = neg ? LLONG_MIN : LLONG_MAX;
+ if (ok != 0)
+ *ok = false;
+ } else if (neg) {
+ acc = (~acc) + 1;
+ }
+ if (endptr != 0)
+ *endptr = (any >= 0 ? s - 1 : nptr);
+
+ if (ok != 0)
+ *ok = any > 0;
+
+ return acc;
+}
+
+#ifndef QT_QLOCALE_USES_FCVT
+
+/* From: NetBSD: strtod.c,v 1.26 1998/02/03 18:44:21 perry Exp */
+/* $FreeBSD: src/lib/libc/stdlib/netbsd_strtod.c,v 1.2.2.2 2001/03/02 17:14:15 tegge Exp $ */
+
+/* Please send bug reports to
+ David M. Gay
+ AT&T Bell Laboratories, Room 2C-463
+ 600 Mountain Avenue
+ Murray Hill, NJ 07974-2070
+ U.S.A.
+ dmg@research.att.com or research!dmg
+ */
+
+/* strtod for IEEE-, VAX-, and IBM-arithmetic machines.
+ *
+ * This strtod returns a nearest machine number to the input decimal
+ * string (or sets errno to ERANGE). With IEEE arithmetic, ties are
+ * broken by the IEEE round-even rule. Otherwise ties are broken by
+ * biased rounding (add half and chop).
+ *
+ * Inspired loosely by William D. Clinger's paper "How to Read Floating
+ * Point Numbers Accurately" [Proc. ACM SIGPLAN '90, pp. 92-101].
+ *
+ * Modifications:
+ *
+ * 1. We only require IEEE, IBM, or VAX double-precision
+ * arithmetic (not IEEE double-extended).
+ * 2. We get by with floating-point arithmetic in a case that
+ * Clinger missed -- when we're computing d * 10^n
+ * for a small integer d and the integer n is not too
+ * much larger than 22 (the maximum integer k for which
+ * we can represent 10^k exactly), we may be able to
+ * compute (d*10^k) * 10^(e-k) with just one roundoff.
+ * 3. Rather than a bit-at-a-time adjustment of the binary
+ * result in the hard case, we use floating-point
+ * arithmetic to determine the adjustment to within
+ * one bit; only in really hard cases do we need to
+ * compute a second residual.
+ * 4. Because of 3., we don't need a large table of powers of 10
+ * for ten-to-e (just some small tables, e.g. of 10^k
+ * for 0 <= k <= 22).
+ */
+
+/*
+ * #define IEEE_LITTLE_ENDIAN for IEEE-arithmetic machines where the least
+ * significant byte has the lowest address.
+ * #define IEEE_BIG_ENDIAN for IEEE-arithmetic machines where the most
+ * significant byte has the lowest address.
+ * #define Long int on machines with 32-bit ints and 64-bit longs.
+ * #define Sudden_Underflow for IEEE-format machines without gradual
+ * underflow (i.e., that flush to zero on underflow).
+ * #define IBM for IBM mainframe-style floating-point arithmetic.
+ * #define VAX for VAX-style floating-point arithmetic.
+ * #define Unsigned_Shifts if >> does treats its left operand as unsigned.
+ * #define No_leftright to omit left-right logic in fast floating-point
+ * computation of dtoa.
+ * #define Check_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3.
+ * #define RND_PRODQUOT to use rnd_prod and rnd_quot (assembly routines
+ * that use extended-precision instructions to compute rounded
+ * products and quotients) with IBM.
+ * #define ROUND_BIASED for IEEE-format with biased rounding.
+ * #define Inaccurate_Divide for IEEE-format with correctly rounded
+ * products but inaccurate quotients, e.g., for Intel i860.
+ * #define Just_16 to store 16 bits per 32-bit Long when doing high-precision
+ * integer arithmetic. Whether this speeds things up or slows things
+ * down depends on the machine and the number being converted.
+ * #define KR_headers for old-style C function headers.
+ * #define Bad_float_h if your system lacks a float.h or if it does not
+ * define some or all of DBL_DIG, DBL_MAX_10_EXP, DBL_MAX_EXP,
+ * FLT_RADIX, FLT_ROUNDS, and DBL_MAX.
+ * #define MALLOC your_malloc, where your_malloc(n) acts like malloc(n)
+ * if memory is available and otherwise does something you deem
+ * appropriate. If MALLOC is undefined, malloc will be invoked
+ * directly -- and assumed always to succeed.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+__RCSID("$NetBSD: strtod.c,v 1.26 1998/02/03 18:44:21 perry Exp $");
+#endif /* LIBC_SCCS and not lint */
+
+/*
+#if defined(__m68k__) || defined(__sparc__) || defined(__i386__) || \
+ defined(__mips__) || defined(__ns32k__) || defined(__alpha__) || \
+ defined(__powerpc__) || defined(Q_OS_WIN) || defined(Q_OS_DARWIN) || defined(Q_OS_MAC) || \
+ defined(mips) || defined(Q_OS_AIX) || defined(Q_OS_SOLARIS)
+# define IEEE_BIG_OR_LITTLE_ENDIAN 1
+#endif
+*/
+
+// *All* of our architectures have IEEE arithmetic, don't they?
+#define IEEE_BIG_OR_LITTLE_ENDIAN 1
+
+#ifdef __arm32__
+/*
+ * Although the CPU is little endian the FP has different
+ * byte and word endianness. The byte order is still little endian
+ * but the word order is big endian.
+ */
+#define IEEE_BIG_OR_LITTLE_ENDIAN
+#endif
+
+#ifdef vax
+#define VAX
+#endif
+
+#define Long qint32
+#define ULong quint32
+
+#define MALLOC malloc
+
+#ifdef BSD_QDTOA_DEBUG
+QT_BEGIN_INCLUDE_NAMESPACE
+#include <stdio.h>
+QT_END_INCLUDE_NAMESPACE
+
+#define Bug(x) {fprintf(stderr, "%s\n", x); exit(1);}
+#endif
+
+#ifdef Unsigned_Shifts
+#define Sign_Extend(a,b) if (b < 0) a |= 0xffff0000;
+#else
+#define Sign_Extend(a,b) /*no-op*/
+#endif
+
+#if (defined(IEEE_BIG_OR_LITTLE_ENDIAN) + defined(VAX) + defined(IBM)) != 1
+#error Exactly one of IEEE_BIG_OR_LITTLE_ENDIAN, VAX, or IBM should be defined.
+#endif
+
+static inline ULong _getWord0(const NEEDS_VOLATILE double x)
+{
+ const NEEDS_VOLATILE uchar *ptr = reinterpret_cast<const NEEDS_VOLATILE uchar *>(&x);
+ if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
+ return (ptr[0]<<24) + (ptr[1]<<16) + (ptr[2]<<8) + ptr[3];
+ } else {
+ return (ptr[7]<<24) + (ptr[6]<<16) + (ptr[5]<<8) + ptr[4];
+ }
+}
+
+static inline void _setWord0(NEEDS_VOLATILE double *x, ULong l)
+{
+ NEEDS_VOLATILE uchar *ptr = reinterpret_cast<NEEDS_VOLATILE uchar *>(x);
+ if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
+ ptr[0] = uchar(l>>24);
+ ptr[1] = uchar(l>>16);
+ ptr[2] = uchar(l>>8);
+ ptr[3] = uchar(l);
+ } else {
+ ptr[7] = uchar(l>>24);
+ ptr[6] = uchar(l>>16);
+ ptr[5] = uchar(l>>8);
+ ptr[4] = uchar(l);
+ }
+}
+
+static inline ULong _getWord1(const NEEDS_VOLATILE double x)
+{
+ const NEEDS_VOLATILE uchar *ptr = reinterpret_cast<const NEEDS_VOLATILE uchar *>(&x);
+ if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
+ return (ptr[4]<<24) + (ptr[5]<<16) + (ptr[6]<<8) + ptr[7];
+ } else {
+ return (ptr[3]<<24) + (ptr[2]<<16) + (ptr[1]<<8) + ptr[0];
+ }
+}
+static inline void _setWord1(NEEDS_VOLATILE double *x, ULong l)
+{
+ NEEDS_VOLATILE uchar *ptr = reinterpret_cast<uchar NEEDS_VOLATILE *>(x);
+ if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
+ ptr[4] = uchar(l>>24);
+ ptr[5] = uchar(l>>16);
+ ptr[6] = uchar(l>>8);
+ ptr[7] = uchar(l);
+ } else {
+ ptr[3] = uchar(l>>24);
+ ptr[2] = uchar(l>>16);
+ ptr[1] = uchar(l>>8);
+ ptr[0] = uchar(l);
+ }
+}
+
+static inline ULong getWord0(const NEEDS_VOLATILE double x)
+{
+#ifdef QT_ARMFPA
+ return _getWord1(x);
+#else
+ return _getWord0(x);
+#endif
+}
+
+static inline void setWord0(NEEDS_VOLATILE double *x, ULong l)
+{
+#ifdef QT_ARMFPA
+ _setWord1(x, l);
+#else
+ _setWord0(x, l);
+#endif
+}
+
+static inline ULong getWord1(const NEEDS_VOLATILE double x)
+{
+#ifdef QT_ARMFPA
+ return _getWord0(x);
+#else
+ return _getWord1(x);
+#endif
+}
+
+static inline void setWord1(NEEDS_VOLATILE double *x, ULong l)
+{
+#ifdef QT_ARMFPA
+ _setWord0(x, l);
+#else
+ _setWord1(x, l);
+#endif
+}
+
+static inline void Storeinc(ULong *&a, const ULong &b, const ULong &c)
+{
+
+ *a = (ushort(b) << 16) | ushort(c);
+ ++a;
+}
+
+/* #define P DBL_MANT_DIG */
+/* Ten_pmax = floor(P*log(2)/log(5)) */
+/* Bletch = (highest power of 2 < DBL_MAX_10_EXP) / 16 */
+/* Quick_max = floor((P-1)*log(FLT_RADIX)/log(10) - 1) */
+/* Int_max = floor(P*log(FLT_RADIX)/log(10) - 1) */
+
+#if defined(IEEE_BIG_OR_LITTLE_ENDIAN)
+#define Exp_shift 20
+#define Exp_shift1 20
+#define Exp_msk1 0x100000
+#define Exp_msk11 0x100000
+#define Exp_mask 0x7ff00000
+#define P 53
+#define Bias 1023
+#define IEEE_Arith
+#define Emin (-1022)
+#define Exp_1 0x3ff00000
+#define Exp_11 0x3ff00000
+#define Ebits 11
+#define Frac_mask 0xfffff
+#define Frac_mask1 0xfffff
+#define Ten_pmax 22
+#define Bletch 0x10
+#define Bndry_mask 0xfffff
+#define Bndry_mask1 0xfffff
+#define LSB 1
+#define Sign_bit 0x80000000
+#define Log2P 1
+#define Tiny0 0
+#define Tiny1 1
+#define Quick_max 14
+#define Int_max 14
+#define Infinite(x) (getWord0(x) == 0x7ff00000) /* sufficient test for here */
+#else
+#undef Sudden_Underflow
+#define Sudden_Underflow
+#ifdef IBM
+#define Exp_shift 24
+#define Exp_shift1 24
+#define Exp_msk1 0x1000000
+#define Exp_msk11 0x1000000
+#define Exp_mask 0x7f000000
+#define P 14
+#define Bias 65
+#define Exp_1 0x41000000
+#define Exp_11 0x41000000
+#define Ebits 8 /* exponent has 7 bits, but 8 is the right value in b2d */
+#define Frac_mask 0xffffff
+#define Frac_mask1 0xffffff
+#define Bletch 4
+#define Ten_pmax 22
+#define Bndry_mask 0xefffff
+#define Bndry_mask1 0xffffff
+#define LSB 1
+#define Sign_bit 0x80000000
+#define Log2P 4
+#define Tiny0 0x100000
+#define Tiny1 0
+#define Quick_max 14
+#define Int_max 15
+#else /* VAX */
+#define Exp_shift 23
+#define Exp_shift1 7
+#define Exp_msk1 0x80
+#define Exp_msk11 0x800000
+#define Exp_mask 0x7f80
+#define P 56
+#define Bias 129
+#define Exp_1 0x40800000
+#define Exp_11 0x4080
+#define Ebits 8
+#define Frac_mask 0x7fffff
+#define Frac_mask1 0xffff007f
+#define Ten_pmax 24
+#define Bletch 2
+#define Bndry_mask 0xffff007f
+#define Bndry_mask1 0xffff007f
+#define LSB 0x10000
+#define Sign_bit 0x8000
+#define Log2P 1
+#define Tiny0 0x80
+#define Tiny1 0
+#define Quick_max 15
+#define Int_max 15
+#endif
+#endif
+
+#ifndef IEEE_Arith
+#define ROUND_BIASED
+#endif
+
+#ifdef RND_PRODQUOT
+#define rounded_product(a,b) a = rnd_prod(a, b)
+#define rounded_quotient(a,b) a = rnd_quot(a, b)
+extern double rnd_prod(double, double), rnd_quot(double, double);
+#else
+#define rounded_product(a,b) a *= b
+#define rounded_quotient(a,b) a /= b
+#endif
+
+#define Big0 (Frac_mask1 | Exp_msk1*(DBL_MAX_EXP+Bias-1))
+#define Big1 0xffffffff
+
+#ifndef Just_16
+/* When Pack_32 is not defined, we store 16 bits per 32-bit Long.
+ * This makes some inner loops simpler and sometimes saves work
+ * during multiplications, but it often seems to make things slightly
+ * slower. Hence the default is now to store 32 bits per Long.
+ */
+#ifndef Pack_32
+#define Pack_32
+#endif
+#endif
+
+#define Kmax 15
+
+struct
+Bigint {
+ struct Bigint *next;
+ int k, maxwds, sign, wds;
+ ULong x[1];
+};
+
+ typedef struct Bigint Bigint;
+
+static Bigint *Balloc(int k)
+{
+ int x;
+ Bigint *rv;
+
+ x = 1 << k;
+ rv = static_cast<Bigint *>(MALLOC(sizeof(Bigint) + (x-1)*sizeof(Long)));
+ rv->k = k;
+ rv->maxwds = x;
+ rv->sign = rv->wds = 0;
+ return rv;
+}
+
+static void Bfree(Bigint *v)
+{
+ free(v);
+}
+
+#define Bcopy(x,y) memcpy(reinterpret_cast<char *>(&x->sign), reinterpret_cast<char *>(&y->sign), \
+y->wds*sizeof(Long) + 2*sizeof(int))
+
+/* multiply by m and add a */
+static Bigint *multadd(Bigint *b, int m, int a)
+{
+ int i, wds;
+ ULong *x, y;
+#ifdef Pack_32
+ ULong xi, z;
+#endif
+ Bigint *b1;
+
+ wds = b->wds;
+ x = b->x;
+ i = 0;
+ do {
+#ifdef Pack_32
+ xi = *x;
+ y = (xi & 0xffff) * m + a;
+ z = (xi >> 16) * m + (y >> 16);
+ a = (z >> 16);
+ *x++ = (z << 16) + (y & 0xffff);
+#else
+ y = *x * m + a;
+ a = (y >> 16);
+ *x++ = y & 0xffff;
+#endif
+ }
+ while(++i < wds);
+ if (a) {
+ if (wds >= b->maxwds) {
+ b1 = Balloc(b->k+1);
+ Bcopy(b1, b);
+ Bfree(b);
+ b = b1;
+ }
+ b->x[wds++] = a;
+ b->wds = wds;
+ }
+ return b;
+}
+
+static Bigint *s2b(const char *s, int nd0, int nd, ULong y9)
+{
+ Bigint *b;
+ int i, k;
+ Long x, y;
+
+ x = (nd + 8) / 9;
+ for(k = 0, y = 1; x > y; y <<= 1, k++) ;
+#ifdef Pack_32
+ b = Balloc(k);
+ b->x[0] = y9;
+ b->wds = 1;
+#else
+ b = Balloc(k+1);
+ b->x[0] = y9 & 0xffff;
+ b->wds = (b->x[1] = y9 >> 16) ? 2 : 1;
+#endif
+
+ i = 9;
+ if (9 < nd0) {
+ s += 9;
+ do b = multadd(b, 10, *s++ - '0');
+ while(++i < nd0);
+ s++;
+ }
+ else
+ s += 10;
+ for(; i < nd; i++)
+ b = multadd(b, 10, *s++ - '0');
+ return b;
+}
+
+static int hi0bits(ULong x)
+{
+ int k = 0;
+
+ if (!(x & 0xffff0000)) {
+ k = 16;
+ x <<= 16;
+ }
+ if (!(x & 0xff000000)) {
+ k += 8;
+ x <<= 8;
+ }
+ if (!(x & 0xf0000000)) {
+ k += 4;
+ x <<= 4;
+ }
+ if (!(x & 0xc0000000)) {
+ k += 2;
+ x <<= 2;
+ }
+ if (!(x & 0x80000000)) {
+ k++;
+ if (!(x & 0x40000000))
+ return 32;
+ }
+ return k;
+}
+
+static int lo0bits(ULong *y)
+{
+ int k;
+ ULong x = *y;
+
+ if (x & 7) {
+ if (x & 1)
+ return 0;
+ if (x & 2) {
+ *y = x >> 1;
+ return 1;
+ }
+ *y = x >> 2;
+ return 2;
+ }
+ k = 0;
+ if (!(x & 0xffff)) {
+ k = 16;
+ x >>= 16;
+ }
+ if (!(x & 0xff)) {
+ k += 8;
+ x >>= 8;
+ }
+ if (!(x & 0xf)) {
+ k += 4;
+ x >>= 4;
+ }
+ if (!(x & 0x3)) {
+ k += 2;
+ x >>= 2;
+ }
+ if (!(x & 1)) {
+ k++;
+ x >>= 1;
+ if (!x & 1)
+ return 32;
+ }
+ *y = x;
+ return k;
+}
+
+static Bigint *i2b(int i)
+{
+ Bigint *b;
+
+ b = Balloc(1);
+ b->x[0] = i;
+ b->wds = 1;
+ return b;
+}
+
+static Bigint *mult(Bigint *a, Bigint *b)
+{
+ Bigint *c;
+ int k, wa, wb, wc;
+ ULong carry, y, z;
+ ULong *x, *xa, *xae, *xb, *xbe, *xc, *xc0;
+#ifdef Pack_32
+ ULong z2;
+#endif
+
+ if (a->wds < b->wds) {
+ c = a;
+ a = b;
+ b = c;
+ }
+ k = a->k;
+ wa = a->wds;
+ wb = b->wds;
+ wc = wa + wb;
+ if (wc > a->maxwds)
+ k++;
+ c = Balloc(k);
+ for(x = c->x, xa = x + wc; x < xa; x++)
+ *x = 0;
+ xa = a->x;
+ xae = xa + wa;
+ xb = b->x;
+ xbe = xb + wb;
+ xc0 = c->x;
+#ifdef Pack_32
+ for(; xb < xbe; xb++, xc0++) {
+ if ((y = *xb & 0xffff) != 0) {
+ x = xa;
+ xc = xc0;
+ carry = 0;
+ do {
+ z = (*x & 0xffff) * y + (*xc & 0xffff) + carry;
+ carry = z >> 16;
+ z2 = (*x++ >> 16) * y + (*xc >> 16) + carry;
+ carry = z2 >> 16;
+ Storeinc(xc, z2, z);
+ }
+ while(x < xae);
+ *xc = carry;
+ }
+ if ((y = *xb >> 16) != 0) {
+ x = xa;
+ xc = xc0;
+ carry = 0;
+ z2 = *xc;
+ do {
+ z = (*x & 0xffff) * y + (*xc >> 16) + carry;
+ carry = z >> 16;
+ Storeinc(xc, z, z2);
+ z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry;
+ carry = z2 >> 16;
+ }
+ while(x < xae);
+ *xc = z2;
+ }
+ }
+#else
+ for(; xb < xbe; xc0++) {
+ if (y = *xb++) {
+ x = xa;
+ xc = xc0;
+ carry = 0;
+ do {
+ z = *x++ * y + *xc + carry;
+ carry = z >> 16;
+ *xc++ = z & 0xffff;
+ }
+ while(x < xae);
+ *xc = carry;
+ }
+ }
+#endif
+ for(xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) ;
+ c->wds = wc;
+ return c;
+}
+
+static Bigint *p5s;
+
+static Bigint *pow5mult(Bigint *b, int k)
+{
+ Bigint *b1, *p5, *p51;
+ int i;
+ static const int p05[3] = { 5, 25, 125 };
+
+ if ((i = k & 3) != 0)
+#if defined(Q_OS_IRIX) && defined(Q_CC_GNU)
+ {
+ // work around a bug on 64 bit IRIX gcc
+ int *p = (int *) p05;
+ b = multadd(b, p[i-1], 0);
+ }
+#else
+ b = multadd(b, p05[i-1], 0);
+#endif
+
+ if (!(k >>= 2))
+ return b;
+ if (!(p5 = p5s)) {
+ /* first time */
+ p5 = p5s = i2b(625);
+ p5->next = 0;
+ }
+ for(;;) {
+ if (k & 1) {
+ b1 = mult(b, p5);
+ Bfree(b);
+ b = b1;
+ }
+ if (!(k >>= 1))
+ break;
+ if (!(p51 = p5->next)) {
+ p51 = p5->next = mult(p5,p5);
+ p51->next = 0;
+ }
+ p5 = p51;
+ }
+ return b;
+}
+
+static Bigint *lshift(Bigint *b, int k)
+{
+ int i, k1, n, n1;
+ Bigint *b1;
+ ULong *x, *x1, *xe, z;
+
+#ifdef Pack_32
+ n = k >> 5;
+#else
+ n = k >> 4;
+#endif
+ k1 = b->k;
+ n1 = n + b->wds + 1;
+ for(i = b->maxwds; n1 > i; i <<= 1)
+ k1++;
+ b1 = Balloc(k1);
+ x1 = b1->x;
+ for(i = 0; i < n; i++)
+ *x1++ = 0;
+ x = b->x;
+ xe = x + b->wds;
+#ifdef Pack_32
+ if (k &= 0x1f) {
+ k1 = 32 - k;
+ z = 0;
+ do {
+ *x1++ = *x << k | z;
+ z = *x++ >> k1;
+ }
+ while(x < xe);
+ if ((*x1 = z) != 0)
+ ++n1;
+ }
+#else
+ if (k &= 0xf) {
+ k1 = 16 - k;
+ z = 0;
+ do {
+ *x1++ = *x << k & 0xffff | z;
+ z = *x++ >> k1;
+ }
+ while(x < xe);
+ if (*x1 = z)
+ ++n1;
+ }
+#endif
+ else do
+ *x1++ = *x++;
+ while(x < xe);
+ b1->wds = n1 - 1;
+ Bfree(b);
+ return b1;
+}
+
+static int cmp(Bigint *a, Bigint *b)
+{
+ ULong *xa, *xa0, *xb, *xb0;
+ int i, j;
+
+ i = a->wds;
+ j = b->wds;
+#ifdef BSD_QDTOA_DEBUG
+ if (i > 1 && !a->x[i-1])
+ Bug("cmp called with a->x[a->wds-1] == 0");
+ if (j > 1 && !b->x[j-1])
+ Bug("cmp called with b->x[b->wds-1] == 0");
+#endif
+ if (i -= j)
+ return i;
+ xa0 = a->x;
+ xa = xa0 + j;
+ xb0 = b->x;
+ xb = xb0 + j;
+ for(;;) {
+ if (*--xa != *--xb)
+ return *xa < *xb ? -1 : 1;
+ if (xa <= xa0)
+ break;
+ }
+ return 0;
+}
+
+static Bigint *diff(Bigint *a, Bigint *b)
+{
+ Bigint *c;
+ int i, wa, wb;
+ Long borrow, y; /* We need signed shifts here. */
+ ULong *xa, *xae, *xb, *xbe, *xc;
+#ifdef Pack_32
+ Long z;
+#endif
+
+ i = cmp(a,b);
+ if (!i) {
+ c = Balloc(0);
+ c->wds = 1;
+ c->x[0] = 0;
+ return c;
+ }
+ if (i < 0) {
+ c = a;
+ a = b;
+ b = c;
+ i = 1;
+ }
+ else
+ i = 0;
+ c = Balloc(a->k);
+ c->sign = i;
+ wa = a->wds;
+ xa = a->x;
+ xae = xa + wa;
+ wb = b->wds;
+ xb = b->x;
+ xbe = xb + wb;
+ xc = c->x;
+ borrow = 0;
+#ifdef Pack_32
+ do {
+ y = (*xa & 0xffff) - (*xb & 0xffff) + borrow;
+ borrow = y >> 16;
+ Sign_Extend(borrow, y);
+ z = (*xa++ >> 16) - (*xb++ >> 16) + borrow;
+ borrow = z >> 16;
+ Sign_Extend(borrow, z);
+ Storeinc(xc, z, y);
+ }
+ while(xb < xbe);
+ while(xa < xae) {
+ y = (*xa & 0xffff) + borrow;
+ borrow = y >> 16;
+ Sign_Extend(borrow, y);
+ z = (*xa++ >> 16) + borrow;
+ borrow = z >> 16;
+ Sign_Extend(borrow, z);
+ Storeinc(xc, z, y);
+ }
+#else
+ do {
+ y = *xa++ - *xb++ + borrow;
+ borrow = y >> 16;
+ Sign_Extend(borrow, y);
+ *xc++ = y & 0xffff;
+ }
+ while(xb < xbe);
+ while(xa < xae) {
+ y = *xa++ + borrow;
+ borrow = y >> 16;
+ Sign_Extend(borrow, y);
+ *xc++ = y & 0xffff;
+ }
+#endif
+ while(!*--xc)
+ wa--;
+ c->wds = wa;
+ return c;
+}
+
+static double ulp(double x)
+{
+ Long L;
+ double a;
+
+ L = (getWord0(x) & Exp_mask) - (P-1)*Exp_msk1;
+#ifndef Sudden_Underflow
+ if (L > 0) {
+#endif
+#ifdef IBM
+ L |= Exp_msk1 >> 4;
+#endif
+ setWord0(&a, L);
+ setWord1(&a, 0);
+#ifndef Sudden_Underflow
+ }
+ else {
+ L = -L >> Exp_shift;
+ if (L < Exp_shift) {
+ setWord0(&a, 0x80000 >> L);
+ setWord1(&a, 0);
+ }
+ else {
+ setWord0(&a, 0);
+ L -= Exp_shift;
+ setWord1(&a, L >= 31 ? 1U : 1U << (31 - L));
+ }
+ }
+#endif
+ return a;
+}
+
+static double b2d(Bigint *a, int *e)
+{
+ ULong *xa, *xa0, w, y, z;
+ int k;
+ double d;
+
+ xa0 = a->x;
+ xa = xa0 + a->wds;
+ y = *--xa;
+#ifdef BSD_QDTOA_DEBUG
+ if (!y) Bug("zero y in b2d");
+#endif
+ k = hi0bits(y);
+ *e = 32 - k;
+#ifdef Pack_32
+ if (k < Ebits) {
+ setWord0(&d, Exp_1 | y >> (Ebits - k));
+ w = xa > xa0 ? *--xa : 0;
+ setWord1(&d, y << ((32-Ebits) + k) | w >> (Ebits - k));
+ goto ret_d;
+ }
+ z = xa > xa0 ? *--xa : 0;
+ if (k -= Ebits) {
+ setWord0(&d, Exp_1 | y << k | z >> (32 - k));
+ y = xa > xa0 ? *--xa : 0;
+ setWord1(&d, z << k | y >> (32 - k));
+ }
+ else {
+ setWord0(&d, Exp_1 | y);
+ setWord1(&d, z);
+ }
+#else
+ if (k < Ebits + 16) {
+ z = xa > xa0 ? *--xa : 0;
+ setWord0(&d, Exp_1 | y << k - Ebits | z >> Ebits + 16 - k);
+ w = xa > xa0 ? *--xa : 0;
+ y = xa > xa0 ? *--xa : 0;
+ setWord1(&d, z << k + 16 - Ebits | w << k - Ebits | y >> 16 + Ebits - k);
+ goto ret_d;
+ }
+ z = xa > xa0 ? *--xa : 0;
+ w = xa > xa0 ? *--xa : 0;
+ k -= Ebits + 16;
+ setWord0(&d, Exp_1 | y << k + 16 | z << k | w >> 16 - k);
+ y = xa > xa0 ? *--xa : 0;
+ setWord1(&d, w << k + 16 | y << k);
+#endif
+ ret_d:
+ return d;
+}
+
+static Bigint *d2b(double d, int *e, int *bits)
+{
+ Bigint *b;
+ int de, i, k;
+ ULong *x, y, z;
+
+#ifdef Pack_32
+ b = Balloc(1);
+#else
+ b = Balloc(2);
+#endif
+ x = b->x;
+
+ z = getWord0(d) & Frac_mask;
+ setWord0(&d, getWord0(d) & 0x7fffffff); /* clear sign bit, which we ignore */
+#ifdef Sudden_Underflow
+ de = (int)(getWord0(d) >> Exp_shift);
+#ifndef IBM
+ z |= Exp_msk11;
+#endif
+#else
+ if ((de = int(getWord0(d) >> Exp_shift)) != 0)
+ z |= Exp_msk1;
+#endif
+#ifdef Pack_32
+ if ((y = getWord1(d)) != 0) {
+ if ((k = lo0bits(&y)) != 0) {
+ x[0] = y | z << (32 - k);
+ z >>= k;
+ }
+ else
+ x[0] = y;
+ i = b->wds = (x[1] = z) ? 2 : 1;
+ }
+ else {
+#ifdef BSD_QDTOA_DEBUG
+ if (!z)
+ Bug("Zero passed to d2b");
+#endif
+ k = lo0bits(&z);
+ x[0] = z;
+ i = b->wds = 1;
+ k += 32;
+ }
+#else
+ if (y = getWord1(d)) {
+ if (k = lo0bits(&y))
+ if (k >= 16) {
+ x[0] = y | z << 32 - k & 0xffff;
+ x[1] = z >> k - 16 & 0xffff;
+ x[2] = z >> k;
+ i = 2;
+ }
+ else {
+ x[0] = y & 0xffff;
+ x[1] = y >> 16 | z << 16 - k & 0xffff;
+ x[2] = z >> k & 0xffff;
+ x[3] = z >> k+16;
+ i = 3;
+ }
+ else {
+ x[0] = y & 0xffff;
+ x[1] = y >> 16;
+ x[2] = z & 0xffff;
+ x[3] = z >> 16;
+ i = 3;
+ }
+ }
+ else {
+#ifdef BSD_QDTOA_DEBUG
+ if (!z)
+ Bug("Zero passed to d2b");
+#endif
+ k = lo0bits(&z);
+ if (k >= 16) {
+ x[0] = z;
+ i = 0;
+ }
+ else {
+ x[0] = z & 0xffff;
+ x[1] = z >> 16;
+ i = 1;
+ }
+ k += 32;
+ }
+ while(!x[i])
+ --i;
+ b->wds = i + 1;
+#endif
+#ifndef Sudden_Underflow
+ if (de) {
+#endif
+#ifdef IBM
+ *e = (de - Bias - (P-1) << 2) + k;
+ *bits = 4*P + 8 - k - hi0bits(getWord0(d) & Frac_mask);
+#else
+ *e = de - Bias - (P-1) + k;
+ *bits = P - k;
+#endif
+#ifndef Sudden_Underflow
+ }
+ else {
+ *e = de - Bias - (P-1) + 1 + k;
+#ifdef Pack_32
+ *bits = 32*i - hi0bits(x[i-1]);
+#else
+ *bits = (i+2)*16 - hi0bits(x[i]);
+#endif
+ }
+#endif
+ return b;
+}
+
+static double ratio(Bigint *a, Bigint *b)
+{
+ double da, db;
+ int k, ka, kb;
+
+ da = b2d(a, &ka);
+ db = b2d(b, &kb);
+#ifdef Pack_32
+ k = ka - kb + 32*(a->wds - b->wds);
+#else
+ k = ka - kb + 16*(a->wds - b->wds);
+#endif
+#ifdef IBM
+ if (k > 0) {
+ setWord0(&da, getWord0(da) + (k >> 2)*Exp_msk1);
+ if (k &= 3)
+ da *= 1 << k;
+ }
+ else {
+ k = -k;
+ setWord0(&db, getWord0(db) + (k >> 2)*Exp_msk1);
+ if (k &= 3)
+ db *= 1 << k;
+ }
+#else
+ if (k > 0)
+ setWord0(&da, getWord0(da) + k*Exp_msk1);
+ else {
+ k = -k;
+ setWord0(&db, getWord0(db) + k*Exp_msk1);
+ }
+#endif
+ return da / db;
+}
+
+static const double tens[] = {
+ 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
+ 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
+ 1e20, 1e21, 1e22
+#ifdef VAX
+ , 1e23, 1e24
+#endif
+};
+
+#ifdef IEEE_Arith
+static const double bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 };
+static const double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128, 1e-256 };
+#define n_bigtens 5
+#else
+#ifdef IBM
+static const double bigtens[] = { 1e16, 1e32, 1e64 };
+static const double tinytens[] = { 1e-16, 1e-32, 1e-64 };
+#define n_bigtens 3
+#else
+static const double bigtens[] = { 1e16, 1e32 };
+static const double tinytens[] = { 1e-16, 1e-32 };
+#define n_bigtens 2
+#endif
+#endif
+
+/*
+ The pre-release gcc3.3 shipped with SuSE 8.2 has a bug which causes
+ the comparison 1e-100 == 0.0 to return true. As a workaround, we
+ compare it to a global variable containing 0.0, which produces
+ correct assembler output.
+
+ ### consider detecting the broken compilers and using the static
+ ### double for these, and use a #define for all working compilers
+*/
+static double g_double_zero = 0.0;
+
+Q_CORE_EXPORT double qstrtod(const char *s00, const char **se, bool *ok)
+{
+ int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, dsign,
+ e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign;
+ const char *s, *s0, *s1;
+ double aadj, aadj1, adj, rv, rv0;
+ Long L;
+ ULong y, z;
+ Bigint *bb1, *bd0;
+ Bigint *bb = NULL, *bd = NULL, *bs = NULL, *delta = NULL;/* pacify gcc */
+
+ /*
+ #ifndef KR_headers
+ const char decimal_point = localeconv()->decimal_point[0];
+ #else
+ const char decimal_point = '.';
+ #endif */
+ if (ok != 0)
+ *ok = true;
+
+ const char decimal_point = '.';
+
+ sign = nz0 = nz = 0;
+ rv = 0.;
+
+
+ for(s = s00; isspace(uchar(*s)); s++)
+ ;
+
+ if (*s == '-') {
+ sign = 1;
+ s++;
+ } else if (*s == '+') {
+ s++;
+ }
+
+ if (*s == '\0') {
+ s = s00;
+ goto ret;
+ }
+
+ if (*s == '0') {
+ nz0 = 1;
+ while(*++s == '0') ;
+ if (!*s)
+ goto ret;
+ }
+ s0 = s;
+ y = z = 0;
+ for(nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++)
+ if (nd < 9)
+ y = 10*y + c - '0';
+ else if (nd < 16)
+ z = 10*z + c - '0';
+ nd0 = nd;
+ if (c == decimal_point) {
+ c = *++s;
+ if (!nd) {
+ for(; c == '0'; c = *++s)
+ nz++;
+ if (c > '0' && c <= '9') {
+ s0 = s;
+ nf += nz;
+ nz = 0;
+ goto have_dig;
+ }
+ goto dig_done;
+ }
+ for(; c >= '0' && c <= '9'; c = *++s) {
+ have_dig:
+ nz++;
+ if (c -= '0') {
+ nf += nz;
+ for(i = 1; i < nz; i++)
+ if (nd++ < 9)
+ y *= 10;
+ else if (nd <= DBL_DIG + 1)
+ z *= 10;
+ if (nd++ < 9)
+ y = 10*y + c;
+ else if (nd <= DBL_DIG + 1)
+ z = 10*z + c;
+ nz = 0;
+ }
+ }
+ }
+ dig_done:
+ e = 0;
+ if (c == 'e' || c == 'E') {
+ if (!nd && !nz && !nz0) {
+ s = s00;
+ goto ret;
+ }
+ s00 = s;
+ esign = 0;
+ switch(c = *++s) {
+ case '-':
+ esign = 1;
+ case '+':
+ c = *++s;
+ }
+ if (c >= '0' && c <= '9') {
+ while(c == '0')
+ c = *++s;
+ if (c > '0' && c <= '9') {
+ L = c - '0';
+ s1 = s;
+ while((c = *++s) >= '0' && c <= '9')
+ L = 10*L + c - '0';
+ if (s - s1 > 8 || L > 19999)
+ /* Avoid confusion from exponents
+ * so large that e might overflow.
+ */
+ e = 19999; /* safe for 16 bit ints */
+ else
+ e = int(L);
+ if (esign)
+ e = -e;
+ }
+ else
+ e = 0;
+ }
+ else
+ s = s00;
+ }
+ if (!nd) {
+ if (!nz && !nz0)
+ s = s00;
+ goto ret;
+ }
+ e1 = e -= nf;
+
+ /* Now we have nd0 digits, starting at s0, followed by a
+ * decimal point, followed by nd-nd0 digits. The number we're
+ * after is the integer represented by those digits times
+ * 10**e */
+
+ if (!nd0)
+ nd0 = nd;
+ k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1;
+ rv = y;
+ if (k > 9)
+#if defined(Q_OS_IRIX) && defined(Q_CC_GNU)
+ {
+ // work around a bug on 64 bit IRIX gcc
+ double *t = (double *) tens;
+ rv = t[k - 9] * rv + z;
+ }
+#else
+ rv = tens[k - 9] * rv + z;
+#endif
+
+ bd0 = 0;
+ if (nd <= DBL_DIG
+#ifndef RND_PRODQUOT
+ && FLT_ROUNDS == 1
+#endif
+ ) {
+ if (!e)
+ goto ret;
+ if (e > 0) {
+ if (e <= Ten_pmax) {
+#ifdef VAX
+ goto vax_ovfl_check;
+#else
+ /* rv = */ rounded_product(rv, tens[e]);
+ goto ret;
+#endif
+ }
+ i = DBL_DIG - nd;
+ if (e <= Ten_pmax + i) {
+ /* A fancier test would sometimes let us do
+ * this for larger i values.
+ */
+ e -= i;
+ rv *= tens[i];
+#ifdef VAX
+ /* VAX exponent range is so narrow we must
+ * worry about overflow here...
+ */
+ vax_ovfl_check:
+ setWord0(&rv, getWord0(rv) - P*Exp_msk1);
+ /* rv = */ rounded_product(rv, tens[e]);
+ if ((getWord0(rv) & Exp_mask)
+ > Exp_msk1*(DBL_MAX_EXP+Bias-1-P))
+ goto ovfl;
+ setWord0(&rv, getWord0(rv) + P*Exp_msk1);
+#else
+ /* rv = */ rounded_product(rv, tens[e]);
+#endif
+ goto ret;
+ }
+ }
+#ifndef Inaccurate_Divide
+ else if (e >= -Ten_pmax) {
+ /* rv = */ rounded_quotient(rv, tens[-e]);
+ goto ret;
+ }
+#endif
+ }
+ e1 += nd - k;
+
+ /* Get starting approximation = rv * 10**e1 */
+
+ if (e1 > 0) {
+ if ((i = e1 & 15) != 0)
+ rv *= tens[i];
+ if (e1 &= ~15) {
+ if (e1 > DBL_MAX_10_EXP) {
+ ovfl:
+ // errno = ERANGE;
+ if (ok != 0)
+ *ok = false;
+#ifdef __STDC__
+ rv = HUGE_VAL;
+#else
+ /* Can't trust HUGE_VAL */
+#ifdef IEEE_Arith
+ setWord0(&rv, Exp_mask);
+ setWord1(&rv, 0);
+#else
+ setWord0(&rv, Big0);
+ setWord1(&rv, Big1);
+#endif
+#endif
+ if (bd0)
+ goto retfree;
+ goto ret;
+ }
+ if (e1 >>= 4) {
+ for(j = 0; e1 > 1; j++, e1 >>= 1)
+ if (e1 & 1)
+ rv *= bigtens[j];
+ /* The last multiplication could overflow. */
+ setWord0(&rv, getWord0(rv) - P*Exp_msk1);
+ rv *= bigtens[j];
+ if ((z = getWord0(rv) & Exp_mask)
+ > Exp_msk1*(DBL_MAX_EXP+Bias-P))
+ goto ovfl;
+ if (z > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) {
+ /* set to largest number */
+ /* (Can't trust DBL_MAX) */
+ setWord0(&rv, Big0);
+ setWord1(&rv, Big1);
+ }
+ else
+ setWord0(&rv, getWord0(rv) + P*Exp_msk1);
+ }
+
+ }
+ }
+ else if (e1 < 0) {
+ e1 = -e1;
+ if ((i = e1 & 15) != 0)
+ rv /= tens[i];
+ if (e1 &= ~15) {
+ e1 >>= 4;
+ if (e1 >= 1 << n_bigtens)
+ goto undfl;
+ for(j = 0; e1 > 1; j++, e1 >>= 1)
+ if (e1 & 1)
+ rv *= tinytens[j];
+ /* The last multiplication could underflow. */
+ rv0 = rv;
+ rv *= tinytens[j];
+ if (rv == g_double_zero)
+ {
+ rv = 2.*rv0;
+ rv *= tinytens[j];
+ if (rv == g_double_zero)
+ {
+ undfl:
+ rv = 0.;
+ // errno = ERANGE;
+ if (ok != 0)
+ *ok = false;
+ if (bd0)
+ goto retfree;
+ goto ret;
+ }
+ setWord0(&rv, Tiny0);
+ setWord1(&rv, Tiny1);
+ /* The refinement below will clean
+ * this approximation up.
+ */
+ }
+ }
+ }
+
+ /* Now the hard part -- adjusting rv to the correct value.*/
+
+ /* Put digits into bd: true value = bd * 10^e */
+
+ bd0 = s2b(s0, nd0, nd, y);
+
+ for(;;) {
+ bd = Balloc(bd0->k);
+ Bcopy(bd, bd0);
+ bb = d2b(rv, &bbe, &bbbits); /* rv = bb * 2^bbe */
+ bs = i2b(1);
+
+ if (e >= 0) {
+ bb2 = bb5 = 0;
+ bd2 = bd5 = e;
+ }
+ else {
+ bb2 = bb5 = -e;
+ bd2 = bd5 = 0;
+ }
+ if (bbe >= 0)
+ bb2 += bbe;
+ else
+ bd2 -= bbe;
+ bs2 = bb2;
+#ifdef Sudden_Underflow
+#ifdef IBM
+ j = 1 + 4*P - 3 - bbbits + ((bbe + bbbits - 1) & 3);
+#else
+ j = P + 1 - bbbits;
+#endif
+#else
+ i = bbe + bbbits - 1; /* logb(rv) */
+ if (i < Emin) /* denormal */
+ j = bbe + (P-Emin);
+ else
+ j = P + 1 - bbbits;
+#endif
+ bb2 += j;
+ bd2 += j;
+ i = bb2 < bd2 ? bb2 : bd2;
+ if (i > bs2)
+ i = bs2;
+ if (i > 0) {
+ bb2 -= i;
+ bd2 -= i;
+ bs2 -= i;
+ }
+ if (bb5 > 0) {
+ bs = pow5mult(bs, bb5);
+ bb1 = mult(bs, bb);
+ Bfree(bb);
+ bb = bb1;
+ }
+ if (bb2 > 0)
+ bb = lshift(bb, bb2);
+ if (bd5 > 0)
+ bd = pow5mult(bd, bd5);
+ if (bd2 > 0)
+ bd = lshift(bd, bd2);
+ if (bs2 > 0)
+ bs = lshift(bs, bs2);
+ delta = diff(bb, bd);
+ dsign = delta->sign;
+ delta->sign = 0;
+ i = cmp(delta, bs);
+ if (i < 0) {
+ /* Error is less than half an ulp -- check for
+ * special case of mantissa a power of two.
+ */
+ if (dsign || getWord1(rv) || getWord0(rv) & Bndry_mask)
+ break;
+ delta = lshift(delta,Log2P);
+ if (cmp(delta, bs) > 0)
+ goto drop_down;
+ break;
+ }
+ if (i == 0) {
+ /* exactly half-way between */
+ if (dsign) {
+ if ((getWord0(rv) & Bndry_mask1) == Bndry_mask1
+ && getWord1(rv) == 0xffffffff) {
+ /*boundary case -- increment exponent*/
+ setWord0(&rv, (getWord0(rv) & Exp_mask)
+ + Exp_msk1
+#ifdef IBM
+ | Exp_msk1 >> 4
+#endif
+ );
+ setWord1(&rv, 0);
+ break;
+ }
+ }
+ else if (!(getWord0(rv) & Bndry_mask) && !getWord1(rv)) {
+ drop_down:
+ /* boundary case -- decrement exponent */
+#ifdef Sudden_Underflow
+ L = getWord0(rv) & Exp_mask;
+#ifdef IBM
+ if (L < Exp_msk1)
+#else
+ if (L <= Exp_msk1)
+#endif
+ goto undfl;
+ L -= Exp_msk1;
+#else
+ L = (getWord0(rv) & Exp_mask) - Exp_msk1;
+#endif
+ setWord0(&rv, L | Bndry_mask1);
+ setWord1(&rv, 0xffffffff);
+#ifdef IBM
+ goto cont;
+#else
+ break;
+#endif
+ }
+#ifndef ROUND_BIASED
+ if (!(getWord1(rv) & LSB))
+ break;
+#endif
+ if (dsign)
+ rv += ulp(rv);
+#ifndef ROUND_BIASED
+ else {
+ rv -= ulp(rv);
+#ifndef Sudden_Underflow
+ if (rv == g_double_zero)
+ goto undfl;
+#endif
+ }
+#endif
+ break;
+ }
+ if ((aadj = ratio(delta, bs)) <= 2.) {
+ if (dsign)
+ aadj = aadj1 = 1.;
+ else if (getWord1(rv) || getWord0(rv) & Bndry_mask) {
+#ifndef Sudden_Underflow
+ if (getWord1(rv) == Tiny1 && !getWord0(rv))
+ goto undfl;
+#endif
+ aadj = 1.;
+ aadj1 = -1.;
+ }
+ else {
+ /* special case -- power of FLT_RADIX to be */
+ /* rounded down... */
+
+ if (aadj < 2./FLT_RADIX)
+ aadj = 1./FLT_RADIX;
+ else
+ aadj *= 0.5;
+ aadj1 = -aadj;
+ }
+ }
+ else {
+ aadj *= 0.5;
+ aadj1 = dsign ? aadj : -aadj;
+#ifdef Check_FLT_ROUNDS
+ switch(FLT_ROUNDS) {
+ case 2: /* towards +infinity */
+ aadj1 -= 0.5;
+ break;
+ case 0: /* towards 0 */
+ case 3: /* towards -infinity */
+ aadj1 += 0.5;
+ }
+#else
+ if (FLT_ROUNDS == 0)
+ aadj1 += 0.5;
+#endif
+ }
+ y = getWord0(rv) & Exp_mask;
+
+ /* Check for overflow */
+
+ if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) {
+ rv0 = rv;
+ setWord0(&rv, getWord0(rv) - P*Exp_msk1);
+ adj = aadj1 * ulp(rv);
+ rv += adj;
+ if ((getWord0(rv) & Exp_mask) >=
+ Exp_msk1*(DBL_MAX_EXP+Bias-P)) {
+ if (getWord0(rv0) == Big0 && getWord1(rv0) == Big1)
+ goto ovfl;
+ setWord0(&rv, Big0);
+ setWord1(&rv, Big1);
+ goto cont;
+ }
+ else
+ setWord0(&rv, getWord0(rv) + P*Exp_msk1);
+ }
+ else {
+#ifdef Sudden_Underflow
+ if ((getWord0(rv) & Exp_mask) <= P*Exp_msk1) {
+ rv0 = rv;
+ setWord0(&rv, getWord0(rv) + P*Exp_msk1);
+ adj = aadj1 * ulp(rv);
+ rv += adj;
+#ifdef IBM
+ if ((getWord0(rv) & Exp_mask) < P*Exp_msk1)
+#else
+ if ((getWord0(rv) & Exp_mask) <= P*Exp_msk1)
+#endif
+ {
+ if (getWord0(rv0) == Tiny0
+ && getWord1(rv0) == Tiny1)
+ goto undfl;
+ setWord0(&rv, Tiny0);
+ setWord1(&rv, Tiny1);
+ goto cont;
+ }
+ else
+ setWord0(&rv, getWord0(rv) - P*Exp_msk1);
+ }
+ else {
+ adj = aadj1 * ulp(rv);
+ rv += adj;
+ }
+#else
+ /* Compute adj so that the IEEE rounding rules will
+ * correctly round rv + adj in some half-way cases.
+ * If rv * ulp(rv) is denormalized (i.e.,
+ * y <= (P-1)*Exp_msk1), we must adjust aadj to avoid
+ * trouble from bits lost to denormalization;
+ * example: 1.2e-307 .
+ */
+ if (y <= (P-1)*Exp_msk1 && aadj >= 1.) {
+ aadj1 = int(aadj + 0.5);
+ if (!dsign)
+ aadj1 = -aadj1;
+ }
+ adj = aadj1 * ulp(rv);
+ rv += adj;
+#endif
+ }
+ z = getWord0(rv) & Exp_mask;
+ if (y == z) {
+ /* Can we stop now? */
+ L = Long(aadj);
+ aadj -= L;
+ /* The tolerances below are conservative. */
+ if (dsign || getWord1(rv) || getWord0(rv) & Bndry_mask) {
+ if (aadj < .4999999 || aadj > .5000001)
+ break;
+ }
+ else if (aadj < .4999999/FLT_RADIX)
+ break;
+ }
+ cont:
+ Bfree(bb);
+ Bfree(bd);
+ Bfree(bs);
+ Bfree(delta);
+ }
+ retfree:
+ Bfree(bb);
+ Bfree(bd);
+ Bfree(bs);
+ Bfree(bd0);
+ Bfree(delta);
+ ret:
+ if (se)
+ *se = s;
+ return sign ? -rv : rv;
+}
+
+static int quorem(Bigint *b, Bigint *S)
+{
+ int n;
+ Long borrow, y;
+ ULong carry, q, ys;
+ ULong *bx, *bxe, *sx, *sxe;
+#ifdef Pack_32
+ Long z;
+ ULong si, zs;
+#endif
+
+ n = S->wds;
+#ifdef BSD_QDTOA_DEBUG
+ /*debug*/ if (b->wds > n)
+ /*debug*/ Bug("oversize b in quorem");
+#endif
+ if (b->wds < n)
+ return 0;
+ sx = S->x;
+ sxe = sx + --n;
+ bx = b->x;
+ bxe = bx + n;
+ q = *bxe / (*sxe + 1); /* ensure q <= true quotient */
+#ifdef BSD_QDTOA_DEBUG
+ /*debug*/ if (q > 9)
+ /*debug*/ Bug("oversized quotient in quorem");
+#endif
+ if (q) {
+ borrow = 0;
+ carry = 0;
+ do {
+#ifdef Pack_32
+ si = *sx++;
+ ys = (si & 0xffff) * q + carry;
+ zs = (si >> 16) * q + (ys >> 16);
+ carry = zs >> 16;
+ y = (*bx & 0xffff) - (ys & 0xffff) + borrow;
+ borrow = y >> 16;
+ Sign_Extend(borrow, y);
+ z = (*bx >> 16) - (zs & 0xffff) + borrow;
+ borrow = z >> 16;
+ Sign_Extend(borrow, z);
+ Storeinc(bx, z, y);
+#else
+ ys = *sx++ * q + carry;
+ carry = ys >> 16;
+ y = *bx - (ys & 0xffff) + borrow;
+ borrow = y >> 16;
+ Sign_Extend(borrow, y);
+ *bx++ = y & 0xffff;
+#endif
+ }
+ while(sx <= sxe);
+ if (!*bxe) {
+ bx = b->x;
+ while(--bxe > bx && !*bxe)
+ --n;
+ b->wds = n;
+ }
+ }
+ if (cmp(b, S) >= 0) {
+ q++;
+ borrow = 0;
+ carry = 0;
+ bx = b->x;
+ sx = S->x;
+ do {
+#ifdef Pack_32
+ si = *sx++;
+ ys = (si & 0xffff) + carry;
+ zs = (si >> 16) + (ys >> 16);
+ carry = zs >> 16;
+ y = (*bx & 0xffff) - (ys & 0xffff) + borrow;
+ borrow = y >> 16;
+ Sign_Extend(borrow, y);
+ z = (*bx >> 16) - (zs & 0xffff) + borrow;
+ borrow = z >> 16;
+ Sign_Extend(borrow, z);
+ Storeinc(bx, z, y);
+#else
+ ys = *sx++ + carry;
+ carry = ys >> 16;
+ y = *bx - (ys & 0xffff) + borrow;
+ borrow = y >> 16;
+ Sign_Extend(borrow, y);
+ *bx++ = y & 0xffff;
+#endif
+ }
+ while(sx <= sxe);
+ bx = b->x;
+ bxe = bx + n;
+ if (!*bxe) {
+ while(--bxe > bx && !*bxe)
+ --n;
+ b->wds = n;
+ }
+ }
+ return q;
+}
+
+/* dtoa for IEEE arithmetic (dmg): convert double to ASCII string.
+ *
+ * Inspired by "How to Print Floating-Point Numbers Accurately" by
+ * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 92-101].
+ *
+ * Modifications:
+ * 1. Rather than iterating, we use a simple numeric overestimate
+ * to determine k = floor(log10(d)). We scale relevant
+ * quantities using O(log2(k)) rather than O(k) multiplications.
+ * 2. For some modes > 2 (corresponding to ecvt and fcvt), we don't
+ * try to generate digits strictly left to right. Instead, we
+ * compute with fewer bits and propagate the carry if necessary
+ * when rounding the final digit up. This is often faster.
+ * 3. Under the assumption that input will be rounded nearest,
+ * mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22.
+ * That is, we allow equality in stopping tests when the
+ * round-nearest rule will give the same floating-point value
+ * as would satisfaction of the stopping test with strict
+ * inequality.
+ * 4. We remove common factors of powers of 2 from relevant
+ * quantities.
+ * 5. When converting floating-point integers less than 1e16,
+ * we use floating-point arithmetic rather than resorting
+ * to multiple-precision integers.
+ * 6. When asked to produce fewer than 15 digits, we first try
+ * to get by with floating-point arithmetic; we resort to
+ * multiple-precision integer arithmetic only if we cannot
+ * guarantee that the floating-point calculation has given
+ * the correctly rounded result. For k requested digits and
+ * "uniformly" distributed input, the probability is
+ * something like 10^(k-15) that we must resort to the Long
+ * calculation.
+ */
+
+
+/* This actually sometimes returns a pointer to a string literal
+ cast to a char*. Do NOT try to modify the return value. */
+
+Q_CORE_EXPORT char *qdtoa ( double d, int mode, int ndigits, int *decpt, int *sign, char **rve, char **resultp)
+{
+ // Some values of the floating-point control word can cause _qdtoa to crash with an underflow.
+ // We set a safe value here.
+#ifdef Q_OS_WIN
+ _clear87();
+ unsigned int oldbits = _control87(0, 0);
+#ifndef MCW_EM
+# ifdef _MCW_EM
+# define MCW_EM _MCW_EM
+# else
+# define MCW_EM 0x0008001F
+# endif
+#endif
+ _control87(MCW_EM, MCW_EM);
+#endif
+
+#if defined(Q_OS_LINUX) && !defined(__UCLIBC__)
+ fenv_t envp;
+ feholdexcept(&envp);
+#endif
+
+ char *s = _qdtoa(d, mode, ndigits, decpt, sign, rve, resultp);
+
+#ifdef Q_OS_WIN
+ _clear87();
+#ifndef _M_X64
+ _control87(oldbits, 0xFFFFF);
+#else
+ _control87(oldbits, _MCW_EM|_MCW_DN|_MCW_RC);
+#endif //_M_X64
+#endif //Q_OS_WIN
+
+#if defined(Q_OS_LINUX) && !defined(__UCLIBC__)
+ fesetenv(&envp);
+#endif
+
+ return s;
+}
+
+static char *_qdtoa( NEEDS_VOLATILE double d, int mode, int ndigits, int *decpt, int *sign, char **rve, char **resultp)
+{
+ /*
+ Arguments ndigits, decpt, sign are similar to those
+ of ecvt and fcvt; trailing zeros are suppressed from
+ the returned string. If not null, *rve is set to point
+ to the end of the return value. If d is +-Infinity or NaN,
+ then *decpt is set to 9999.
+
+ mode:
+ 0 ==> shortest string that yields d when read in
+ and rounded to nearest.
+ 1 ==> like 0, but with Steele & White stopping rule;
+ e.g. with IEEE P754 arithmetic , mode 0 gives
+ 1e23 whereas mode 1 gives 9.999999999999999e22.
+ 2 ==> max(1,ndigits) significant digits. This gives a
+ return value similar to that of ecvt, except
+ that trailing zeros are suppressed.
+ 3 ==> through ndigits past the decimal point. This
+ gives a return value similar to that from fcvt,
+ except that trailing zeros are suppressed, and
+ ndigits can be negative.
+ 4-9 should give the same return values as 2-3, i.e.,
+ 4 <= mode <= 9 ==> same return as mode
+ 2 + (mode & 1). These modes are mainly for
+ debugging; often they run slower but sometimes
+ faster than modes 2-3.
+ 4,5,8,9 ==> left-to-right digit generation.
+ 6-9 ==> don't try fast floating-point estimate
+ (if applicable).
+
+ Values of mode other than 0-9 are treated as mode 0.
+
+ Sufficient space is allocated to the return value
+ to hold the suppressed trailing zeros.
+ */
+
+ int bbits, b2, b5, be, dig, i, ieps, ilim0,
+ j, j1, k, k0, k_check, leftright, m2, m5, s2, s5,
+ try_quick;
+ int ilim = 0, ilim1 = 0, spec_case = 0; /* pacify gcc */
+ Long L;
+#ifndef Sudden_Underflow
+ int denorm;
+ ULong x;
+#endif
+ Bigint *b, *b1, *delta, *mhi, *S;
+ Bigint *mlo = NULL; /* pacify gcc */
+ double d2;
+ double ds, eps;
+ char *s, *s0;
+
+ if (getWord0(d) & Sign_bit) {
+ /* set sign for everything, including 0's and NaNs */
+ *sign = 1;
+ setWord0(&d, getWord0(d) & ~Sign_bit); /* clear sign bit */
+ }
+ else
+ *sign = 0;
+
+#if defined(IEEE_Arith) + defined(VAX)
+#ifdef IEEE_Arith
+ if ((getWord0(d) & Exp_mask) == Exp_mask)
+#else
+ if (getWord0(d) == 0x8000)
+#endif
+ {
+ /* Infinity or NaN */
+ *decpt = 9999;
+ s =
+#ifdef IEEE_Arith
+ !getWord1(d) && !(getWord0(d) & 0xfffff) ? const_cast<char*>("Infinity") :
+#endif
+ const_cast<char*>("NaN");
+ if (rve)
+ *rve =
+#ifdef IEEE_Arith
+ s[3] ? s + 8 :
+#endif
+ s + 3;
+ return s;
+ }
+#endif
+#ifdef IBM
+ d += 0; /* normalize */
+#endif
+ if (d == g_double_zero)
+ {
+ *decpt = 1;
+ s = const_cast<char*>("0");
+ if (rve)
+ *rve = s + 1;
+ return s;
+ }
+
+ b = d2b(d, &be, &bbits);
+#ifdef Sudden_Underflow
+ i = (int)(getWord0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1));
+#else
+ if ((i = int(getWord0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1))) != 0) {
+#endif
+ d2 = d;
+ setWord0(&d2, getWord0(d2) & Frac_mask1);
+ setWord0(&d2, getWord0(d2) | Exp_11);
+#ifdef IBM
+ if (j = 11 - hi0bits(getWord0(d2) & Frac_mask))
+ d2 /= 1 << j;
+#endif
+
+ /* log(x) ~=~ log(1.5) + (x-1.5)/1.5
+ * log10(x) = log(x) / log(10)
+ * ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10))
+ * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2)
+ *
+ * This suggests computing an approximation k to log10(d) by
+ *
+ * k = (i - Bias)*0.301029995663981
+ * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 );
+ *
+ * We want k to be too large rather than too small.
+ * The error in the first-order Taylor series approximation
+ * is in our favor, so we just round up the constant enough
+ * to compensate for any error in the multiplication of
+ * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077,
+ * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14,
+ * adding 1e-13 to the constant term more than suffices.
+ * Hence we adjust the constant term to 0.1760912590558.
+ * (We could get a more accurate k by invoking log10,
+ * but this is probably not worthwhile.)
+ */
+
+ i -= Bias;
+#ifdef IBM
+ i <<= 2;
+ i += j;
+#endif
+#ifndef Sudden_Underflow
+ denorm = 0;
+ }
+ else {
+ /* d is denormalized */
+
+ i = bbits + be + (Bias + (P-1) - 1);
+ x = i > 32 ? getWord0(d) << (64 - i) | getWord1(d) >> (i - 32)
+ : getWord1(d) << (32 - i);
+ d2 = x;
+ setWord0(&d2, getWord0(d2) - 31*Exp_msk1); /* adjust exponent */
+ i -= (Bias + (P-1) - 1) + 1;
+ denorm = 1;
+ }
+#endif
+ ds = (d2-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981;
+ k = int(ds);
+ if (ds < 0. && ds != k)
+ k--; /* want k = floor(ds) */
+ k_check = 1;
+ if (k >= 0 && k <= Ten_pmax) {
+ if (d < tens[k])
+ k--;
+ k_check = 0;
+ }
+ j = bbits - i - 1;
+ if (j >= 0) {
+ b2 = 0;
+ s2 = j;
+ }
+ else {
+ b2 = -j;
+ s2 = 0;
+ }
+ if (k >= 0) {
+ b5 = 0;
+ s5 = k;
+ s2 += k;
+ }
+ else {
+ b2 -= k;
+ b5 = -k;
+ s5 = 0;
+ }
+ if (mode < 0 || mode > 9)
+ mode = 0;
+ try_quick = 1;
+ if (mode > 5) {
+ mode -= 4;
+ try_quick = 0;
+ }
+ leftright = 1;
+ switch(mode) {
+ case 0:
+ case 1:
+ ilim = ilim1 = -1;
+ i = 18;
+ ndigits = 0;
+ break;
+ case 2:
+ leftright = 0;
+ /* no break */
+ case 4:
+ if (ndigits <= 0)
+ ndigits = 1;
+ ilim = ilim1 = i = ndigits;
+ break;
+ case 3:
+ leftright = 0;
+ /* no break */
+ case 5:
+ i = ndigits + k + 1;
+ ilim = i;
+ ilim1 = i - 1;
+ if (i <= 0)
+ i = 1;
+ }
+ *resultp = static_cast<char *>(malloc(i + 1));
+ s = s0 = *resultp;
+
+ if (ilim >= 0 && ilim <= Quick_max && try_quick) {
+
+ /* Try to get by with floating-point arithmetic. */
+
+ i = 0;
+ d2 = d;
+ k0 = k;
+ ilim0 = ilim;
+ ieps = 2; /* conservative */
+ if (k > 0) {
+ ds = tens[k&0xf];
+ j = k >> 4;
+ if (j & Bletch) {
+ /* prevent overflows */
+ j &= Bletch - 1;
+ d /= bigtens[n_bigtens-1];
+ ieps++;
+ }
+ for(; j; j >>= 1, i++)
+ if (j & 1) {
+ ieps++;
+ ds *= bigtens[i];
+ }
+ d /= ds;
+ }
+ else if ((j1 = -k) != 0) {
+ d *= tens[j1 & 0xf];
+ for(j = j1 >> 4; j; j >>= 1, i++)
+ if (j & 1) {
+ ieps++;
+ d *= bigtens[i];
+ }
+ }
+ if (k_check && d < 1. && ilim > 0) {
+ if (ilim1 <= 0)
+ goto fast_failed;
+ ilim = ilim1;
+ k--;
+ d *= 10.;
+ ieps++;
+ }
+ eps = ieps*d + 7.;
+ setWord0(&eps, getWord0(eps) - (P-1)*Exp_msk1);
+ if (ilim == 0) {
+ S = mhi = 0;
+ d -= 5.;
+ if (d > eps)
+ goto one_digit;
+ if (d < -eps)
+ goto no_digits;
+ goto fast_failed;
+ }
+#ifndef No_leftright
+ if (leftright) {
+ /* Use Steele & White method of only
+ * generating digits needed.
+ */
+ eps = 0.5/tens[ilim-1] - eps;
+ for(i = 0;;) {
+ L = Long(d);
+ d -= L;
+ *s++ = '0' + int(L);
+ if (d < eps)
+ goto ret1;
+ if (1. - d < eps)
+ goto bump_up;
+ if (++i >= ilim)
+ break;
+ eps *= 10.;
+ d *= 10.;
+ }
+ }
+ else {
+#endif
+ /* Generate ilim digits, then fix them up. */
+#if defined(Q_OS_IRIX) && defined(Q_CC_GNU)
+ // work around a bug on 64 bit IRIX gcc
+ double *t = (double *) tens;
+ eps *= t[ilim-1];
+#else
+ eps *= tens[ilim-1];
+#endif
+ for(i = 1;; i++, d *= 10.) {
+ L = Long(d);
+ d -= L;
+ *s++ = '0' + int(L);
+ if (i == ilim) {
+ if (d > 0.5 + eps)
+ goto bump_up;
+ else if (d < 0.5 - eps) {
+ while(*--s == '0') {}
+ s++;
+ goto ret1;
+ }
+ break;
+ }
+ }
+#ifndef No_leftright
+ }
+#endif
+ fast_failed:
+ s = s0;
+ d = d2;
+ k = k0;
+ ilim = ilim0;
+ }
+
+ /* Do we have a "small" integer? */
+
+ if (be >= 0 && k <= Int_max) {
+ /* Yes. */
+ ds = tens[k];
+ if (ndigits < 0 && ilim <= 0) {
+ S = mhi = 0;
+ if (ilim < 0 || d <= 5*ds)
+ goto no_digits;
+ goto one_digit;
+ }
+ for(i = 1;; i++) {
+ L = Long(d / ds);
+ d -= L*ds;
+#ifdef Check_FLT_ROUNDS
+ /* If FLT_ROUNDS == 2, L will usually be high by 1 */
+ if (d < 0) {
+ L--;
+ d += ds;
+ }
+#endif
+ *s++ = '0' + int(L);
+ if (i == ilim) {
+ d += d;
+ if (d > ds || (d == ds && L & 1)) {
+ bump_up:
+ while(*--s == '9')
+ if (s == s0) {
+ k++;
+ *s = '0';
+ break;
+ }
+ ++*s++;
+ }
+ break;
+ }
+ if ((d *= 10.) == g_double_zero)
+ break;
+ }
+ goto ret1;
+ }
+
+ m2 = b2;
+ m5 = b5;
+ mhi = mlo = 0;
+ if (leftright) {
+ if (mode < 2) {
+ i =
+#ifndef Sudden_Underflow
+ denorm ? be + (Bias + (P-1) - 1 + 1) :
+#endif
+#ifdef IBM
+ 1 + 4*P - 3 - bbits + ((bbits + be - 1) & 3);
+#else
+ 1 + P - bbits;
+#endif
+ }
+ else {
+ j = ilim - 1;
+ if (m5 >= j)
+ m5 -= j;
+ else {
+ s5 += j -= m5;
+ b5 += j;
+ m5 = 0;
+ }
+ if ((i = ilim) < 0) {
+ m2 -= i;
+ i = 0;
+ }
+ }
+ b2 += i;
+ s2 += i;
+ mhi = i2b(1);
+ }
+ if (m2 > 0 && s2 > 0) {
+ i = m2 < s2 ? m2 : s2;
+ b2 -= i;
+ m2 -= i;
+ s2 -= i;
+ }
+ if (b5 > 0) {
+ if (leftright) {
+ if (m5 > 0) {
+ mhi = pow5mult(mhi, m5);
+ b1 = mult(mhi, b);
+ Bfree(b);
+ b = b1;
+ }
+ if ((j = b5 - m5) != 0)
+ b = pow5mult(b, j);
+ }
+ else
+ b = pow5mult(b, b5);
+ }
+ S = i2b(1);
+ if (s5 > 0)
+ S = pow5mult(S, s5);
+
+ /* Check for special case that d is a normalized power of 2. */
+
+ if (mode < 2) {
+ if (!getWord1(d) && !(getWord0(d) & Bndry_mask)
+#ifndef Sudden_Underflow
+ && getWord0(d) & Exp_mask
+#endif
+ ) {
+ /* The special case */
+ b2 += Log2P;
+ s2 += Log2P;
+ spec_case = 1;
+ }
+ else
+ spec_case = 0;
+ }
+
+ /* Arrange for convenient computation of quotients:
+ * shift left if necessary so divisor has 4 leading 0 bits.
+ *
+ * Perhaps we should just compute leading 28 bits of S once
+ * and for all and pass them and a shift to quorem, so it
+ * can do shifts and ors to compute the numerator for q.
+ */
+#ifdef Pack_32
+ if ((i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0x1f) != 0)
+ i = 32 - i;
+#else
+ if (i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0xf)
+ i = 16 - i;
+#endif
+ if (i > 4) {
+ i -= 4;
+ b2 += i;
+ m2 += i;
+ s2 += i;
+ }
+ else if (i < 4) {
+ i += 28;
+ b2 += i;
+ m2 += i;
+ s2 += i;
+ }
+ if (b2 > 0)
+ b = lshift(b, b2);
+ if (s2 > 0)
+ S = lshift(S, s2);
+ if (k_check) {
+ if (cmp(b,S) < 0) {
+ k--;
+ b = multadd(b, 10, 0); /* we botched the k estimate */
+ if (leftright)
+ mhi = multadd(mhi, 10, 0);
+ ilim = ilim1;
+ }
+ }
+ if (ilim <= 0 && mode > 2) {
+ if (ilim < 0 || cmp(b,S = multadd(S,5,0)) <= 0) {
+ /* no digits, fcvt style */
+ no_digits:
+ k = -1 - ndigits;
+ goto ret;
+ }
+ one_digit:
+ *s++ = '1';
+ k++;
+ goto ret;
+ }
+ if (leftright) {
+ if (m2 > 0)
+ mhi = lshift(mhi, m2);
+
+ /* Compute mlo -- check for special case
+ * that d is a normalized power of 2.
+ */
+
+ mlo = mhi;
+ if (spec_case) {
+ mhi = Balloc(mhi->k);
+ Bcopy(mhi, mlo);
+ mhi = lshift(mhi, Log2P);
+ }
+
+ for(i = 1;;i++) {
+ dig = quorem(b,S) + '0';
+ /* Do we yet have the shortest decimal string
+ * that will round to d?
+ */
+ j = cmp(b, mlo);
+ delta = diff(S, mhi);
+ j1 = delta->sign ? 1 : cmp(b, delta);
+ Bfree(delta);
+#ifndef ROUND_BIASED
+ if (j1 == 0 && !mode && !(getWord1(d) & 1)) {
+ if (dig == '9')
+ goto round_9_up;
+ if (j > 0)
+ dig++;
+ *s++ = dig;
+ goto ret;
+ }
+#endif
+ if (j < 0 || (j == 0 && !mode
+#ifndef ROUND_BIASED
+ && !(getWord1(d) & 1)
+#endif
+ )) {
+ if (j1 > 0) {
+ b = lshift(b, 1);
+ j1 = cmp(b, S);
+ if ((j1 > 0 || (j1 == 0 && dig & 1))
+ && dig++ == '9')
+ goto round_9_up;
+ }
+ *s++ = dig;
+ goto ret;
+ }
+ if (j1 > 0) {
+ if (dig == '9') { /* possible if i == 1 */
+ round_9_up:
+ *s++ = '9';
+ goto roundoff;
+ }
+ *s++ = dig + 1;
+ goto ret;
+ }
+ *s++ = dig;
+ if (i == ilim)
+ break;
+ b = multadd(b, 10, 0);
+ if (mlo == mhi)
+ mlo = mhi = multadd(mhi, 10, 0);
+ else {
+ mlo = multadd(mlo, 10, 0);
+ mhi = multadd(mhi, 10, 0);
+ }
+ }
+ }
+ else
+ for(i = 1;; i++) {
+ *s++ = dig = quorem(b,S) + '0';
+ if (i >= ilim)
+ break;
+ b = multadd(b, 10, 0);
+ }
+
+ /* Round off last digit */
+
+ b = lshift(b, 1);
+ j = cmp(b, S);
+ if (j > 0 || (j == 0 && dig & 1)) {
+ roundoff:
+ while(*--s == '9')
+ if (s == s0) {
+ k++;
+ *s++ = '1';
+ goto ret;
+ }
+ ++*s++;
+ }
+ else {
+ while(*--s == '0') {}
+ s++;
+ }
+ ret:
+ Bfree(S);
+ if (mhi) {
+ if (mlo && mlo != mhi)
+ Bfree(mlo);
+ Bfree(mhi);
+ }
+ ret1:
+ Bfree(b);
+ if (s == s0) { /* don't return empty string */
+ *s++ = '0';
+ k = 0;
+ }
+ *s = 0;
+ *decpt = k + 1;
+ if (rve)
+ *rve = s;
+ return s0;
+}
+#else
+// NOT thread safe!
+
+#include <errno.h>
+
+Q_CORE_EXPORT char *qdtoa( double d, int mode, int ndigits, int *decpt, int *sign, char **rve, char **resultp)
+{
+ if(rve)
+ *rve = 0;
+
+ char *res;
+ if (mode == 0)
+ ndigits = 80;
+
+ if (mode == 3)
+ res = fcvt(d, ndigits, decpt, sign);
+ else
+ res = ecvt(d, ndigits, decpt, sign);
+
+ int n = qstrlen(res);
+ if (mode == 0) { // remove trailing 0's
+ const int stop = qMax(1, *decpt);
+ int i;
+ for (i = n-1; i >= stop; --i) {
+ if (res[i] != '0')
+ break;
+ }
+ n = i + 1;
+ }
+ *resultp = static_cast<char*>(malloc(n + 1));
+ qstrncpy(*resultp, res, n + 1);
+ return *resultp;
+}
+
+Q_CORE_EXPORT double qstrtod(const char *s00, const char **se, bool *ok)
+{
+ double ret = strtod((char*)s00, (char**)se);
+ if (ok) {
+ if((ret == 0.0l && errno == ERANGE)
+ || ret == HUGE_VAL || ret == -HUGE_VAL)
+ *ok = false;
+ else
+ *ok = true; // the result will be that we don't report underflow in this case
+ }
+ return ret;
+}
+#endif // QT_QLOCALE_USES_FCVT
+
+QT_END_NAMESPACE
diff --git a/src/corelib/tools/qlocale.h b/src/corelib/tools/qlocale.h
new file mode 100644
index 0000000000..5b611eb831
--- /dev/null
+++ b/src/corelib/tools/qlocale.h
@@ -0,0 +1,678 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QLOCALE_H
+#define QLOCALE_H
+
+#include <QtCore/qstring.h>
+#include <QtCore/qobjectdefs.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Core)
+
+class QDataStream;
+class QDate;
+class QDateTime;
+class QTime;
+class QVariant;
+class QTextStream;
+class QTextStreamPrivate;
+
+class QLocale;
+
+#ifndef QT_NO_SYSTEMLOCALE
+class Q_CORE_EXPORT QSystemLocale
+{
+public:
+ QSystemLocale();
+ virtual ~QSystemLocale();
+
+ enum QueryType {
+ LanguageId, // uint
+ CountryId, // uint
+ DecimalPoint, // QString
+ GroupSeparator, // QString
+ ZeroDigit, // QString
+ NegativeSign, // QString
+ DateFormatLong, // QString
+ DateFormatShort, // QString
+ TimeFormatLong, // QString
+ TimeFormatShort, // QString
+ DayNameLong, // QString, in: int
+ DayNameShort, // QString, in: int
+ MonthNameLong, // QString, in: int
+ MonthNameShort, // QString, in: int
+ DateToStringLong, // QString, in: QDate
+ DateToStringShort, // QString in: QDate
+ TimeToStringLong, // QString in: QTime
+ TimeToStringShort, // QString in: QTime
+ DateTimeFormatLong, // QString
+ DateTimeFormatShort, // QString
+ DateTimeToStringLong, // QString in: QDateTime
+ DateTimeToStringShort, // QString in: QDateTime
+ MeasurementSystem, // uint
+ PositiveSign, // QString
+ AMText, // QString
+ PMText // QString
+ };
+ virtual QVariant query(QueryType type, QVariant in) const;
+ virtual QLocale fallbackLocale() const;
+
+#ifdef QLOCALE_CPP
+private:
+ QSystemLocale(bool);
+ friend QSystemLocale *QSystemLocale_globalSystemLocale();
+#endif
+};
+#endif
+
+struct QLocalePrivate;
+class Q_CORE_EXPORT QLocale
+{
+ Q_GADGET
+ Q_ENUMS(Language)
+ Q_ENUMS(Country)
+ friend class QString;
+ friend class QByteArray;
+ friend class QIntValidator;
+ friend class QDoubleValidator;
+ friend class QTextStream;
+ friend class QTextStreamPrivate;
+
+public:
+ enum Language {
+ C = 1,
+ Abkhazian = 2,
+ Afan = 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,
+ Bhutani = 16,
+ Bihari = 17,
+ Bislama = 18,
+ Breton = 19,
+ Bulgarian = 20,
+ Burmese = 21,
+ Byelorussian = 22,
+ Cambodian = 23,
+ Catalan = 24,
+ Chinese = 25,
+ Corsican = 26,
+ Croatian = 27,
+ Czech = 28,
+ Danish = 29,
+ Dutch = 30,
+ English = 31,
+ Esperanto = 32,
+ Estonian = 33,
+ Faroese = 34,
+ FijiLanguage = 35,
+ Finnish = 36,
+ French = 37,
+ Frisian = 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,
+ Kurundi = 68,
+ Laothian = 69,
+ Latin = 70,
+ Latvian = 71,
+ Lingala = 72,
+ Lithuanian = 73,
+ Macedonian = 74,
+ Malagasy = 75,
+ Malay = 76,
+ Malayalam = 77,
+ Maltese = 78,
+ Maori = 79,
+ Marathi = 80,
+ Moldavian = 81,
+ Mongolian = 82,
+ NauruLanguage = 83,
+ Nepali = 84,
+ Norwegian = 85,
+ NorwegianBokmal = Norwegian,
+ Occitan = 86,
+ Oriya = 87,
+ Pashto = 88,
+ Persian = 89,
+ Polish = 90,
+ Portuguese = 91,
+ Punjabi = 92,
+ Quechua = 93,
+ RhaetoRomance = 94,
+ Romanian = 95,
+ Russian = 96,
+ Samoan = 97,
+ Sangho = 98,
+ Sanskrit = 99,
+ Serbian = 100,
+ SerboCroatian = 101,
+ Sesotho = 102,
+ Setswana = 103,
+ Shona = 104,
+ Sindhi = 105,
+ Singhalese = 106,
+ Siswati = 107,
+ Slovak = 108,
+ Slovenian = 109,
+ Somali = 110,
+ Spanish = 111,
+ Sundanese = 112,
+ Swahili = 113,
+ Swedish = 114,
+ Tagalog = 115,
+ Tajik = 116,
+ Tamil = 117,
+ Tatar = 118,
+ Telugu = 119,
+ Thai = 120,
+ Tibetan = 121,
+ Tigrinya = 122,
+ TongaLanguage = 123,
+ Tsonga = 124,
+ Turkish = 125,
+ Turkmen = 126,
+ Twi = 127,
+ Uigur = 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,
+ Nynorsk = NorwegianNynorsk, // ### obsolete
+ 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,
+ Chewa = 165,
+ LastLanguage = Chewa
+ };
+
+ 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,
+ BruneiDarussalam = 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,
+ DemocraticRepublicOfCongo = 49,
+ PeoplesRepublicOfCongo = 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,
+ FijiCountry = 72,
+ Finland = 73,
+ France = 74,
+ MetropolitanFrance = 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,
+ DemocraticRepublicOfKorea = 113,
+ RepublicOfKorea = 114,
+ Kuwait = 115,
+ Kyrgyzstan = 116,
+ Lao = 117,
+ Latvia = 118,
+ Lebanon = 119,
+ Lesotho = 120,
+ Liberia = 121,
+ LibyanArabJamahiriya = 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,
+ NetherlandsAntilles = 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,
+ PalestinianTerritory = 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,
+ RussianFederation = 178,
+ Rwanda = 179,
+ SaintKittsAndNevis = 180,
+ StLucia = 181,
+ StVincentAndTheGrenadines = 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,
+ StHelena = 199,
+ StPierreAndMiquelon = 200,
+ Sudan = 201,
+ Suriname = 202,
+ SvalbardAndJanMayenIslands = 203,
+ Swaziland = 204,
+ Sweden = 205,
+ Switzerland = 206,
+ SyrianArabRepublic = 207,
+ Taiwan = 208,
+ Tajikistan = 209,
+ Tanzania = 210,
+ Thailand = 211,
+ Togo = 212,
+ Tokelau = 213,
+ TongaCountry = 214,
+ TrinidadAndTobago = 215,
+ Tunisia = 216,
+ Turkey = 217,
+ Turkmenistan = 218,
+ TurksAndCaicosIslands = 219,
+ Tuvalu = 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,
+ USVirginIslands = 234,
+ WallisAndFutunaIslands = 235,
+ WesternSahara = 236,
+ Yemen = 237,
+ Yugoslavia = 238,
+ Zambia = 239,
+ Zimbabwe = 240,
+ SerbiaAndMontenegro = 241,
+ LastCountry = SerbiaAndMontenegro
+ };
+
+ enum MeasurementSystem { MetricSystem, ImperialSystem };
+
+ enum FormatType { LongFormat, ShortFormat, NarrowFormat };
+ enum NumberOption {
+ OmitGroupSeparator = 0x01,
+ RejectGroupSeparator = 0x02
+ };
+ Q_DECLARE_FLAGS(NumberOptions, NumberOption)
+
+ QLocale();
+ QLocale(const QString &name);
+ QLocale(Language language, Country country = AnyCountry);
+ QLocale(const QLocale &other);
+
+ QLocale &operator=(const QLocale &other);
+
+ Language language() const;
+ Country country() const;
+ QString name() const;
+
+ short toShort(const QString &s, bool *ok = 0, int base = 0) const;
+ ushort toUShort(const QString &s, bool *ok = 0, int base = 0) const;
+ int toInt(const QString &s, bool *ok = 0, int base = 0) const;
+ uint toUInt(const QString &s, bool *ok = 0, int base = 0) const;
+ qlonglong toLongLong(const QString &s, bool *ok = 0, int base = 0) const;
+ qlonglong toULongLong(const QString &s, bool *ok = 0, int base = 0) const;
+ float toFloat(const QString &s, bool *ok = 0) const;
+ double toDouble(const QString &s, bool *ok = 0) const;
+
+ QString toString(qlonglong i) const;
+ QString toString(qulonglong 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;
+ QString toString(const QDate &date, const QString &formatStr) const;
+ QString toString(const QDate &date, FormatType format = LongFormat) const;
+ QString toString(const QTime &time, const QString &formatStr) const;
+ QString toString(const QTime &time, FormatType format = LongFormat) const;
+ QString toString(const QDateTime &dateTime, FormatType format = LongFormat) const;
+ QString toString(const QDateTime &dateTime, const QString &format) const;
+
+ QString dateFormat(FormatType format = LongFormat) const;
+ QString timeFormat(FormatType format = LongFormat) const;
+ QString dateTimeFormat(FormatType format = LongFormat) const;
+#ifndef QT_NO_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;
+
+ QString amText() const;
+ QString pmText() const;
+
+ MeasurementSystem measurementSystem() const;
+
+ inline bool operator==(const QLocale &other) const;
+ inline bool operator!=(const QLocale &other) const;
+
+ static QString languageToString(Language language);
+ static QString countryToString(Country country);
+ static void setDefault(const QLocale &locale);
+
+ static QLocale c() { return QLocale(C); }
+ static QLocale system();
+
+ static QList<Country> countriesForLanguage(Language lang);
+
+ void setNumberOptions(NumberOptions options);
+ NumberOptions numberOptions() const;
+
+//private: // this should be private, but can't be
+ struct Data {
+ quint16 index;
+ quint16 numberOptions;
+ }
+#if (defined(__arm__) || defined(__ARMEL__))
+ Q_PACKED
+#endif
+ ;
+private:
+ friend struct QLocalePrivate;
+ // ### We now use this field to pack an index into locale_data and NumberOptions.
+ // ### Qt 5: change to a QLocaleData *d; uint numberOptions.
+ union {
+ void *v;
+ Data p;
+ };
+ const QLocalePrivate *d() const;
+};
+Q_DECLARE_TYPEINFO(QLocale, Q_MOVABLE_TYPE);
+Q_DECLARE_OPERATORS_FOR_FLAGS(QLocale::NumberOptions)
+
+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 bool QLocale::operator==(const QLocale &other) const
+ { return d() == other.d() && numberOptions() == other.numberOptions(); }
+inline bool QLocale::operator!=(const QLocale &other) const
+ { return d() != other.d() || numberOptions() != other.numberOptions(); }
+
+#ifndef QT_NO_DATASTREAM
+Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QLocale &);
+Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QLocale &);
+#endif
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QLOCALE_H
diff --git a/src/corelib/tools/qlocale_data_p.h b/src/corelib/tools/qlocale_data_p.h
new file mode 100644
index 0000000000..37f59a421a
--- /dev/null
+++ b/src/corelib/tools/qlocale_data_p.h
@@ -0,0 +1,3391 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $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.
+//
+
+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
+{
+ quint32 languageId;
+ quint32 countryId;
+};
+static const CountryLanguage ImperialMeasurementSystems[] = {
+ { 31, 225 },
+ { 31, 226 },
+ { 111, 225 },
+ { 163, 225 }
+};
+static const int ImperialMeasurementSystemsCount =
+ sizeof(ImperialMeasurementSystems)/sizeof(ImperialMeasurementSystems[0]);
+
+/*
+ This part of the file was generated on 2008-08-07 from the
+ Common Locale Data Repository v1.6.1
+
+ http://www.unicode.org/cldr/
+
+ Do not change it, instead edit $QTDIR/util/locale_database/locale.xml and run
+ qlocalexml2cpp.py.
+*/
+
+
+static const uint locale_index[] = {
+ 0, // unused
+ 0, // C
+ 0, // Abkhazian
+ 1, // Afan
+ 3, // Afar
+ 6, // Afrikaans
+ 8, // Albanian
+ 9, // Amharic
+ 10, // Arabic
+ 27, // Armenian
+ 28, // Assamese
+ 0, // Aymara
+ 29, // Azerbaijani
+ 0, // Bashkir
+ 30, // Basque
+ 31, // Bengali
+ 33, // Bhutani
+ 0, // Bihari
+ 0, // Bislama
+ 0, // Breton
+ 34, // Bulgarian
+ 35, // Burmese
+ 36, // Byelorussian
+ 37, // Cambodian
+ 38, // Catalan
+ 39, // Chinese
+ 0, // Corsican
+ 44, // Croatian
+ 45, // Czech
+ 46, // Danish
+ 47, // Dutch
+ 49, // English
+ 0, // Esperanto
+ 75, // Estonian
+ 76, // Faroese
+ 0, // Fiji
+ 77, // Finnish
+ 78, // French
+ 0, // Frisian
+ 0, // Gaelic
+ 85, // Galician
+ 86, // Georgian
+ 87, // German
+ 93, // Greek
+ 95, // Greenlandic
+ 0, // Guarani
+ 96, // Gujarati
+ 97, // Hausa
+ 101, // Hebrew
+ 102, // Hindi
+ 103, // Hungarian
+ 104, // Icelandic
+ 105, // Indonesian
+ 0, // Interlingua
+ 0, // Interlingue
+ 0, // Inuktitut
+ 0, // Inupiak
+ 106, // Irish
+ 107, // Italian
+ 109, // Japanese
+ 0, // Javanese
+ 110, // Kannada
+ 0, // Kashmiri
+ 111, // Kazakh
+ 112, // Kinyarwanda
+ 113, // Kirghiz
+ 114, // Korean
+ 115, // Kurdish
+ 0, // Kurundi
+ 116, // Laothian
+ 0, // Latin
+ 117, // Latvian
+ 118, // Lingala
+ 120, // Lithuanian
+ 121, // Macedonian
+ 0, // Malagasy
+ 122, // Malay
+ 124, // Malayalam
+ 125, // Maltese
+ 0, // Maori
+ 126, // Marathi
+ 0, // Moldavian
+ 127, // Mongolian
+ 0, // Nauru
+ 129, // Nepali
+ 131, // Norwegian
+ 0, // Occitan
+ 132, // Oriya
+ 133, // Pashto
+ 134, // Persian
+ 136, // Polish
+ 137, // Portuguese
+ 139, // Punjabi
+ 0, // Quechua
+ 0, // RhaetoRomance
+ 141, // Romanian
+ 143, // Russian
+ 0, // Samoan
+ 0, // Sangho
+ 145, // Sanskrit
+ 146, // Serbian
+ 149, // SerboCroatian
+ 152, // Sesotho
+ 154, // Setswana
+ 0, // Shona
+ 0, // Sindhi
+ 155, // Singhalese
+ 156, // Siswati
+ 158, // Slovak
+ 159, // Slovenian
+ 160, // Somali
+ 164, // Spanish
+ 0, // Sundanese
+ 184, // Swahili
+ 186, // Swedish
+ 0, // Tagalog
+ 188, // Tajik
+ 189, // Tamil
+ 190, // Tatar
+ 191, // Telugu
+ 192, // Thai
+ 0, // Tibetan
+ 193, // Tigrinya
+ 195, // Tonga
+ 196, // Tsonga
+ 197, // Turkish
+ 0, // Turkmen
+ 0, // Twi
+ 198, // Uigur
+ 199, // Ukrainian
+ 200, // Urdu
+ 202, // Uzbek
+ 204, // Vietnamese
+ 0, // Volapuk
+ 205, // Welsh
+ 206, // Wolof
+ 207, // Xhosa
+ 0, // Yiddish
+ 208, // Yoruba
+ 0, // Zhuang
+ 209, // Zulu
+ 210, // Nynorsk
+ 211, // Bosnian
+ 212, // Divehi
+ 213, // Manx
+ 214, // Cornish
+ 215, // Akan
+ 216, // Konkani
+ 217, // Ga
+ 218, // Igbo
+ 219, // Kamba
+ 220, // Syriac
+ 221, // Blin
+ 222, // Geez
+ 224, // Koro
+ 225, // Sidamo
+ 226, // Atsam
+ 227, // Tigre
+ 228, // Jju
+ 229, // Friulian
+ 230, // Venda
+ 231, // Ewe
+ 0, // Walamo
+ 233, // Hawaiian
+ 234, // Tyap
+ 235, // Chewa
+ 0 // trailing 0
+};
+
+static const QLocalePrivate locale_data[] = {
+// lang terr dec group list prcnt zero minus plus exp sDtFmt lDtFmt sTmFmt lTmFmt ssMonth slMonth sMonth lMonth sDays lDays am,len pm,len
+ { 1, 0, 46, 44, 59, 37, 48, 45, 43, 101, 0,10 , 10,17 , 0,8 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,27 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 99,14 , 0,2 , 0,2 }, // C/AnyCountry
+ { 3, 69, 46, 44, 59, 37, 48, 45, 43, 101, 27,8 , 35,18 , 18,7 , 25,11 , 158,12 , 158,12 , 134,24 , 161,48 , 209,111 , 320,12 , 113,7 , 113,7 , 85,14 , 120,28 , 148,55 , 113,7 , 2,0 , 2,0 }, // Afan/Ethiopia
+ { 3, 111, 46, 44, 59, 37, 48, 45, 43, 101, 27,8 , 35,18 , 18,7 , 25,11 , 158,12 , 158,12 , 134,24 , 161,48 , 209,111 , 320,12 , 113,7 , 113,7 , 85,14 , 120,28 , 148,55 , 113,7 , 2,0 , 2,0 }, // Afan/Kenya
+ { 4, 59, 46, 44, 59, 37, 48, 45, 43, 101, 27,8 , 53,19 , 18,7 , 25,11 , 158,12 , 158,12 , 170,24 , 332,48 , 380,129 , 320,12 , 113,7 , 113,7 , 203,14 , 217,28 , 245,52 , 113,7 , 2,0 , 2,0 }, // Afar/Djibouti
+ { 4, 67, 46, 44, 59, 37, 48, 45, 43, 101, 27,8 , 53,19 , 18,7 , 25,11 , 158,12 , 158,12 , 170,24 , 332,48 , 509,118 , 320,12 , 113,7 , 113,7 , 203,14 , 217,28 , 245,52 , 113,7 , 2,0 , 2,0 }, // Afar/Eritrea
+ { 4, 69, 46, 44, 59, 37, 48, 45, 43, 101, 27,8 , 53,19 , 18,7 , 25,11 , 158,12 , 158,12 , 170,24 , 332,48 , 509,118 , 320,12 , 113,7 , 113,7 , 203,14 , 217,28 , 245,52 , 113,7 , 2,0 , 2,0 }, // Afar/Ethiopia
+ { 5, 195, 44, 160, 59, 37, 48, 45, 43, 101, 72,10 , 82,17 , 18,7 , 25,11 , 158,12 , 158,12 , 194,27 , 627,48 , 675,92 , 320,12 , 113,7 , 113,7 , 297,14 , 311,21 , 332,58 , 113,7 , 2,3 , 2,3 }, // Afrikaans/SouthAfrica
+ { 5, 148, 44, 160, 59, 37, 48, 45, 43, 101, 99,10 , 109,16 , 36,5 , 41,9 , 158,12 , 158,12 , 194,27 , 627,48 , 675,92 , 320,12 , 113,7 , 113,7 , 297,14 , 311,21 , 332,58 , 113,7 , 2,3 , 2,3 }, // Afrikaans/Namibia
+ { 6, 2, 44, 46, 59, 37, 48, 45, 43, 101, 125,8 , 133,18 , 50,7 , 57,11 , 158,12 , 158,12 , 221,24 , 767,48 , 815,78 , 320,12 , 113,7 , 113,7 , 390,14 , 404,28 , 432,58 , 113,7 , 5,2 , 5,2 }, // Albanian/Albania
+ { 7, 69, 46, 44, 59, 37, 48, 45, 43, 101, 27,8 , 151,23 , 18,7 , 68,12 , 158,12 , 158,12 , 245,24 , 893,46 , 939,62 , 320,12 , 113,7 , 113,7 , 490,14 , 504,27 , 531,28 , 113,7 , 2,0 , 2,0 }, // Amharic/Ethiopia
+ { 8, 186, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 174,10 , 184,18 , 18,7 , 80,11 , 158,12 , 158,12 , 269,24 , 1001,75 , 1001,75 , 320,12 , 559,38 , 113,7 , 597,14 , 611,52 , 611,52 , 113,7 , 7,1 , 7,1 }, // Arabic/SaudiArabia
+ { 8, 3, 1643, 1644, 1563, 1642, 48, 45, 43, 101, 174,10 , 184,18 , 18,7 , 80,11 , 158,12 , 158,12 , 269,24 , 1001,75 , 1001,75 , 320,12 , 559,38 , 113,7 , 597,14 , 597,14 , 611,52 , 113,7 , 7,1 , 7,1 }, // Arabic/Algeria
+ { 8, 17, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 174,10 , 184,18 , 18,7 , 80,11 , 158,12 , 158,12 , 269,24 , 1001,75 , 1001,75 , 320,12 , 559,38 , 113,7 , 597,14 , 597,14 , 611,52 , 113,7 , 7,1 , 7,1 }, // Arabic/Bahrain
+ { 8, 64, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 174,10 , 184,18 , 18,7 , 80,11 , 158,12 , 158,12 , 269,24 , 1001,75 , 1001,75 , 320,12 , 559,38 , 113,7 , 597,14 , 597,14 , 611,52 , 113,7 , 7,1 , 7,1 }, // Arabic/Egypt
+ { 8, 103, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 174,10 , 184,18 , 18,7 , 80,11 , 158,12 , 158,12 , 269,24 , 1001,75 , 1001,75 , 320,12 , 559,38 , 113,7 , 597,14 , 597,14 , 611,52 , 113,7 , 7,1 , 7,1 }, // Arabic/Iraq
+ { 8, 109, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 174,10 , 184,18 , 18,7 , 80,11 , 158,12 , 158,12 , 269,24 , 1076,92 , 1076,92 , 320,12 , 559,38 , 113,7 , 597,14 , 611,52 , 611,52 , 113,7 , 7,1 , 7,1 }, // Arabic/Jordan
+ { 8, 115, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 174,10 , 184,18 , 18,7 , 80,11 , 158,12 , 158,12 , 269,24 , 1001,75 , 1001,75 , 320,12 , 559,38 , 113,7 , 597,14 , 597,14 , 611,52 , 113,7 , 7,1 , 7,1 }, // Arabic/Kuwait
+ { 8, 119, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 174,10 , 184,18 , 18,7 , 80,11 , 158,12 , 158,12 , 269,24 , 1168,92 , 1168,92 , 320,12 , 559,38 , 113,7 , 597,14 , 611,52 , 611,52 , 113,7 , 7,1 , 7,1 }, // Arabic/Lebanon
+ { 8, 122, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 174,10 , 184,18 , 18,7 , 80,11 , 158,12 , 158,12 , 269,24 , 1001,75 , 1001,75 , 320,12 , 559,38 , 113,7 , 597,14 , 597,14 , 611,52 , 113,7 , 7,1 , 7,1 }, // Arabic/LibyanArabJamahiriya
+ { 8, 145, 1643, 1644, 1563, 1642, 48, 45, 43, 101, 174,10 , 184,18 , 18,7 , 80,11 , 158,12 , 158,12 , 269,24 , 1001,75 , 1001,75 , 320,12 , 559,38 , 113,7 , 597,14 , 597,14 , 611,52 , 113,7 , 7,1 , 7,1 }, // Arabic/Morocco
+ { 8, 162, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 174,10 , 184,18 , 18,7 , 80,11 , 158,12 , 158,12 , 269,24 , 1001,75 , 1001,75 , 320,12 , 559,38 , 113,7 , 597,14 , 597,14 , 611,52 , 113,7 , 7,1 , 7,1 }, // Arabic/Oman
+ { 8, 175, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 174,10 , 184,18 , 18,7 , 80,11 , 158,12 , 158,12 , 269,24 , 1001,75 , 1001,75 , 320,12 , 559,38 , 113,7 , 597,14 , 611,52 , 611,52 , 113,7 , 7,1 , 7,1 }, // Arabic/Qatar
+ { 8, 201, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 174,10 , 184,18 , 18,7 , 80,11 , 158,12 , 158,12 , 269,24 , 1001,75 , 1001,75 , 320,12 , 559,38 , 113,7 , 597,14 , 597,14 , 611,52 , 113,7 , 7,1 , 7,1 }, // Arabic/Sudan
+ { 8, 207, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 174,10 , 184,18 , 18,7 , 80,11 , 158,12 , 158,12 , 269,24 , 1168,92 , 1168,92 , 320,12 , 559,38 , 113,7 , 597,14 , 611,52 , 611,52 , 113,7 , 7,1 , 7,1 }, // Arabic/SyrianArabRepublic
+ { 8, 216, 1643, 1644, 1563, 1642, 48, 45, 43, 101, 174,10 , 184,18 , 18,7 , 80,11 , 158,12 , 158,12 , 269,24 , 1001,75 , 1001,75 , 320,12 , 559,38 , 113,7 , 597,14 , 611,52 , 611,52 , 113,7 , 7,1 , 7,1 }, // Arabic/Tunisia
+ { 8, 223, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 174,10 , 184,18 , 18,7 , 80,11 , 158,12 , 158,12 , 269,24 , 1001,75 , 1001,75 , 320,12 , 559,38 , 113,7 , 597,14 , 597,14 , 611,52 , 113,7 , 7,1 , 7,1 }, // Arabic/UnitedArabEmirates
+ { 8, 237, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 174,10 , 184,18 , 18,7 , 80,11 , 158,12 , 158,12 , 269,24 , 1001,75 , 1001,75 , 320,12 , 559,38 , 113,7 , 597,14 , 611,52 , 611,52 , 113,7 , 7,1 , 7,1 }, // Arabic/Yemen
+ { 9, 11, 44, 46, 59, 37, 48, 45, 43, 101, 202,8 , 35,18 , 36,5 , 41,9 , 158,12 , 158,12 , 194,27 , 1260,48 , 1308,96 , 320,12 , 113,7 , 113,7 , 297,14 , 663,28 , 691,62 , 113,7 , 8,3 , 8,3 }, // Armenian/Armenia
+ { 10, 100, 46, 44, 59, 37, 48, 45, 43, 101, 210,8 , 218,18 , 91,8 , 99,11 , 158,12 , 158,12 , 194,27 , 1404,62 , 1466,90 , 320,12 , 113,7 , 113,7 , 297,14 , 753,37 , 790,58 , 113,7 , 11,6 , 11,2 }, // Assamese/India
+ { 12, 15, 44, 46, 59, 37, 48, 45, 43, 101, 236,8 , 244,18 , 36,5 , 41,9 , 158,12 , 158,12 , 194,27 , 1556,48 , 1604,77 , 320,12 , 113,7 , 113,7 , 99,14 , 848,26 , 874,67 , 113,7 , 2,0 , 2,0 }, // Azerbaijani/Azerbaijan
+ { 14, 197, 44, 46, 59, 37, 48, 45, 43, 101, 125,8 , 262,31 , 36,5 , 41,9 , 158,12 , 158,12 , 194,27 , 1681,48 , 1729,93 , 320,12 , 113,7 , 113,7 , 297,14 , 941,21 , 962,68 , 113,7 , 2,0 , 2,0 }, // Basque/Spain
+ { 15, 18, 46, 44, 59, 37, 2534, 45, 43, 101, 293,6 , 218,18 , 18,7 , 25,11 , 158,12 , 158,12 , 293,33 , 1822,90 , 1822,90 , 320,12 , 113,7 , 113,7 , 1030,18 , 1048,37 , 1085,58 , 113,7 , 17,9 , 13,7 }, // Bengali/Bangladesh
+ { 15, 100, 46, 44, 59, 37, 2534, 45, 43, 101, 293,6 , 218,18 , 18,7 , 25,11 , 158,12 , 158,12 , 293,33 , 1822,90 , 1822,90 , 320,12 , 113,7 , 113,7 , 1030,18 , 1048,37 , 1085,58 , 113,7 , 17,9 , 13,7 }, // Bengali/India
+ { 16, 25, 46, 44, 59, 37, 3872, 45, 43, 101, 299,28 , 327,29 , 110,22 , 132,34 , 158,12 , 158,12 , 194,27 , 1912,75 , 1987,205 , 320,12 , 113,7 , 113,7 , 297,14 , 1143,34 , 1177,79 , 113,7 , 2,0 , 2,0 }, // Bhutani/Bhutan
+ { 20, 33, 44, 160, 59, 37, 48, 45, 43, 101, 356,8 , 364,18 , 36,5 , 41,9 , 158,12 , 158,12 , 326,24 , 2192,59 , 2251,82 , 320,12 , 113,7 , 113,7 , 1256,14 , 1270,21 , 1291,55 , 113,7 , 26,7 , 20,7 }, // Bulgarian/Bulgaria
+ { 21, 147, 46, 44, 4170, 37, 4160, 45, 43, 101, 236,8 , 244,18 , 36,5 , 41,9 , 158,12 , 158,12 , 350,24 , 2333,43 , 2376,88 , 320,12 , 113,7 , 113,7 , 1346,14 , 1360,25 , 1385,54 , 113,7 , 2,0 , 2,0 }, // Burmese/Myanmar
+ { 22, 20, 44, 160, 59, 37, 48, 45, 43, 101, 382,6 , 10,17 , 166,5 , 171,9 , 374,15 , 389,19 , 408,24 , 2464,48 , 2512,95 , 2607,13 , 113,7 , 113,7 , 1439,14 , 1453,21 , 1474,56 , 113,7 , 33,10 , 27,13 }, // Byelorussian/Belarus
+ { 23, 36, 44, 46, 59, 37, 48, 45, 43, 101, 388,8 , 396,31 , 180,4 , 184,25 , 158,12 , 158,12 , 194,27 , 2620,27 , 2647,71 , 320,12 , 113,7 , 113,7 , 297,14 , 1530,19 , 1549,76 , 113,7 , 43,5 , 40,5 }, // Cambodian/Cambodia
+ { 24, 197, 44, 46, 59, 37, 48, 45, 43, 101, 27,8 , 427,26 , 180,4 , 209,8 , 158,12 , 158,12 , 432,24 , 2718,60 , 2778,82 , 320,12 , 1625,21 , 113,7 , 1646,14 , 1660,28 , 1688,60 , 113,7 , 2,0 , 2,0 }, // Catalan/Spain
+ { 25, 44, 46, 44, 59, 37, 48, 45, 43, 101, 453,6 , 459,13 , 217,6 , 223,11 , 456,38 , 456,38 , 494,39 , 2860,39 , 2860,39 , 320,12 , 113,7 , 113,7 , 1748,14 , 1762,21 , 1783,28 , 113,7 , 48,2 , 45,2 }, // Chinese/China
+ { 25, 97, 46, 65292, 65307, 37, 48, 45, 43, 101, 472,7 , 459,13 , 217,6 , 223,11 , 456,38 , 456,38 , 494,39 , 2860,39 , 2860,39 , 320,12 , 113,7 , 113,7 , 1748,14 , 1762,21 , 1783,28 , 113,7 , 48,2 , 45,2 }, // Chinese/HongKong
+ { 25, 126, 46, 44, 59, 37, 48, 45, 43, 101, 472,7 , 479,15 , 217,6 , 223,11 , 456,38 , 456,38 , 494,39 , 2860,39 , 2860,39 , 320,12 , 113,7 , 113,7 , 1748,14 , 1762,21 , 1783,28 , 113,7 , 48,2 , 45,2 }, // Chinese/Macau
+ { 25, 190, 46, 44, 59, 37, 48, 45, 43, 101, 27,8 , 459,13 , 234,7 , 223,11 , 456,38 , 456,38 , 494,39 , 2860,39 , 2860,39 , 320,12 , 113,7 , 113,7 , 1748,14 , 1762,21 , 1783,28 , 113,7 , 48,2 , 45,2 }, // Chinese/Singapore
+ { 25, 208, 46, 44, 59, 37, 48, 45, 43, 101, 453,6 , 459,13 , 217,6 , 223,11 , 456,38 , 456,38 , 494,39 , 2860,39 , 2860,39 , 320,12 , 113,7 , 113,7 , 1748,14 , 1762,21 , 1783,28 , 113,7 , 48,2 , 45,2 }, // Chinese/Taiwan
+ { 27, 54, 44, 46, 59, 37, 48, 45, 43, 101, 494,11 , 505,19 , 36,5 , 41,9 , 158,12 , 533,94 , 627,24 , 2899,48 , 2947,98 , 320,12 , 113,7 , 113,7 , 1811,14 , 1825,28 , 1853,58 , 113,7 , 0,2 , 0,2 }, // Croatian/Croatia
+ { 28, 57, 44, 160, 59, 37, 48, 45, 43, 101, 382,6 , 524,18 , 180,4 , 41,9 , 651,39 , 690,82 , 772,24 , 134,27 , 3045,84 , 320,12 , 113,7 , 113,7 , 1911,14 , 1925,21 , 1946,49 , 113,7 , 50,4 , 47,4 }, // Czech/CzechRepublic
+ { 29, 58, 44, 46, 44, 37, 48, 45, 43, 101, 27,8 , 542,23 , 166,5 , 171,9 , 158,12 , 158,12 , 134,24 , 3129,48 , 3177,84 , 320,12 , 113,7 , 113,7 , 1995,14 , 2009,28 , 2037,51 , 113,7 , 54,4 , 51,4 }, // Danish/Denmark
+ { 30, 151, 44, 46, 59, 37, 48, 45, 43, 101, 565,8 , 109,16 , 36,5 , 41,9 , 158,12 , 158,12 , 134,24 , 3261,48 , 3309,88 , 320,12 , 113,7 , 113,7 , 2088,14 , 2102,21 , 2123,59 , 113,7 , 2,0 , 2,0 }, // Dutch/Netherlands
+ { 30, 21, 44, 46, 59, 37, 48, 45, 43, 101, 573,7 , 109,16 , 36,5 , 41,9 , 158,12 , 158,12 , 134,24 , 3261,48 , 3309,88 , 320,12 , 113,7 , 113,7 , 2088,14 , 2102,21 , 2123,59 , 113,7 , 2,0 , 2,0 }, // Dutch/Belgium
+ { 31, 225, 46, 44, 59, 37, 48, 45, 43, 101, 580,6 , 35,18 , 18,7 , 25,11 , 158,12 , 158,12 , 134,24 , 0,48 , 48,86 , 320,12 , 113,7 , 113,7 , 85,14 , 0,28 , 28,57 , 113,7 , 0,2 , 0,2 }, // English/UnitedStates
+ { 31, 4, 46, 44, 59, 37, 48, 45, 43, 101, 580,6 , 35,18 , 18,7 , 25,11 , 158,12 , 158,12 , 134,24 , 0,48 , 48,86 , 320,12 , 113,7 , 113,7 , 85,14 , 0,28 , 28,57 , 113,7 , 0,2 , 0,2 }, // English/AmericanSamoa
+ { 31, 13, 46, 44, 59, 37, 48, 45, 43, 101, 573,7 , 10,17 , 18,7 , 25,11 , 158,12 , 158,12 , 134,24 , 0,48 , 48,86 , 320,12 , 113,7 , 113,7 , 85,14 , 0,28 , 28,57 , 113,7 , 0,2 , 0,2 }, // English/Australia
+ { 31, 21, 44, 46, 59, 37, 48, 45, 43, 101, 27,8 , 109,16 , 36,5 , 241,23 , 158,12 , 158,12 , 134,24 , 0,48 , 48,86 , 320,12 , 113,7 , 113,7 , 85,14 , 0,28 , 28,57 , 113,7 , 0,2 , 0,2 }, // English/Belgium
+ { 31, 22, 46, 44, 59, 37, 48, 45, 43, 101, 27,8 , 586,12 , 36,5 , 41,9 , 158,12 , 158,12 , 134,24 , 0,48 , 48,86 , 320,12 , 113,7 , 113,7 , 85,14 , 0,28 , 28,57 , 113,7 , 0,2 , 0,2 }, // English/Belize
+ { 31, 28, 46, 44, 59, 37, 48, 45, 43, 101, 27,8 , 82,17 , 18,7 , 25,11 , 158,12 , 158,12 , 134,24 , 0,48 , 48,86 , 320,12 , 113,7 , 113,7 , 85,14 , 0,28 , 28,57 , 113,7 , 0,2 , 0,2 }, // English/Botswana
+ { 31, 38, 46, 44, 59, 37, 48, 45, 43, 101, 125,8 , 35,18 , 18,7 , 25,11 , 158,12 , 158,12 , 134,24 , 0,48 , 48,86 , 320,12 , 113,7 , 113,7 , 85,14 , 0,28 , 28,57 , 113,7 , 0,2 , 0,2 }, // English/Canada
+ { 31, 89, 46, 44, 59, 37, 48, 45, 43, 101, 580,6 , 35,18 , 18,7 , 25,11 , 158,12 , 158,12 , 134,24 , 0,48 , 48,86 , 320,12 , 113,7 , 113,7 , 85,14 , 0,28 , 28,57 , 113,7 , 0,2 , 0,2 }, // English/Guam
+ { 31, 97, 46, 44, 59, 37, 48, 45, 43, 101, 598,10 , 10,17 , 18,7 , 25,11 , 158,12 , 158,12 , 134,24 , 0,48 , 48,86 , 320,12 , 113,7 , 113,7 , 85,14 , 0,28 , 28,57 , 113,7 , 0,2 , 0,2 }, // English/HongKong
+ { 31, 100, 46, 44, 59, 37, 48, 45, 43, 101, 27,8 , 109,16 , 18,7 , 25,11 , 158,12 , 158,12 , 134,24 , 0,48 , 48,86 , 320,12 , 113,7 , 113,7 , 85,14 , 0,28 , 28,57 , 113,7 , 0,2 , 0,2 }, // English/India
+ { 31, 104, 46, 44, 59, 37, 48, 45, 43, 101, 598,10 , 109,16 , 36,5 , 41,9 , 158,12 , 158,12 , 134,24 , 0,48 , 48,86 , 320,12 , 113,7 , 113,7 , 85,14 , 0,28 , 28,57 , 113,7 , 58,4 , 55,4 }, // English/Ireland
+ { 31, 107, 46, 44, 59, 37, 48, 45, 43, 101, 580,6 , 35,18 , 18,7 , 25,11 , 158,12 , 158,12 , 134,24 , 0,48 , 48,86 , 320,12 , 113,7 , 113,7 , 85,14 , 0,28 , 28,57 , 113,7 , 0,2 , 0,2 }, // English/Jamaica
+ { 31, 133, 46, 44, 59, 37, 48, 45, 43, 101, 598,10 , 10,17 , 36,5 , 41,9 , 158,12 , 158,12 , 134,24 , 0,48 , 48,86 , 320,12 , 113,7 , 113,7 , 85,14 , 0,28 , 28,57 , 113,7 , 0,2 , 0,2 }, // English/Malta
+ { 31, 134, 46, 44, 59, 37, 48, 45, 43, 101, 580,6 , 35,18 , 18,7 , 25,11 , 158,12 , 158,12 , 134,24 , 0,48 , 48,86 , 320,12 , 113,7 , 113,7 , 85,14 , 0,28 , 28,57 , 113,7 , 0,2 , 0,2 }, // English/MarshallIslands
+ { 31, 148, 46, 44, 59, 37, 48, 45, 43, 101, 580,6 , 35,18 , 18,7 , 25,11 , 158,12 , 158,12 , 134,24 , 0,48 , 48,86 , 320,12 , 113,7 , 113,7 , 85,14 , 0,28 , 28,57 , 113,7 , 0,2 , 0,2 }, // English/Namibia
+ { 31, 154, 46, 44, 59, 37, 48, 45, 43, 101, 573,7 , 10,17 , 18,7 , 25,11 , 158,12 , 158,12 , 134,24 , 0,48 , 48,86 , 320,12 , 113,7 , 113,7 , 85,14 , 0,28 , 28,57 , 113,7 , 0,2 , 0,2 }, // English/NewZealand
+ { 31, 160, 46, 44, 59, 37, 48, 45, 43, 101, 580,6 , 35,18 , 18,7 , 25,11 , 158,12 , 158,12 , 134,24 , 0,48 , 48,86 , 320,12 , 113,7 , 113,7 , 85,14 , 0,28 , 28,57 , 113,7 , 0,2 , 0,2 }, // English/NorthernMarianaIslands
+ { 31, 163, 46, 44, 59, 37, 48, 45, 43, 101, 27,8 , 109,16 , 18,7 , 25,11 , 158,12 , 158,12 , 134,24 , 0,48 , 48,86 , 320,12 , 113,7 , 113,7 , 85,14 , 0,28 , 28,57 , 113,7 , 0,2 , 0,2 }, // English/Pakistan
+ { 31, 170, 46, 44, 59, 37, 48, 45, 43, 101, 580,6 , 35,18 , 18,7 , 25,11 , 158,12 , 158,12 , 134,24 , 0,48 , 48,86 , 320,12 , 113,7 , 113,7 , 85,14 , 0,28 , 28,57 , 113,7 , 0,2 , 0,2 }, // English/Philippines
+ { 31, 190, 46, 44, 59, 37, 48, 45, 43, 101, 27,8 , 133,18 , 264,8 , 272,12 , 158,12 , 158,12 , 134,24 , 0,48 , 48,86 , 320,12 , 113,7 , 113,7 , 85,14 , 0,28 , 28,57 , 113,7 , 0,2 , 0,2 }, // English/Singapore
+ { 31, 195, 44, 160, 59, 37, 48, 45, 43, 101, 72,10 , 82,17 , 18,7 , 25,11 , 158,12 , 158,12 , 134,24 , 0,48 , 48,86 , 320,12 , 113,7 , 113,7 , 85,14 , 0,28 , 28,57 , 113,7 , 0,2 , 0,2 }, // English/SouthAfrica
+ { 31, 215, 46, 44, 59, 37, 48, 45, 43, 101, 580,6 , 35,18 , 18,7 , 25,11 , 158,12 , 158,12 , 134,24 , 0,48 , 48,86 , 320,12 , 113,7 , 113,7 , 85,14 , 0,28 , 28,57 , 113,7 , 0,2 , 0,2 }, // English/TrinidadAndTobago
+ { 31, 224, 46, 44, 59, 37, 48, 45, 43, 101, 598,10 , 10,17 , 36,5 , 41,9 , 158,12 , 158,12 , 134,24 , 0,48 , 48,86 , 320,12 , 113,7 , 113,7 , 85,14 , 0,28 , 28,57 , 113,7 , 0,2 , 0,2 }, // English/UnitedKingdom
+ { 31, 226, 46, 44, 59, 37, 48, 45, 43, 101, 580,6 , 35,18 , 18,7 , 25,11 , 158,12 , 158,12 , 134,24 , 0,48 , 48,86 , 320,12 , 113,7 , 113,7 , 85,14 , 0,28 , 28,57 , 113,7 , 0,2 , 0,2 }, // English/UnitedStatesMinorOutlyingIslands
+ { 31, 234, 46, 44, 59, 37, 48, 45, 43, 101, 580,6 , 35,18 , 18,7 , 25,11 , 158,12 , 158,12 , 134,24 , 0,48 , 48,86 , 320,12 , 113,7 , 113,7 , 85,14 , 0,28 , 28,57 , 113,7 , 0,2 , 0,2 }, // English/USVirginIslands
+ { 31, 240, 46, 44, 59, 37, 48, 45, 43, 101, 388,8 , 82,17 , 18,7 , 25,11 , 158,12 , 158,12 , 134,24 , 0,48 , 48,86 , 320,12 , 113,7 , 113,7 , 85,14 , 0,28 , 28,57 , 113,7 , 0,2 , 0,2 }, // English/Zimbabwe
+ { 33, 68, 44, 160, 59, 37, 48, 45, 43, 101, 356,8 , 608,18 , 180,4 , 209,8 , 158,12 , 158,12 , 194,27 , 3397,59 , 3456,91 , 320,12 , 113,7 , 113,7 , 297,14 , 2182,14 , 2196,63 , 113,7 , 2,0 , 2,0 }, // Estonian/Estonia
+ { 34, 71, 44, 46, 59, 37, 48, 8722, 43, 101, 565,8 , 82,17 , 36,5 , 41,9 , 158,12 , 158,12 , 194,27 , 3547,48 , 3595,83 , 320,12 , 113,7 , 113,7 , 297,14 , 2259,28 , 2287,74 , 113,7 , 2,0 , 2,0 }, // Faroese/FaroeIslands
+ { 36, 73, 44, 160, 59, 37, 48, 45, 43, 101, 626,8 , 634,17 , 284,4 , 288,8 , 158,12 , 158,12 , 796,24 , 3678,69 , 3747,129 , 320,12 , 113,7 , 113,7 , 2361,14 , 2375,21 , 2396,81 , 113,7 , 62,3 , 59,3 }, // Finnish/Finland
+ { 37, 74, 44, 160, 59, 37, 48, 45, 43, 101, 27,8 , 109,16 , 36,5 , 41,9 , 158,12 , 158,12 , 134,24 , 3876,63 , 3939,85 , 320,12 , 113,7 , 113,7 , 2477,14 , 2491,35 , 2526,52 , 113,7 , 0,2 , 0,2 }, // French/France
+ { 37, 21, 44, 46, 59, 37, 48, 45, 43, 101, 573,7 , 109,16 , 36,5 , 296,22 , 158,12 , 158,12 , 134,24 , 3876,63 , 3939,85 , 320,12 , 113,7 , 113,7 , 2477,14 , 2491,35 , 2526,52 , 113,7 , 0,2 , 0,2 }, // French/Belgium
+ { 37, 38, 44, 160, 59, 37, 48, 45, 43, 101, 125,8 , 109,16 , 36,5 , 241,23 , 158,12 , 158,12 , 134,24 , 3876,63 , 3939,85 , 320,12 , 113,7 , 113,7 , 2477,14 , 2491,35 , 2526,52 , 113,7 , 0,2 , 0,2 }, // French/Canada
+ { 37, 125, 44, 46, 59, 37, 48, 45, 43, 101, 27,8 , 109,16 , 36,5 , 41,9 , 158,12 , 158,12 , 134,24 , 3876,63 , 3939,85 , 320,12 , 113,7 , 113,7 , 2477,14 , 2491,35 , 2526,52 , 113,7 , 0,2 , 0,2 }, // French/Luxembourg
+ { 37, 142, 44, 160, 59, 37, 48, 45, 43, 101, 27,8 , 109,16 , 36,5 , 41,9 , 158,12 , 158,12 , 134,24 , 3876,63 , 3939,85 , 320,12 , 113,7 , 113,7 , 2477,14 , 2491,35 , 2526,52 , 113,7 , 0,2 , 0,2 }, // French/Monaco
+ { 37, 187, 44, 160, 59, 37, 48, 45, 43, 101, 27,8 , 109,16 , 36,5 , 41,9 , 158,12 , 158,12 , 134,24 , 3876,63 , 3939,85 , 320,12 , 113,7 , 113,7 , 2477,14 , 2491,35 , 2526,52 , 113,7 , 0,2 , 0,2 }, // French/Senegal
+ { 37, 206, 46, 39, 59, 37, 48, 45, 43, 101, 356,8 , 10,17 , 36,5 , 318,13 , 158,12 , 158,12 , 134,24 , 3876,63 , 3939,85 , 320,12 , 113,7 , 113,7 , 2477,14 , 2491,35 , 2526,52 , 113,7 , 0,2 , 0,2 }, // French/Switzerland
+ { 40, 197, 44, 46, 59, 37, 48, 45, 43, 101, 27,8 , 82,17 , 36,5 , 41,9 , 158,12 , 158,12 , 820,24 , 4024,48 , 4072,87 , 320,12 , 113,7 , 113,7 , 2578,14 , 2592,28 , 2620,49 , 113,7 , 2,0 , 2,0 }, // Galician/Spain
+ { 41, 81, 44, 46, 59, 37, 48, 45, 43, 101, 236,8 , 244,18 , 36,5 , 41,9 , 158,12 , 158,12 , 844,24 , 4159,48 , 4207,99 , 320,12 , 113,7 , 113,7 , 2669,14 , 2683,28 , 2711,62 , 113,7 , 2,0 , 2,0 }, // Georgian/Georgia
+ { 42, 82, 44, 46, 59, 37, 48, 45, 43, 101, 356,8 , 524,18 , 36,5 , 41,9 , 868,33 , 158,12 , 134,24 , 4306,48 , 4354,83 , 320,12 , 113,7 , 113,7 , 2773,14 , 2787,28 , 2815,60 , 113,7 , 65,5 , 62,6 }, // German/Germany
+ { 42, 14, 44, 46, 59, 37, 48, 45, 43, 101, 356,8 , 651,19 , 36,5 , 41,9 , 868,33 , 158,12 , 134,24 , 4437,48 , 4485,83 , 320,12 , 113,7 , 113,7 , 2773,14 , 2787,28 , 2815,60 , 113,7 , 65,5 , 62,6 }, // German/Austria
+ { 42, 21, 44, 46, 59, 37, 48, 45, 43, 101, 573,7 , 109,16 , 36,5 , 241,23 , 868,33 , 158,12 , 134,24 , 4568,48 , 4354,83 , 320,12 , 113,7 , 113,7 , 2773,14 , 2875,28 , 2815,60 , 113,7 , 65,5 , 62,6 }, // German/Belgium
+ { 42, 123, 46, 39, 59, 37, 48, 45, 43, 101, 356,8 , 524,18 , 36,5 , 41,9 , 868,33 , 158,12 , 134,24 , 4306,48 , 4354,83 , 320,12 , 113,7 , 113,7 , 2773,14 , 2787,28 , 2815,60 , 113,7 , 65,5 , 62,6 }, // German/Liechtenstein
+ { 42, 125, 44, 46, 59, 37, 48, 45, 43, 101, 356,8 , 524,18 , 36,5 , 41,9 , 868,33 , 158,12 , 134,24 , 4306,48 , 4354,83 , 320,12 , 113,7 , 113,7 , 2773,14 , 2787,28 , 2815,60 , 113,7 , 65,5 , 62,6 }, // German/Luxembourg
+ { 42, 206, 46, 39, 59, 37, 48, 45, 43, 101, 356,8 , 524,18 , 36,5 , 41,9 , 868,33 , 158,12 , 134,24 , 4306,48 , 4354,83 , 320,12 , 113,7 , 113,7 , 2773,14 , 2787,28 , 2815,60 , 113,7 , 65,5 , 62,6 }, // German/Switzerland
+ { 43, 85, 44, 46, 59, 37, 48, 45, 43, 101, 598,10 , 133,18 , 18,7 , 25,11 , 158,12 , 901,115 , 1016,24 , 4616,50 , 4666,115 , 320,12 , 113,7 , 113,7 , 2903,14 , 2917,28 , 2945,55 , 113,7 , 70,4 , 68,4 }, // Greek/Greece
+ { 43, 56, 44, 46, 59, 37, 48, 45, 43, 101, 598,10 , 133,18 , 18,7 , 25,11 , 158,12 , 901,115 , 1016,24 , 4616,50 , 4666,115 , 320,12 , 113,7 , 113,7 , 2903,14 , 2917,28 , 2945,55 , 113,7 , 70,4 , 68,4 }, // Greek/Cyprus
+ { 44, 86, 44, 46, 59, 37, 48, 45, 43, 101, 27,8 , 82,17 , 18,7 , 25,11 , 158,12 , 158,12 , 194,27 , 3129,48 , 4781,96 , 320,12 , 113,7 , 113,7 , 297,14 , 3000,28 , 3028,98 , 113,7 , 2,0 , 2,0 }, // Greenlandic/Greenland
+ { 46, 100, 46, 44, 59, 37, 2790, 45, 43, 101, 670,7 , 109,16 , 331,8 , 68,12 , 158,12 , 158,12 , 194,27 , 4877,67 , 4944,87 , 320,12 , 113,7 , 113,7 , 297,14 , 3126,32 , 3158,53 , 113,7 , 74,14 , 72,14 }, // Gujarati/India
+ { 47, 83, 46, 44, 59, 37, 48, 45, 43, 101, 293,6 , 218,18 , 36,5 , 41,9 , 158,12 , 158,12 , 1040,24 , 5031,48 , 5079,84 , 320,12 , 113,7 , 113,7 , 3211,14 , 3225,28 , 3253,51 , 113,7 , 0,2 , 0,2 }, // Hausa/Ghana
+ { 47, 156, 46, 44, 59, 37, 48, 45, 43, 101, 293,6 , 218,18 , 36,5 , 41,9 , 158,12 , 158,12 , 1040,24 , 5031,48 , 5079,84 , 320,12 , 113,7 , 113,7 , 3211,14 , 3225,28 , 3253,51 , 113,7 , 0,2 , 0,2 }, // Hausa/Niger
+ { 47, 157, 46, 44, 59, 37, 48, 45, 43, 101, 293,6 , 218,18 , 36,5 , 41,9 , 158,12 , 158,12 , 1040,24 , 5031,48 , 5079,84 , 320,12 , 113,7 , 113,7 , 3211,14 , 3225,28 , 3253,51 , 113,7 , 0,2 , 0,2 }, // Hausa/Nigeria
+ { 47, 201, 46, 44, 59, 37, 48, 45, 43, 101, 293,6 , 218,18 , 36,5 , 41,9 , 158,12 , 158,12 , 1040,24 , 5031,48 , 5079,84 , 320,12 , 113,7 , 113,7 , 3211,14 , 3225,28 , 3253,51 , 113,7 , 0,2 , 0,2 }, // Hausa/Sudan
+ { 48, 105, 46, 44, 59, 37, 48, 45, 43, 101, 27,8 , 109,16 , 36,5 , 41,9 , 1064,15 , 1064,15 , 194,27 , 5163,48 , 5211,72 , 320,12 , 113,7 , 113,7 , 3304,14 , 3304,14 , 3318,61 , 113,7 , 88,6 , 86,5 }, // Hebrew/Israel
+ { 49, 100, 46, 44, 59, 37, 2406, 45, 43, 101, 677,6 , 109,16 , 18,7 , 25,11 , 158,12 , 158,12 , 194,27 , 5283,75 , 5283,75 , 320,12 , 113,7 , 113,7 , 3379,16 , 3395,32 , 3427,53 , 113,7 , 94,9 , 91,7 }, // Hindi/India
+ { 50, 98, 44, 160, 59, 37, 48, 45, 43, 101, 683,11 , 694,13 , 180,4 , 209,8 , 158,12 , 158,12 , 1079,24 , 5358,64 , 5422,98 , 320,12 , 113,7 , 113,7 , 3480,14 , 3494,19 , 3513,52 , 113,7 , 103,3 , 98,3 }, // Hungarian/Hungary
+ { 51, 99, 44, 46, 59, 37, 48, 8722, 43, 101, 626,8 , 524,18 , 36,5 , 41,9 , 158,12 , 158,12 , 1103,24 , 5520,48 , 5568,82 , 320,12 , 113,7 , 113,7 , 3565,14 , 3579,28 , 3607,81 , 113,7 , 2,0 , 2,0 }, // Icelandic/Iceland
+ { 52, 101, 44, 46, 59, 37, 48, 45, 43, 101, 27,8 , 82,17 , 180,4 , 209,8 , 158,12 , 158,12 , 194,27 , 5650,48 , 5698,87 , 320,12 , 113,7 , 113,7 , 297,14 , 3688,28 , 3716,43 , 113,7 , 2,0 , 2,0 }, // Indonesian/Indonesia
+ { 57, 104, 46, 44, 59, 37, 48, 45, 43, 101, 598,10 , 109,16 , 36,5 , 41,9 , 158,12 , 158,12 , 1127,24 , 5785,62 , 5847,107 , 320,12 , 113,7 , 113,7 , 3759,14 , 3773,37 , 3810,75 , 113,7 , 58,4 , 55,4 }, // Irish/Ireland
+ { 58, 106, 44, 46, 59, 37, 48, 45, 43, 101, 27,8 , 109,16 , 166,5 , 171,9 , 158,12 , 1151,56 , 1207,24 , 5954,48 , 6002,94 , 320,12 , 113,7 , 3885,57 , 3942,14 , 3956,28 , 3984,57 , 113,7 , 106,2 , 101,2 }, // Italian/Italy
+ { 58, 206, 46, 39, 59, 37, 48, 45, 43, 101, 356,8 , 10,17 , 166,5 , 318,13 , 158,12 , 1151,56 , 1207,24 , 5954,48 , 6002,94 , 320,12 , 113,7 , 3885,57 , 3942,14 , 3956,28 , 3984,57 , 113,7 , 106,2 , 101,2 }, // Italian/Switzerland
+ { 59, 108, 46, 44, 59, 37, 48, 45, 43, 101, 236,8 , 459,13 , 180,4 , 339,8 , 494,39 , 158,12 , 194,27 , 2860,39 , 2860,39 , 320,12 , 113,7 , 113,7 , 4041,14 , 4041,14 , 4055,28 , 113,7 , 108,2 , 103,2 }, // Japanese/Japan
+ { 61, 100, 46, 44, 59, 37, 48, 45, 43, 101, 677,6 , 109,16 , 331,8 , 68,12 , 158,12 , 158,12 , 194,27 , 6096,86 , 6096,86 , 320,12 , 113,7 , 113,7 , 297,14 , 4083,28 , 4111,53 , 113,7 , 110,9 , 105,7 }, // Kannada/India
+ { 63, 110, 44, 160, 59, 37, 48, 45, 43, 101, 356,8 , 707,22 , 36,5 , 41,9 , 158,12 , 158,12 , 194,27 , 6182,61 , 6243,83 , 320,12 , 113,7 , 113,7 , 297,14 , 4164,28 , 4192,54 , 113,7 , 2,0 , 2,0 }, // Kazakh/Kazakhstan
+ { 64, 179, 44, 46, 59, 37, 48, 45, 43, 101, 236,8 , 244,18 , 36,5 , 41,9 , 158,12 , 158,12 , 194,27 , 6326,60 , 6386,101 , 320,12 , 113,7 , 113,7 , 297,14 , 4246,35 , 4281,84 , 113,7 , 2,0 , 2,0 }, // Kinyarwanda/Rwanda
+ { 65, 116, 44, 160, 59, 37, 48, 45, 43, 101, 236,8 , 244,18 , 36,5 , 41,9 , 158,12 , 158,12 , 194,27 , 134,27 , 134,27 , 320,12 , 113,7 , 113,7 , 297,14 , 297,14 , 297,14 , 113,7 , 2,0 , 2,0 }, // Kirghiz/Kyrgyzstan
+ { 66, 114, 46, 44, 59, 37, 48, 45, 43, 101, 729,9 , 738,16 , 347,7 , 354,15 , 1231,39 , 1231,39 , 1231,39 , 6487,39 , 6487,39 , 320,12 , 113,7 , 113,7 , 4365,14 , 4365,14 , 4379,28 , 113,7 , 119,2 , 112,2 }, // Korean/RepublicOfKorea
+ { 67, 217, 46, 44, 59, 37, 48, 45, 43, 101, 99,10 , 244,18 , 36,5 , 41,9 , 158,12 , 158,12 , 194,27 , 320,12 , 134,27 , 320,12 , 113,7 , 113,7 , 297,14 , 113,7 , 297,14 , 113,7 , 2,0 , 2,0 }, // Kurdish/Turkey
+ { 69, 117, 46, 44, 59, 37, 48, 45, 43, 101, 388,8 , 754,21 , 180,4 , 369,20 , 158,12 , 158,12 , 194,27 , 6526,63 , 6589,75 , 320,12 , 113,7 , 113,7 , 297,14 , 4407,24 , 4431,57 , 113,7 , 2,0 , 2,0 }, // Laothian/Lao
+ { 71, 118, 44, 160, 59, 37, 48, 45, 43, 101, 775,6 , 781,26 , 36,5 , 41,9 , 158,12 , 158,12 , 134,24 , 6664,48 , 6712,101 , 320,12 , 4488,19 , 113,7 , 4507,14 , 4521,16 , 4537,72 , 113,7 , 2,0 , 2,0 }, // Latvian/Latvia
+ { 72, 49, 46, 44, 59, 37, 48, 45, 43, 101, 236,8 , 244,18 , 36,5 , 41,9 , 158,12 , 158,12 , 194,27 , 6813,39 , 6852,203 , 320,12 , 113,7 , 113,7 , 297,14 , 4609,23 , 4632,98 , 113,7 , 2,0 , 2,0 }, // Lingala/DemocraticRepublicOfCongo
+ { 72, 50, 46, 44, 59, 37, 48, 45, 43, 101, 236,8 , 244,18 , 36,5 , 41,9 , 158,12 , 158,12 , 194,27 , 6813,39 , 6852,203 , 320,12 , 113,7 , 113,7 , 297,14 , 4609,23 , 4632,98 , 113,7 , 2,0 , 2,0 }, // Lingala/PeoplesRepublicOfCongo
+ { 73, 124, 44, 46, 59, 37, 48, 8722, 43, 101, 99,10 , 807,26 , 36,5 , 41,9 , 158,12 , 1270,96 , 1366,24 , 7055,48 , 7103,98 , 320,12 , 113,7 , 113,7 , 4730,14 , 4744,21 , 4765,89 , 113,7 , 121,9 , 114,6 }, // Lithuanian/Lithuania
+ { 74, 127, 44, 46, 59, 37, 48, 45, 43, 101, 833,7 , 133,18 , 36,5 , 41,9 , 158,12 , 158,12 , 1390,24 , 7201,63 , 7264,85 , 7349,14 , 113,7 , 113,7 , 1256,14 , 4854,34 , 4888,54 , 113,7 , 2,0 , 2,0 }, // Macedonian/Macedonia
+ { 76, 130, 46, 44, 59, 37, 48, 45, 43, 101, 598,10 , 840,16 , 389,4 , 25,11 , 158,12 , 158,12 , 194,27 , 7363,49 , 7412,82 , 320,12 , 113,7 , 113,7 , 297,14 , 4942,28 , 4970,43 , 113,7 , 2,0 , 2,0 }, // Malay/Malaysia
+ { 76, 32, 44, 46, 59, 37, 48, 45, 43, 101, 598,10 , 586,12 , 180,4 , 393,13 , 158,12 , 158,12 , 194,27 , 7363,49 , 7412,82 , 320,12 , 113,7 , 113,7 , 297,14 , 4942,28 , 4970,43 , 113,7 , 2,0 , 2,0 }, // Malay/BruneiDarussalam
+ { 77, 100, 46, 44, 59, 37, 48, 45, 43, 101, 565,8 , 856,18 , 18,7 , 25,11 , 158,12 , 158,12 , 1414,30 , 7494,66 , 7560,101 , 320,12 , 113,7 , 5013,17 , 5030,14 , 5044,22 , 5066,47 , 5113,9 , 2,0 , 2,0 }, // Malayalam/India
+ { 78, 133, 46, 44, 59, 37, 48, 45, 43, 101, 598,10 , 874,23 , 36,5 , 41,9 , 158,12 , 158,12 , 1444,24 , 7661,48 , 7709,85 , 320,12 , 113,7 , 113,7 , 5122,14 , 5136,28 , 5164,63 , 113,7 , 130,2 , 120,2 }, // Maltese/Malta
+ { 80, 100, 46, 44, 59, 37, 48, 45, 43, 101, 677,6 , 109,16 , 18,7 , 25,11 , 158,12 , 158,12 , 194,27 , 7794,87 , 7794,87 , 320,12 , 113,7 , 113,7 , 297,14 , 5227,32 , 5259,53 , 113,7 , 132,5 , 122,5 }, // Marathi/India
+ { 82, 44, 44, 160, 59, 37, 48, 45, 43, 101, 236,8 , 244,18 , 36,5 , 41,9 , 158,12 , 158,12 , 194,27 , 7881,48 , 7929,66 , 320,12 , 113,7 , 113,7 , 297,14 , 5312,21 , 5333,43 , 113,7 , 2,0 , 2,0 }, // Mongolian/China
+ { 82, 143, 44, 160, 59, 37, 48, 45, 43, 101, 236,8 , 244,18 , 36,5 , 41,9 , 158,12 , 158,12 , 194,27 , 7881,48 , 7929,66 , 320,12 , 113,7 , 113,7 , 297,14 , 5312,21 , 5333,43 , 113,7 , 2,0 , 2,0 }, // Mongolian/Mongolia
+ { 84, 100, 46, 44, 59, 37, 2406, 45, 43, 101, 236,8 , 244,18 , 36,5 , 41,9 , 158,12 , 158,12 , 1468,27 , 7995,56 , 8051,85 , 320,12 , 113,7 , 113,7 , 5376,14 , 5390,33 , 5423,54 , 113,7 , 2,0 , 2,0 }, // Nepali/India
+ { 84, 150, 46, 44, 59, 37, 2406, 45, 43, 101, 236,8 , 244,18 , 36,5 , 41,9 , 158,12 , 158,12 , 1468,27 , 7995,56 , 8051,85 , 320,12 , 113,7 , 113,7 , 5376,14 , 5390,33 , 5423,54 , 113,7 , 2,0 , 2,0 }, // Nepali/Nepal
+ { 85, 161, 44, 160, 59, 37, 48, 45, 43, 101, 356,8 , 634,17 , 166,5 , 406,15 , 158,12 , 158,12 , 134,24 , 8136,59 , 8195,83 , 320,12 , 113,7 , 113,7 , 1995,14 , 5477,35 , 2037,51 , 113,7 , 137,9 , 127,11 }, // Norwegian/Norway
+ { 87, 100, 46, 44, 59, 37, 2918, 45, 43, 101, 565,8 , 897,17 , 18,7 , 25,11 , 158,12 , 158,12 , 194,27 , 8278,89 , 8278,89 , 320,12 , 113,7 , 113,7 , 297,14 , 5512,33 , 5545,54 , 113,7 , 2,0 , 2,0 }, // Oriya/India
+ { 88, 1, 1643, 1644, 59, 1642, 1776, 8722, 43, 101, 914,8 , 922,20 , 180,4 , 421,10 , 158,12 , 158,12 , 194,27 , 8367,31 , 8398,68 , 320,12 , 113,7 , 113,7 , 297,14 , 297,14 , 5599,49 , 113,7 , 146,4 , 138,4 }, // Pashto/Afghanistan
+ { 89, 102, 1643, 1644, 1563, 1642, 1776, 8722, 43, 101, 942,6 , 948,21 , 180,4 , 421,10 , 158,12 , 1495,70 , 1565,24 , 8466,74 , 8466,74 , 320,12 , 113,7 , 113,7 , 5648,14 , 5599,49 , 5599,49 , 113,7 , 150,10 , 142,10 }, // Persian/Iran
+ { 89, 1, 1643, 1644, 1563, 1642, 1776, 8722, 43, 101, 942,6 , 948,21 , 180,4 , 421,10 , 158,12 , 1495,70 , 1589,24 , 8540,63 , 8603,68 , 320,12 , 113,7 , 113,7 , 5648,14 , 5599,49 , 5599,49 , 113,7 , 150,10 , 142,10 }, // Persian/Afghanistan
+ { 90, 172, 44, 160, 59, 37, 48, 45, 43, 101, 125,8 , 10,17 , 36,5 , 41,9 , 158,12 , 1613,97 , 1710,24 , 8671,48 , 8719,99 , 320,12 , 113,7 , 113,7 , 5662,14 , 5676,34 , 5710,59 , 113,7 , 0,2 , 0,2 }, // Polish/Poland
+ { 91, 173, 44, 160, 59, 37, 48, 45, 43, 101, 236,8 , 969,27 , 36,5 , 431,16 , 158,12 , 158,12 , 134,24 , 8818,48 , 8866,89 , 320,12 , 113,7 , 113,7 , 5769,14 , 5783,28 , 5811,79 , 113,7 , 160,17 , 152,18 }, // Portuguese/Portugal
+ { 91, 30, 44, 46, 59, 37, 48, 45, 43, 101, 27,8 , 969,27 , 36,5 , 447,18 , 158,12 , 158,12 , 134,24 , 8955,48 , 9003,89 , 320,12 , 113,7 , 113,7 , 5769,14 , 5783,28 , 5811,79 , 113,7 , 0,2 , 0,2 }, // Portuguese/Brazil
+ { 92, 100, 46, 44, 59, 37, 2662, 45, 43, 101, 996,9 , 133,18 , 36,5 , 41,9 , 158,12 , 158,12 , 1734,27 , 9092,68 , 9092,68 , 320,12 , 113,7 , 113,7 , 5890,23 , 5913,38 , 5951,55 , 113,7 , 177,5 , 170,4 }, // Punjabi/India
+ { 92, 163, 46, 44, 59, 37, 2662, 45, 43, 101, 996,9 , 133,18 , 36,5 , 41,9 , 158,12 , 158,12 , 1734,27 , 9092,68 , 9092,68 , 320,12 , 113,7 , 113,7 , 5890,23 , 5913,38 , 5951,55 , 113,7 , 177,5 , 170,4 }, // Punjabi/Pakistan
+ { 95, 141, 44, 46, 59, 37, 48, 45, 43, 101, 1005,10 , 10,17 , 36,5 , 41,9 , 158,12 , 158,12 , 1761,24 , 9160,60 , 9220,98 , 320,12 , 113,7 , 6006,14 , 2477,14 , 6020,16 , 6036,48 , 113,7 , 0,2 , 0,2 }, // Romanian/Moldova
+ { 95, 177, 44, 46, 59, 37, 48, 45, 43, 101, 1005,10 , 10,17 , 36,5 , 41,9 , 158,12 , 158,12 , 1761,24 , 9160,60 , 9220,98 , 320,12 , 113,7 , 6006,14 , 2477,14 , 6020,16 , 6036,48 , 113,7 , 0,2 , 0,2 }, // Romanian/Romania
+ { 96, 178, 44, 160, 59, 37, 48, 45, 43, 101, 356,8 , 1015,22 , 180,4 , 209,8 , 1785,62 , 1847,80 , 1927,24 , 9318,63 , 9381,82 , 320,12 , 113,7 , 6084,62 , 6146,14 , 6160,21 , 6181,62 , 113,7 , 0,2 , 0,2 }, // Russian/RussianFederation
+ { 96, 222, 44, 160, 59, 37, 48, 45, 43, 101, 356,8 , 1015,22 , 36,5 , 41,9 , 1785,62 , 1847,80 , 1927,24 , 9318,63 , 9381,82 , 320,12 , 113,7 , 6084,62 , 6146,14 , 6160,21 , 6181,62 , 113,7 , 0,2 , 0,2 }, // Russian/Ukraine
+ { 99, 100, 46, 44, 59, 37, 2406, 45, 43, 101, 670,7 , 109,16 , 331,8 , 68,12 , 158,12 , 158,12 , 194,27 , 134,27 , 134,27 , 320,12 , 113,7 , 113,7 , 297,14 , 297,14 , 297,14 , 113,7 , 2,0 , 2,0 }, // Sanskrit/India
+ { 100, 241, 44, 46, 59, 37, 48, 45, 43, 1077, 1037,7 , 1044,20 , 166,5 , 171,9 , 158,12 , 158,12 , 1390,24 , 9463,48 , 9511,81 , 320,12 , 113,7 , 113,7 , 6243,14 , 6257,28 , 6285,52 , 113,7 , 182,8 , 174,7 }, // Serbian/SerbiaAndMontenegro
+ { 100, 27, 44, 46, 59, 37, 48, 45, 43, 1077, 125,8 , 1044,20 , 36,5 , 465,39 , 158,12 , 158,12 , 1390,24 , 9463,48 , 9592,83 , 320,12 , 113,7 , 113,7 , 6243,14 , 6337,28 , 6365,54 , 113,7 , 182,8 , 174,7 }, // Serbian/BosniaAndHerzegowina
+ { 100, 238, 44, 46, 59, 37, 48, 45, 43, 1077, 1037,7 , 1044,20 , 166,5 , 171,9 , 158,12 , 158,12 , 1390,24 , 9463,48 , 9511,81 , 320,12 , 113,7 , 113,7 , 6243,14 , 6257,28 , 6285,52 , 113,7 , 182,8 , 174,7 }, // Serbian/Yugoslavia
+ { 101, 241, 46, 44, 59, 37, 48, 45, 43, 101, 99,10 , 244,18 , 36,5 , 41,9 , 158,12 , 158,12 , 1951,24 , 9675,48 , 9723,81 , 320,12 , 113,7 , 113,7 , 1811,14 , 6419,28 , 6447,54 , 113,7 , 0,2 , 0,2 }, // SerboCroatian/SerbiaAndMontenegro
+ { 101, 27, 46, 44, 59, 37, 48, 45, 43, 101, 99,10 , 244,18 , 36,5 , 41,9 , 158,12 , 158,12 , 1951,24 , 9675,48 , 9723,81 , 320,12 , 113,7 , 113,7 , 1811,14 , 6419,28 , 6447,54 , 113,7 , 0,2 , 0,2 }, // SerboCroatian/BosniaAndHerzegowina
+ { 101, 238, 46, 44, 59, 37, 48, 45, 43, 101, 99,10 , 244,18 , 36,5 , 41,9 , 158,12 , 158,12 , 1951,24 , 9675,48 , 9723,81 , 320,12 , 113,7 , 113,7 , 1811,14 , 6419,28 , 6447,54 , 113,7 , 0,2 , 0,2 }, // SerboCroatian/Yugoslavia
+ { 102, 120, 44, 160, 59, 37, 48, 45, 43, 101, 236,8 , 244,18 , 36,5 , 41,9 , 158,12 , 158,12 , 194,27 , 9804,48 , 9852,105 , 320,12 , 113,7 , 113,7 , 297,14 , 6501,27 , 6528,61 , 113,7 , 2,0 , 2,0 }, // Sesotho/Lesotho
+ { 102, 195, 44, 160, 59, 37, 48, 45, 43, 101, 236,8 , 244,18 , 36,5 , 41,9 , 158,12 , 158,12 , 194,27 , 9804,48 , 9852,105 , 320,12 , 113,7 , 113,7 , 297,14 , 6501,27 , 6528,61 , 113,7 , 2,0 , 2,0 }, // Sesotho/SouthAfrica
+ { 103, 195, 44, 160, 59, 37, 48, 45, 43, 101, 236,8 , 244,18 , 36,5 , 41,9 , 158,12 , 158,12 , 194,27 , 9957,48 , 10005,117 , 320,12 , 113,7 , 113,7 , 297,14 , 6589,27 , 6616,64 , 113,7 , 2,0 , 2,0 }, // Setswana/SouthAfrica
+ { 106, 198, 46, 44, 59, 37, 48, 45, 43, 101, 72,10 , 1064,17 , 18,7 , 25,11 , 158,12 , 158,12 , 1975,32 , 10122,54 , 10176,92 , 320,12 , 113,7 , 113,7 , 6680,19 , 6699,30 , 6729,62 , 113,7 , 190,5 , 181,4 }, // Singhalese/SriLanka
+ { 107, 195, 44, 160, 59, 37, 48, 45, 43, 101, 236,8 , 244,18 , 36,5 , 41,9 , 158,12 , 158,12 , 194,27 , 10268,48 , 10316,114 , 320,12 , 113,7 , 113,7 , 297,14 , 6791,27 , 6818,68 , 113,7 , 2,0 , 2,0 }, // Siswati/SouthAfrica
+ { 107, 204, 44, 160, 59, 37, 48, 45, 43, 101, 236,8 , 244,18 , 36,5 , 41,9 , 158,12 , 158,12 , 194,27 , 10268,48 , 10316,114 , 320,12 , 113,7 , 113,7 , 297,14 , 6791,27 , 6818,68 , 113,7 , 2,0 , 2,0 }, // Siswati/Swaziland
+ { 108, 191, 44, 160, 59, 37, 48, 45, 43, 101, 626,8 , 524,18 , 180,4 , 209,8 , 158,12 , 158,12 , 1951,24 , 10430,48 , 10478,82 , 320,12 , 113,7 , 113,7 , 6886,14 , 6900,21 , 6921,52 , 113,7 , 2,0 , 2,0 }, // Slovak/Slovakia
+ { 109, 192, 44, 46, 59, 37, 48, 45, 43, 101, 382,6 , 651,19 , 180,4 , 209,8 , 158,12 , 158,12 , 1951,24 , 9675,48 , 10560,86 , 320,12 , 113,7 , 113,7 , 6973,14 , 6987,28 , 7015,52 , 113,7 , 2,0 , 2,0 }, // Slovenian/Slovenia
+ { 110, 194, 46, 44, 59, 37, 48, 45, 43, 101, 27,8 , 53,19 , 18,7 , 25,11 , 158,12 , 158,12 , 2007,24 , 10646,48 , 10694,189 , 320,12 , 113,7 , 113,7 , 7067,14 , 7081,28 , 7109,47 , 113,7 , 195,2 , 185,2 }, // Somali/Somalia
+ { 110, 59, 46, 44, 59, 37, 48, 45, 43, 101, 27,8 , 53,19 , 18,7 , 25,11 , 158,12 , 158,12 , 2007,24 , 10646,48 , 10694,189 , 320,12 , 113,7 , 113,7 , 7067,14 , 7081,28 , 7109,47 , 113,7 , 195,2 , 185,2 }, // Somali/Djibouti
+ { 110, 69, 46, 44, 59, 37, 48, 45, 43, 101, 27,8 , 53,19 , 18,7 , 25,11 , 158,12 , 158,12 , 2007,24 , 10646,48 , 10694,189 , 320,12 , 113,7 , 113,7 , 7067,14 , 7081,28 , 7109,47 , 113,7 , 195,2 , 185,2 }, // Somali/Ethiopia
+ { 110, 111, 46, 44, 59, 37, 48, 45, 43, 101, 27,8 , 53,19 , 18,7 , 25,11 , 158,12 , 158,12 , 2007,24 , 10646,48 , 10694,189 , 320,12 , 113,7 , 113,7 , 7067,14 , 7081,28 , 7109,47 , 113,7 , 195,2 , 185,2 }, // Somali/Kenya
+ { 111, 197, 44, 46, 59, 37, 48, 45, 43, 101, 27,8 , 427,26 , 36,5 , 68,12 , 158,12 , 158,12 , 2031,24 , 10883,48 , 10931,89 , 320,12 , 113,7 , 113,7 , 2477,14 , 7156,28 , 7184,53 , 113,7 , 58,4 , 55,4 }, // Spanish/Spain
+ { 111, 10, 44, 46, 59, 37, 48, 45, 43, 101, 27,8 , 427,26 , 36,5 , 504,13 , 158,12 , 158,12 , 2031,24 , 10883,48 , 10931,89 , 320,12 , 113,7 , 113,7 , 2477,14 , 7156,28 , 7184,53 , 113,7 , 58,4 , 55,4 }, // Spanish/Argentina
+ { 111, 26, 44, 46, 59, 37, 48, 45, 43, 101, 27,8 , 427,26 , 36,5 , 68,12 , 158,12 , 158,12 , 2031,24 , 10883,48 , 10931,89 , 320,12 , 113,7 , 113,7 , 2477,14 , 7156,28 , 7184,53 , 113,7 , 58,4 , 55,4 }, // Spanish/Bolivia
+ { 111, 43, 44, 46, 59, 37, 48, 45, 43, 101, 565,8 , 427,26 , 180,4 , 41,9 , 158,12 , 158,12 , 2031,24 , 10883,48 , 10931,89 , 320,12 , 113,7 , 113,7 , 2477,14 , 7156,28 , 7184,53 , 113,7 , 58,4 , 55,4 }, // Spanish/Chile
+ { 111, 47, 44, 46, 59, 37, 48, 45, 43, 101, 573,7 , 427,26 , 180,4 , 41,9 , 158,12 , 158,12 , 2031,24 , 10883,48 , 10931,89 , 320,12 , 113,7 , 113,7 , 2477,14 , 7156,28 , 7184,53 , 113,7 , 58,4 , 55,4 }, // Spanish/Colombia
+ { 111, 52, 44, 46, 59, 37, 48, 45, 43, 101, 27,8 , 427,26 , 36,5 , 68,12 , 158,12 , 158,12 , 2031,24 , 10883,48 , 10931,89 , 320,12 , 113,7 , 113,7 , 2477,14 , 7156,28 , 7184,53 , 113,7 , 58,4 , 55,4 }, // Spanish/CostaRica
+ { 111, 61, 46, 44, 59, 37, 48, 45, 43, 101, 27,8 , 427,26 , 36,5 , 68,12 , 158,12 , 158,12 , 2031,24 , 10883,48 , 10931,89 , 320,12 , 113,7 , 113,7 , 2477,14 , 7156,28 , 7184,53 , 113,7 , 58,4 , 55,4 }, // Spanish/DominicanRepublic
+ { 111, 63, 44, 46, 59, 37, 48, 45, 43, 101, 27,8 , 427,26 , 180,4 , 41,9 , 158,12 , 158,12 , 2031,24 , 10883,48 , 10931,89 , 320,12 , 113,7 , 113,7 , 2477,14 , 7156,28 , 7184,53 , 113,7 , 58,4 , 55,4 }, // Spanish/Ecuador
+ { 111, 65, 46, 44, 59, 37, 48, 45, 43, 101, 27,8 , 427,26 , 36,5 , 68,12 , 158,12 , 158,12 , 2031,24 , 10883,48 , 10931,89 , 320,12 , 113,7 , 113,7 , 2477,14 , 7156,28 , 7184,53 , 113,7 , 58,4 , 55,4 }, // Spanish/ElSalvador
+ { 111, 90, 46, 44, 59, 37, 48, 45, 43, 101, 573,7 , 427,26 , 36,5 , 68,12 , 158,12 , 158,12 , 2031,24 , 10883,48 , 10931,89 , 320,12 , 113,7 , 113,7 , 2477,14 , 7156,28 , 7184,53 , 113,7 , 58,4 , 55,4 }, // Spanish/Guatemala
+ { 111, 96, 46, 44, 59, 37, 48, 45, 43, 101, 27,8 , 1081,27 , 36,5 , 68,12 , 158,12 , 158,12 , 2031,24 , 10883,48 , 10931,89 , 320,12 , 113,7 , 113,7 , 2477,14 , 7156,28 , 7184,53 , 113,7 , 58,4 , 55,4 }, // Spanish/Honduras
+ { 111, 139, 46, 44, 59, 37, 48, 45, 43, 101, 27,8 , 427,26 , 36,5 , 68,12 , 158,12 , 158,12 , 2031,24 , 10883,48 , 10931,89 , 320,12 , 113,7 , 113,7 , 2477,14 , 7156,28 , 7184,53 , 113,7 , 58,4 , 55,4 }, // Spanish/Mexico
+ { 111, 155, 46, 44, 59, 37, 48, 45, 43, 101, 27,8 , 427,26 , 36,5 , 68,12 , 158,12 , 158,12 , 2031,24 , 10883,48 , 10931,89 , 320,12 , 113,7 , 113,7 , 2477,14 , 7156,28 , 7184,53 , 113,7 , 58,4 , 55,4 }, // Spanish/Nicaragua
+ { 111, 166, 46, 44, 59, 37, 48, 45, 43, 101, 202,8 , 427,26 , 36,5 , 68,12 , 158,12 , 158,12 , 2031,24 , 10883,48 , 10931,89 , 320,12 , 113,7 , 113,7 , 2477,14 , 7156,28 , 7184,53 , 113,7 , 58,4 , 55,4 }, // Spanish/Panama
+ { 111, 168, 44, 46, 59, 37, 48, 45, 43, 101, 27,8 , 427,26 , 36,5 , 68,12 , 158,12 , 158,12 , 2031,24 , 10883,48 , 10931,89 , 320,12 , 113,7 , 113,7 , 2477,14 , 7156,28 , 7184,53 , 113,7 , 58,4 , 55,4 }, // Spanish/Paraguay
+ { 111, 169, 46, 44, 59, 37, 48, 45, 43, 101, 573,7 , 427,26 , 36,5 , 517,13 , 158,12 , 158,12 , 2031,24 , 10883,48 , 10931,89 , 320,12 , 113,7 , 113,7 , 2477,14 , 7156,28 , 7184,53 , 113,7 , 58,4 , 55,4 }, // Spanish/Peru
+ { 111, 174, 46, 44, 59, 37, 48, 45, 43, 101, 202,8 , 427,26 , 36,5 , 68,12 , 158,12 , 158,12 , 2031,24 , 10883,48 , 10931,89 , 320,12 , 113,7 , 113,7 , 2477,14 , 7156,28 , 7184,53 , 113,7 , 58,4 , 55,4 }, // Spanish/PuertoRico
+ { 111, 225, 46, 44, 59, 37, 48, 45, 43, 101, 580,6 , 427,26 , 18,7 , 25,11 , 158,12 , 158,12 , 2031,24 , 10883,48 , 10931,89 , 320,12 , 113,7 , 113,7 , 2477,14 , 7156,28 , 7184,53 , 113,7 , 58,4 , 55,4 }, // Spanish/UnitedStates
+ { 111, 227, 44, 46, 59, 37, 48, 45, 43, 101, 27,8 , 427,26 , 36,5 , 68,12 , 158,12 , 158,12 , 2031,24 , 10883,48 , 10931,89 , 320,12 , 113,7 , 113,7 , 2477,14 , 7156,28 , 7184,53 , 113,7 , 58,4 , 55,4 }, // Spanish/Uruguay
+ { 111, 231, 44, 46, 59, 37, 48, 45, 43, 101, 27,8 , 427,26 , 36,5 , 68,12 , 158,12 , 158,12 , 2031,24 , 10883,48 , 10931,89 , 320,12 , 113,7 , 113,7 , 2477,14 , 7156,28 , 7184,53 , 113,7 , 58,4 , 55,4 }, // Spanish/Venezuela
+ { 113, 111, 46, 44, 59, 37, 48, 45, 43, 101, 236,8 , 244,18 , 36,5 , 41,9 , 158,12 , 158,12 , 194,27 , 11020,48 , 11068,84 , 320,12 , 113,7 , 113,7 , 297,14 , 7237,28 , 7265,60 , 113,7 , 2,0 , 2,0 }, // Swahili/Kenya
+ { 113, 210, 46, 44, 59, 37, 48, 45, 43, 101, 236,8 , 244,18 , 36,5 , 41,9 , 158,12 , 158,12 , 194,27 , 11020,48 , 11068,84 , 320,12 , 113,7 , 113,7 , 297,14 , 7237,28 , 7265,60 , 113,7 , 2,0 , 2,0 }, // Swahili/Tanzania
+ { 114, 205, 44, 160, 59, 37, 48, 8722, 43, 101, 99,10 , 1108,22 , 166,5 , 406,15 , 158,12 , 158,12 , 134,24 , 3129,48 , 11152,86 , 320,12 , 113,7 , 113,7 , 1995,14 , 7325,29 , 7354,50 , 113,7 , 197,2 , 187,2 }, // Swedish/Sweden
+ { 114, 73, 44, 160, 59, 37, 48, 8722, 43, 101, 99,10 , 1108,22 , 166,5 , 406,15 , 158,12 , 158,12 , 134,24 , 3129,48 , 11152,86 , 320,12 , 113,7 , 113,7 , 1995,14 , 7325,29 , 7354,50 , 113,7 , 197,2 , 187,2 }, // Swedish/Finland
+ { 116, 209, 46, 44, 59, 37, 48, 45, 43, 101, 236,8 , 244,18 , 36,5 , 41,9 , 158,12 , 158,12 , 194,27 , 11238,48 , 11286,71 , 320,12 , 113,7 , 113,7 , 297,14 , 7404,28 , 7432,55 , 113,7 , 2,0 , 2,0 }, // Tajik/Tajikistan
+ { 117, 100, 46, 44, 59, 37, 48, 45, 43, 101, 677,6 , 109,16 , 18,7 , 25,11 , 158,12 , 158,12 , 194,27 , 11357,58 , 11415,86 , 320,12 , 113,7 , 113,7 , 297,14 , 7487,20 , 7507,49 , 113,7 , 199,4 , 189,4 }, // Tamil/India
+ { 118, 178, 44, 160, 59, 37, 48, 45, 43, 101, 1005,10 , 1130,11 , 180,4 , 25,11 , 158,12 , 158,12 , 194,27 , 134,27 , 134,27 , 320,12 , 113,7 , 113,7 , 297,14 , 297,14 , 297,14 , 113,7 , 2,0 , 2,0 }, // Tatar/RussianFederation
+ { 119, 100, 46, 44, 59, 37, 3174, 45, 43, 101, 565,8 , 109,16 , 18,7 , 25,11 , 158,12 , 158,12 , 2055,30 , 11501,86 , 11501,86 , 320,12 , 113,7 , 113,7 , 7556,18 , 7574,32 , 7606,60 , 113,7 , 203,10 , 193,8 }, // Telugu/India
+ { 120, 211, 46, 44, 59, 37, 48, 45, 43, 101, 388,8 , 1141,21 , 180,4 , 530,26 , 158,12 , 158,12 , 2085,63 , 11587,63 , 11650,98 , 320,12 , 113,7 , 113,7 , 7666,14 , 7680,23 , 7703,68 , 7771,9 , 213,10 , 201,10 }, // Thai/Thailand
+ { 122, 67, 46, 44, 59, 37, 48, 45, 43, 101, 27,8 , 1162,25 , 18,7 , 25,11 , 158,12 , 158,12 , 245,24 , 11748,46 , 11794,54 , 320,12 , 113,7 , 113,7 , 7780,14 , 7794,28 , 7822,29 , 113,7 , 223,7 , 211,7 }, // Tigrinya/Eritrea
+ { 122, 69, 46, 44, 59, 37, 48, 45, 43, 101, 27,8 , 1187,25 , 18,7 , 25,11 , 158,12 , 158,12 , 245,24 , 893,46 , 939,62 , 320,12 , 113,7 , 113,7 , 7780,14 , 7851,28 , 7879,29 , 113,7 , 223,7 , 211,7 }, // Tigrinya/Ethiopia
+ { 123, 214, 46, 44, 59, 37, 48, 45, 43, 101, 1212,10 , 109,16 , 36,5 , 41,9 , 158,12 , 158,12 , 2148,24 , 11848,51 , 11899,87 , 320,12 , 113,7 , 113,7 , 7908,14 , 7922,29 , 7951,60 , 113,7 , 2,0 , 2,0 }, // Tonga/Tonga
+ { 124, 195, 44, 160, 59, 37, 48, 45, 43, 101, 236,8 , 244,18 , 36,5 , 41,9 , 158,12 , 158,12 , 194,27 , 11986,48 , 12034,122 , 320,12 , 113,7 , 113,7 , 297,14 , 8011,27 , 8038,72 , 113,7 , 2,0 , 2,0 }, // Tsonga/SouthAfrica
+ { 125, 217, 44, 46, 59, 37, 48, 45, 43, 101, 1005,10 , 1222,17 , 36,5 , 41,9 , 158,12 , 158,12 , 2172,24 , 12156,48 , 12204,75 , 320,12 , 113,7 , 113,7 , 8110,14 , 8124,28 , 8152,54 , 113,7 , 0,2 , 0,2 }, // Turkish/Turkey
+ { 128, 44, 46, 44, 59, 37, 48, 45, 43, 101, 236,8 , 244,18 , 36,5 , 41,9 , 158,12 , 158,12 , 194,27 , 134,27 , 134,27 , 320,12 , 113,7 , 113,7 , 297,14 , 297,14 , 297,14 , 113,7 , 2,0 , 2,0 }, // Uigur/China
+ { 129, 222, 44, 160, 59, 37, 48, 45, 43, 101, 356,8 , 1239,22 , 36,5 , 41,9 , 2196,48 , 2244,95 , 2339,24 , 12279,67 , 12346,87 , 320,12 , 113,7 , 113,7 , 8206,14 , 8220,21 , 8241,56 , 113,7 , 230,2 , 218,2 }, // Ukrainian/Ukraine
+ { 130, 100, 46, 44, 59, 37, 48, 45, 43, 1602, 293,6 , 608,18 , 18,7 , 25,11 , 158,12 , 158,12 , 1589,24 , 320,12 , 12433,67 , 320,12 , 113,7 , 113,7 , 297,14 , 113,7 , 8297,36 , 8333,14 , 2,0 , 2,0 }, // Urdu/India
+ { 130, 163, 46, 44, 59, 37, 48, 45, 43, 1602, 293,6 , 608,18 , 18,7 , 25,11 , 158,12 , 158,12 , 1589,24 , 320,12 , 12433,67 , 320,12 , 113,7 , 113,7 , 297,14 , 113,7 , 8297,36 , 8333,14 , 2,0 , 2,0 }, // Urdu/Pakistan
+ { 131, 228, 44, 160, 59, 37, 48, 45, 43, 101, 236,8 , 244,18 , 36,5 , 41,9 , 158,12 , 158,12 , 1927,24 , 11238,48 , 12500,115 , 320,12 , 113,7 , 113,7 , 8347,14 , 8361,28 , 8389,53 , 113,7 , 2,0 , 2,0 }, // Uzbek/Uzbekistan
+ { 131, 1, 44, 160, 59, 37, 48, 45, 43, 101, 236,8 , 244,18 , 36,5 , 41,9 , 158,12 , 158,12 , 1927,24 , 11238,48 , 12500,115 , 320,12 , 113,7 , 113,7 , 8347,14 , 8361,28 , 8389,53 , 113,7 , 2,0 , 2,0 }, // Uzbek/Afghanistan
+ { 132, 232, 44, 46, 59, 37, 48, 45, 43, 101, 598,10 , 1261,31 , 36,5 , 41,9 , 158,12 , 158,12 , 194,27 , 12615,75 , 12690,130 , 320,12 , 113,7 , 113,7 , 297,14 , 8442,33 , 8475,55 , 113,7 , 232,2 , 220,2 }, // Vietnamese/VietNam
+ { 134, 224, 46, 44, 59, 37, 48, 45, 43, 101, 598,10 , 133,18 , 18,7 , 25,11 , 2363,25 , 2388,22 , 2410,24 , 12820,62 , 12882,86 , 320,12 , 8530,10 , 113,7 , 8540,14 , 8554,30 , 8584,77 , 113,7 , 2,0 , 2,0 }, // Welsh/UnitedKingdom
+ { 135, 187, 46, 44, 59, 37, 48, 45, 43, 101, 236,8 , 244,18 , 36,5 , 41,9 , 158,12 , 158,12 , 194,27 , 134,27 , 134,27 , 320,12 , 113,7 , 113,7 , 297,14 , 297,14 , 297,14 , 113,7 , 2,0 , 2,0 }, // Wolof/Senegal
+ { 136, 195, 44, 160, 59, 37, 48, 45, 43, 101, 236,8 , 244,18 , 36,5 , 41,9 , 158,12 , 158,12 , 194,27 , 12968,48 , 13016,91 , 320,12 , 113,7 , 113,7 , 297,14 , 8661,28 , 8689,61 , 113,7 , 2,0 , 2,0 }, // Xhosa/SouthAfrica
+ { 138, 157, 46, 44, 59, 37, 48, 45, 43, 101, 236,8 , 244,18 , 36,5 , 41,9 , 158,12 , 158,12 , 194,27 , 13107,73 , 13180,121 , 320,12 , 113,7 , 113,7 , 297,14 , 8750,50 , 8800,80 , 113,7 , 234,5 , 222,5 }, // Yoruba/Nigeria
+ { 140, 195, 44, 160, 59, 37, 48, 45, 43, 101, 99,10 , 82,17 , 18,7 , 25,11 , 158,12 , 2434,104 , 134,24 , 13301,48 , 13349,90 , 320,12 , 113,7 , 113,7 , 8880,14 , 8894,28 , 8922,68 , 113,7 , 2,0 , 2,0 }, // Zulu/SouthAfrica
+ { 141, 161, 44, 160, 59, 37, 48, 8722, 43, 101, 356,8 , 634,17 , 166,5 , 406,15 , 158,12 , 158,12 , 134,24 , 3547,48 , 8195,83 , 320,12 , 8990,13 , 113,7 , 1995,14 , 9003,22 , 9025,51 , 113,7 , 137,9 , 127,11 }, // Nynorsk/Norway
+ { 142, 27, 44, 46, 59, 37, 48, 45, 43, 101, 236,8 , 244,18 , 36,5 , 41,9 , 158,12 , 158,12 , 194,27 , 13439,48 , 13487,83 , 320,12 , 113,7 , 113,7 , 297,14 , 9076,28 , 9104,58 , 113,7 , 2,0 , 2,0 }, // Bosnian/BosniaAndHerzegowina
+ { 143, 131, 46, 44, 1548, 37, 1632, 45, 43, 101, 677,6 , 109,16 , 331,8 , 68,12 , 158,12 , 158,12 , 194,27 , 134,27 , 134,27 , 320,12 , 113,7 , 113,7 , 297,14 , 297,14 , 297,14 , 113,7 , 2,0 , 2,0 }, // Divehi/Maldives
+ { 144, 224, 46, 44, 59, 37, 48, 45, 43, 101, 27,8 , 82,17 , 36,5 , 41,9 , 158,12 , 158,12 , 194,27 , 13570,102 , 13672,140 , 320,12 , 113,7 , 113,7 , 297,14 , 9162,30 , 9192,57 , 113,7 , 58,4 , 55,4 }, // Manx/UnitedKingdom
+ { 145, 224, 46, 44, 59, 37, 48, 45, 43, 101, 598,10 , 109,16 , 36,5 , 41,9 , 158,12 , 158,12 , 194,27 , 13812,46 , 13858,124 , 320,12 , 113,7 , 113,7 , 297,14 , 9249,28 , 9277,60 , 113,7 , 58,4 , 55,4 }, // Cornish/UnitedKingdom
+ { 146, 83, 46, 44, 59, 37, 48, 45, 43, 101, 236,8 , 244,18 , 36,5 , 41,9 , 158,12 , 158,12 , 194,27 , 13982,48 , 14030,192 , 320,12 , 113,7 , 113,7 , 9337,14 , 9351,28 , 9379,49 , 113,7 , 2,0 , 2,0 }, // Akan/Ghana
+ { 147, 100, 46, 44, 59, 37, 48, 45, 43, 101, 677,6 , 109,16 , 18,7 , 25,11 , 158,12 , 158,12 , 194,27 , 14222,85 , 7794,87 , 320,12 , 113,7 , 113,7 , 297,14 , 5227,32 , 9428,55 , 113,7 , 132,5 , 122,5 }, // Konkani/India
+ { 148, 83, 46, 44, 59, 37, 48, 45, 43, 101, 236,8 , 244,18 , 36,5 , 41,9 , 158,12 , 158,12 , 194,27 , 14307,48 , 14355,94 , 320,12 , 113,7 , 113,7 , 297,14 , 9483,26 , 9509,34 , 113,7 , 2,0 , 2,0 }, // Ga/Ghana
+ { 149, 157, 46, 44, 59, 37, 48, 45, 43, 101, 236,8 , 244,18 , 36,5 , 41,9 , 158,12 , 158,12 , 194,27 , 14449,48 , 14497,86 , 320,12 , 113,7 , 113,7 , 297,14 , 9543,29 , 9572,57 , 113,7 , 2,0 , 2,0 }, // Igbo/Nigeria
+ { 150, 111, 46, 44, 59, 37, 48, 45, 43, 101, 236,8 , 244,18 , 36,5 , 41,9 , 158,12 , 158,12 , 194,27 , 14583,189 , 14583,189 , 320,12 , 113,7 , 113,7 , 297,14 , 9629,28 , 9657,59 , 113,7 , 2,0 , 2,0 }, // Kamba/Kenya
+ { 151, 207, 46, 44, 59, 37, 48, 45, 43, 101, 598,10 , 1292,13 , 389,4 , 25,11 , 158,12 , 158,12 , 194,27 , 14772,65 , 14837,65 , 320,12 , 113,7 , 113,7 , 297,14 , 297,14 , 297,14 , 113,7 , 2,0 , 2,0 }, // Syriac/SyrianArabRepublic
+ { 152, 67, 46, 44, 59, 37, 48, 45, 43, 101, 27,8 , 1305,24 , 18,7 , 25,11 , 158,12 , 158,12 , 2538,24 , 14902,47 , 14949,77 , 320,12 , 113,7 , 113,7 , 9716,14 , 9730,26 , 9756,43 , 113,7 , 2,0 , 2,0 }, // Blin/Eritrea
+ { 153, 67, 46, 4808, 59, 37, 48, 45, 43, 101, 27,8 , 1329,25 , 18,7 , 25,11 , 158,12 , 158,12 , 2562,24 , 15026,48 , 15074,49 , 320,12 , 113,7 , 113,7 , 9799,14 , 9813,28 , 9841,29 , 113,7 , 2,0 , 2,0 }, // Geez/Eritrea
+ { 153, 69, 46, 4808, 59, 37, 48, 45, 43, 101, 27,8 , 1329,25 , 18,7 , 25,11 , 158,12 , 158,12 , 2562,24 , 15026,48 , 15074,49 , 320,12 , 113,7 , 113,7 , 9799,14 , 9813,28 , 9841,29 , 113,7 , 2,0 , 2,0 }, // Geez/Ethiopia
+ { 154, 53, 46, 44, 59, 37, 48, 45, 43, 101, 236,8 , 244,18 , 36,5 , 41,9 , 158,12 , 158,12 , 194,27 , 15123,48 , 15171,124 , 320,12 , 113,7 , 113,7 , 297,14 , 9870,28 , 9898,54 , 113,7 , 2,0 , 2,0 }, // Koro/IvoryCoast
+ { 155, 69, 46, 44, 59, 37, 48, 45, 43, 101, 27,8 , 53,19 , 18,7 , 25,11 , 158,12 , 158,12 , 134,24 , 0,48 , 48,86 , 320,12 , 113,7 , 113,7 , 9952,14 , 9966,28 , 9994,51 , 113,7 , 2,0 , 2,0 }, // Sidamo/Ethiopia
+ { 156, 157, 46, 44, 59, 37, 48, 45, 43, 101, 236,8 , 244,18 , 36,5 , 41,9 , 158,12 , 158,12 , 194,27 , 15295,59 , 15354,129 , 320,12 , 113,7 , 113,7 , 297,14 , 10045,35 , 10080,87 , 113,7 , 2,0 , 2,0 }, // Atsam/Nigeria
+ { 157, 67, 46, 44, 59, 37, 48, 45, 43, 101, 27,8 , 1354,23 , 18,7 , 25,11 , 158,12 , 158,12 , 245,24 , 893,46 , 939,62 , 320,12 , 113,7 , 113,7 , 10167,14 , 10181,27 , 10208,41 , 113,7 , 2,0 , 2,0 }, // Tigre/Eritrea
+ { 158, 157, 46, 44, 59, 37, 48, 45, 43, 101, 236,8 , 244,18 , 36,5 , 41,9 , 158,12 , 158,12 , 194,27 , 15483,57 , 15540,178 , 320,12 , 113,7 , 113,7 , 297,14 , 10249,28 , 10277,44 , 113,7 , 2,0 , 2,0 }, // Jju/Nigeria
+ { 159, 106, 46, 44, 59, 37, 48, 45, 43, 101, 573,7 , 1377,27 , 36,5 , 41,9 , 158,12 , 158,12 , 2586,24 , 15718,48 , 15766,77 , 320,12 , 113,7 , 113,7 , 2477,14 , 10321,28 , 10349,50 , 113,7 , 2,0 , 2,0 }, // Friulian/Italy
+ { 160, 195, 44, 160, 59, 37, 48, 45, 43, 101, 236,8 , 244,18 , 36,5 , 41,9 , 158,12 , 158,12 , 194,27 , 15843,48 , 15891,111 , 320,12 , 113,7 , 113,7 , 297,14 , 10399,27 , 10426,70 , 113,7 , 2,0 , 2,0 }, // Venda/SouthAfrica
+ { 161, 83, 46, 44, 59, 37, 48, 45, 43, 101, 236,8 , 244,18 , 36,5 , 41,9 , 158,12 , 158,12 , 2610,24 , 16002,48 , 16050,87 , 320,12 , 113,7 , 113,7 , 10496,14 , 10510,32 , 10542,44 , 113,7 , 2,0 , 2,0 }, // Ewe/Ghana
+ { 161, 212, 46, 44, 59, 37, 48, 45, 43, 101, 236,8 , 244,18 , 36,5 , 41,9 , 158,12 , 158,12 , 2610,24 , 16002,48 , 16050,87 , 320,12 , 113,7 , 113,7 , 10496,14 , 10510,32 , 10542,44 , 113,7 , 2,0 , 2,0 }, // Ewe/Togo
+ { 163, 225, 46, 44, 59, 37, 48, 45, 43, 101, 293,6 , 10,17 , 18,7 , 25,11 , 158,12 , 158,12 , 194,27 , 16137,59 , 16196,95 , 320,12 , 113,7 , 113,7 , 297,14 , 10586,21 , 10607,57 , 113,7 , 2,0 , 2,0 }, // Hawaiian/UnitedStates
+ { 164, 157, 46, 44, 59, 37, 48, 45, 43, 101, 236,8 , 244,18 , 36,5 , 41,9 , 158,12 , 158,12 , 194,27 , 16291,48 , 16339,153 , 320,12 , 113,7 , 113,7 , 297,14 , 10664,28 , 10692,42 , 113,7 , 2,0 , 2,0 }, // Tyap/Nigeria
+ { 165, 129, 46, 44, 59, 37, 48, 45, 43, 101, 236,8 , 244,18 , 36,5 , 41,9 , 158,12 , 158,12 , 194,27 , 16492,48 , 16540,91 , 320,12 , 113,7 , 113,7 , 297,14 , 10734,28 , 10762,67 , 113,7 , 2,0 , 2,0 }, // Chewa/Malawi
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 } // trailing 0s
+};
+
+static const ushort date_format_data[] = {
+0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x20, 0x4d, 0x4d,
+0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x2f, 0x4d, 0x4d, 0x2f, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x2c,
+0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x64, 0x2c, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x4d,
+0x4d, 0x4d, 0x4d, 0x20, 0x64, 0x64, 0x2c, 0x20, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x2f, 0x4d, 0x4d, 0x2f,
+0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x20, 0x64, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x79,
+0x79, 0x79, 0x79, 0x2d, 0x4d, 0x4d, 0x2d, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x20, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d,
+0x20, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x2d, 0x4d, 0x4d, 0x2d, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64,
+0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x1363, 0x20, 0x64, 0x64, 0x20,
+0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x1240, 0x1295, 0x20, 0x79, 0x79, 0x79, 0x79, 0x20, 0x47, 0x64, 0x200f, 0x2f, 0x4d, 0x200f, 0x2f,
+0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x60c, 0x20, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x60c, 0x20, 0x79, 0x79,
+0x79, 0x79, 0x4d, 0x4d, 0x2f, 0x64, 0x64, 0x2f, 0x79, 0x79, 0x64, 0x2d, 0x4d, 0x2d, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64,
+0x64, 0x64, 0x2c, 0x20, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x2c, 0x20, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x2f, 0x4d,
+0x4d, 0x2f, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x79, 0x79, 0x79, 0x79, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20,
+0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x79, 0x79, 0x79, 0x79, 0x27, 0x65, 0x6b, 0x6f, 0x27, 0x20, 0x4d, 0x4d,
+0x4d, 0x4d, 0x27, 0x72, 0x65, 0x6e, 0x27, 0x20, 0x64, 0x64, 0x27, 0x61, 0x27, 0x64, 0x2f, 0x4d, 0x2f, 0x79, 0x79, 0xf66,
+0xfa4, 0xfb1, 0xf72, 0xf0b, 0xf63, 0xf7c, 0xf0b, 0x20, 0x79, 0x79, 0x79, 0x79, 0x20, 0xf5f, 0xfb3, 0xf0b, 0x20, 0x4d, 0x4d, 0x20,
+0xf5a, 0xf7a, 0xf66, 0xf0b, 0x20, 0x64, 0x64, 0xf66, 0xfa4, 0xfb1, 0xf72, 0xf0b, 0xf63, 0xf7c, 0xf0b, 0x79, 0x79, 0x79, 0x79, 0x20,
+0xf5f, 0xfb3, 0xf0b, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0xf5a, 0xf7a, 0xf66, 0xf0b, 0x20, 0x64, 0x64, 0x64, 0x64, 0x2e, 0x4d,
+0x4d, 0x2e, 0x79, 0x79, 0x64, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x2c, 0x20, 0x64, 0x64,
+0x64, 0x64, 0x64, 0x2e, 0x4d, 0x2e, 0x79, 0x79, 0x64, 0x2f, 0x4d, 0x2f, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64,
+0x20, 0x1790, 0x17d2, 0x1784, 0x17c3, 0x20, 0x64, 0x20, 0x1781, 0x17c2, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x1786, 0x17d2, 0x1793, 0x17b6,
+0x17c6, 0x20, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x20, 0x64, 0x20, 0x27, 0x64, 0x65, 0x27, 0x20, 0x4d,
+0x4d, 0x4d, 0x4d, 0x20, 0x27, 0x64, 0x65, 0x27, 0x20, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x2d, 0x4d, 0x2d, 0x64, 0x79,
+0x79, 0x79, 0x79, 0x5e74, 0x4d, 0x6708, 0x64, 0x65e5, 0x64, 0x64, 0x64, 0x64, 0x79, 0x79, 0x5e74, 0x4d, 0x6708, 0x64, 0x65e5, 0x79,
+0x79, 0x79, 0x79, 0x5e74, 0x4d, 0x4d, 0x6708, 0x64, 0x64, 0x65e5, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x2e, 0x4d, 0x4d, 0x2e,
+0x79, 0x79, 0x79, 0x79, 0x2e, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x2e, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79,
+0x79, 0x79, 0x79, 0x2e, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x2e, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79,
+0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x20, 0x27, 0x64, 0x65, 0x6e, 0x27, 0x20, 0x64, 0x2e, 0x20, 0x4d, 0x4d, 0x4d, 0x4d,
+0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x2d, 0x4d, 0x4d, 0x2d, 0x79, 0x79, 0x64, 0x2f, 0x4d, 0x4d, 0x2f, 0x79, 0x79,
+0x4d, 0x2f, 0x64, 0x2f, 0x79, 0x79, 0x64, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64,
+0x2f, 0x4d, 0x4d, 0x2f, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x2c, 0x20, 0x4d, 0x4d, 0x4d,
+0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x2e, 0x4d, 0x2e, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x20, 0x64,
+0x2e, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x64, 0x2e,
+0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x2d, 0x4d, 0x4d, 0x2d, 0x79, 0x79, 0x64, 0x2d, 0x4d,
+0x2d, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x2e, 0x4d, 0x4d, 0x2e, 0x64, 0x64, 0x2e, 0x79, 0x79, 0x79, 0x79, 0x2e, 0x20,
+0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x64, 0x2e, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20,
+0x79, 0x79, 0x79, 0x79, 0x20, 0x27, 0x436, 0x27, 0x2e, 0x79, 0x79, 0x2e, 0x20, 0x4d, 0x2e, 0x20, 0x64, 0x2e, 0x79, 0x79,
+0x79, 0x79, 0xb144, 0x20, 0x4d, 0xc6d4, 0x20, 0x64, 0xc77c, 0x20, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0xe97, 0xeb5,
+0x20, 0x20, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x47, 0x20, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x2e, 0x64, 0x2e,
+0x4d, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x79, 0x79, 0x79, 0x79, 0x2e, 0x20, 0x27, 0x67, 0x61, 0x64, 0x61, 0x27, 0x20,
+0x64, 0x2e, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x79, 0x79, 0x79, 0x79, 0x20, 0x27, 0x6d, 0x27, 0x2e, 0x20, 0x4d, 0x4d, 0x4d,
+0x4d, 0x20, 0x64, 0x20, 0x27, 0x64, 0x27, 0x2e, 0x2c, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x2e, 0x4d, 0x2e, 0x79, 0x79,
+0x64, 0x64, 0x64, 0x64, 0x20, 0x64, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
+0x2c, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x64, 0x2c, 0x20, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20,
+0x64, 0x20, 0x27, 0x74, 0x61, 0x27, 0x2019, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x4d, 0x4d, 0x4d,
+0x4d, 0x20, 0x64, 0x2c, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x2f, 0x4d,
+0x2f, 0x64, 0x64, 0x64, 0x64, 0x64, 0x20, 0x62f, 0x20, 0x79, 0x79, 0x79, 0x79, 0x20, 0x62f, 0x20, 0x4d, 0x4d, 0x4d, 0x4d,
+0x20, 0x64, 0x79, 0x79, 0x2f, 0x4d, 0x2f, 0x64, 0x64, 0x64, 0x64, 0x64, 0x20, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20,
+0x79, 0x79, 0x79, 0x79, 0x20, 0x47, 0x47, 0x47, 0x47, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x20, 0x27, 0x64, 0x65,
+0x27, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x27, 0x64, 0x65, 0x27, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x2f, 0x4d,
+0x4d, 0x2f, 0x79, 0x79, 0x79, 0x64, 0x64, 0x2e, 0x4d, 0x4d, 0x2e, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x2c,
+0x20, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x20, 0x27, 0x433, 0x27, 0x2e, 0x64, 0x2e, 0x4d,
+0x2e, 0x79, 0x79, 0x2e, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x64, 0x2e, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79,
+0x79, 0x79, 0x79, 0x2e, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x79, 0x79, 0x79, 0x79, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20,
+0x64, 0x64, 0x64, 0x64, 0x64, 0x20, 0x64, 0x64, 0x20, 0x27, 0x64, 0x65, 0x27, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x27,
+0x64, 0x65, 0x27, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x20, 0x27, 0x64, 0x65, 0x6e, 0x27, 0x20, 0x64,
+0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79,
+0x79, 0x64, 0x64, 0x64, 0x64, 0xe17, 0xe35, 0xe48, 0x20, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x47, 0x20, 0x79, 0x79,
+0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x1361, 0x20, 0x64, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x1218, 0x12d3, 0x120d, 0x1272,
+0x20, 0x79, 0x79, 0x79, 0x79, 0x20, 0x47, 0x64, 0x64, 0x64, 0x64, 0x1363, 0x20, 0x64, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d,
+0x20, 0x1218, 0x12d3, 0x120d, 0x1272, 0x20, 0x79, 0x79, 0x79, 0x79, 0x20, 0x47, 0x64, 0x64, 0x2d, 0x4d, 0x4d, 0x2d, 0x79, 0x79,
+0x79, 0x79, 0x64, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x20, 0x64, 0x64, 0x64, 0x64, 0x64,
+0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x20, 0x27, 0x440, 0x27,
+0x2e, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x27, 0x6e, 0x67, 0xe0, 0x79, 0x27, 0x20, 0x64, 0x64, 0x20, 0x4d, 0x4d, 0x4d,
+0x4d, 0x20, 0x27, 0x6e, 0x103, 0x6d, 0x27, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x2c,
+0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x1361, 0x20, 0x64, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x130d,
+0x122d, 0x130b, 0x20, 0x79, 0x79, 0x79, 0x79, 0x20, 0x47, 0x64, 0x64, 0x64, 0x64, 0x1365, 0x20, 0x64, 0x64, 0x20, 0x4d, 0x4d,
+0x4d, 0x4d, 0x20, 0x1218, 0x12d3, 0x120d, 0x1275, 0x20, 0x79, 0x79, 0x79, 0x79, 0x20, 0x47, 0x64, 0x64, 0x64, 0x64, 0x1361, 0x20,
+0x64, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x12ee, 0x121d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x20, 0x47, 0x64, 0x64, 0x64,
+0x64, 0x20, 0x64, 0x20, 0x27, 0x64, 0x69, 0x27, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x27, 0x64, 0x61, 0x6c, 0x27, 0x20,
+0x79, 0x79, 0x79, 0x79
+};
+
+static const ushort time_format_data[] = {
+0x48, 0x48, 0x3a, 0x6d, 0x6d, 0x3a, 0x73, 0x73, 0x48, 0x48, 0x3a, 0x6d, 0x6d, 0x3a, 0x73, 0x73, 0x20, 0x74, 0x68, 0x3a,
+0x6d, 0x6d, 0x20, 0x41, 0x50, 0x68, 0x3a, 0x6d, 0x6d, 0x3a, 0x73, 0x73, 0x20, 0x41, 0x50, 0x20, 0x48, 0x48, 0x3a, 0x6d,
+0x6d, 0x48, 0x48, 0x3a, 0x6d, 0x6d, 0x3a, 0x73, 0x73, 0x20, 0x68, 0x2e, 0x6d, 0x6d, 0x2e, 0x41, 0x50, 0x68, 0x2e, 0x6d,
+0x6d, 0x2e, 0x73, 0x73, 0x2e, 0x41, 0x50, 0x20, 0x68, 0x68, 0x3a, 0x6d, 0x6d, 0x3a, 0x73, 0x73, 0x20, 0x41, 0x50, 0x20,
+0x20, 0x68, 0x3a, 0x6d, 0x6d, 0x3a, 0x73, 0x73, 0x20, 0x41, 0x50, 0x68, 0x2e, 0x6d, 0x6d, 0x2e, 0x20, 0x41, 0x50, 0x68,
+0x2e, 0x6d, 0x6d, 0x2e, 0x73, 0x73, 0x20, 0x41, 0x50, 0x20, 0xf46, 0xf74, 0xf0b, 0xf5a, 0xf7c, 0xf51, 0xf0b, 0x20, 0x68, 0x20,
+0xf66, 0xf90, 0xf62, 0xf0b, 0xf58, 0xf0b, 0x20, 0x6d, 0x6d, 0x20, 0x41, 0x50, 0xf46, 0xf74, 0xf0b, 0xf5a, 0xf7c, 0xf51, 0xf0b, 0x20,
+0x68, 0x20, 0xf66, 0xf90, 0xf62, 0xf0b, 0xf58, 0xf0b, 0x20, 0x6d, 0x6d, 0x20, 0xf66, 0xf90, 0xf62, 0xf0b, 0xf46, 0xf71, 0xf0b, 0x20,
+0x73, 0x73, 0x20, 0x41, 0x50, 0x20, 0x48, 0x48, 0x2e, 0x6d, 0x6d, 0x48, 0x48, 0x2e, 0x6d, 0x6d, 0x2e, 0x73, 0x73, 0x20,
+0x48, 0x3a, 0x6d, 0x6d, 0x48, 0x20, 0x1798, 0x17c9, 0x17c4, 0x1784, 0x20, 0x6d, 0x20, 0x1793, 0x17b6, 0x1791, 0x17b8, 0x20, 0x73, 0x73,
+0x20, 0x179c, 0x17b7, 0x1793, 0x17b6, 0x1791, 0x17b8, 0x200b, 0x20, 0x48, 0x3a, 0x6d, 0x6d, 0x3a, 0x73, 0x73, 0x20, 0x41, 0x50, 0x68,
+0x3a, 0x6d, 0x6d, 0x41, 0x50, 0x68, 0x68, 0x65f6, 0x6d, 0x6d, 0x5206, 0x73, 0x73, 0x79d2, 0x41, 0x50, 0x68, 0x68, 0x3a, 0x6d,
+0x6d, 0x48, 0x48, 0x20, 0x27, 0x68, 0x27, 0x20, 0x6d, 0x6d, 0x20, 0x27, 0x6d, 0x69, 0x6e, 0x27, 0x20, 0x73, 0x73, 0x20,
+0x27, 0x73, 0x27, 0x20, 0x41, 0x50, 0x20, 0x68, 0x68, 0x3a, 0x6d, 0x6d, 0x41, 0x50, 0x20, 0x68, 0x68, 0x3a, 0x6d, 0x6d,
+0x3a, 0x73, 0x73, 0x20, 0x48, 0x2e, 0x6d, 0x6d, 0x48, 0x2e, 0x6d, 0x6d, 0x2e, 0x73, 0x73, 0x20, 0x48, 0x20, 0x27, 0x68,
+0x27, 0x20, 0x6d, 0x6d, 0x20, 0x27, 0x6d, 0x69, 0x6e, 0x27, 0x20, 0x73, 0x73, 0x20, 0x27, 0x73, 0x27, 0x20, 0x48, 0x48,
+0x2e, 0x6d, 0x6d, 0x3a, 0x73, 0x73, 0x20, 0x27, 0x68, 0x27, 0x20, 0x68, 0x68, 0x3a, 0x6d, 0x6d, 0x20, 0x41, 0x50, 0x48,
+0x6642, 0x6d, 0x6d, 0x5206, 0x73, 0x73, 0x79d2, 0x41, 0x50, 0x20, 0x68, 0x3a, 0x6d, 0x6d, 0x41, 0x50, 0x20, 0x68, 0x68, 0xc2dc,
+0x20, 0x6d, 0x6d, 0xbd84, 0x20, 0x73, 0x73, 0xcd08, 0x20, 0x48, 0xec2, 0xea1, 0xe87, 0x20, 0x6d, 0xe99, 0xeb2, 0xe97, 0xeb5, 0x20,
+0x73, 0x73, 0x20, 0xea7, 0xeb4, 0xe99, 0xeb2, 0xe97, 0xeb5, 0x68, 0x3a, 0x6d, 0x6d, 0x68, 0x3a, 0x6d, 0x6d, 0x3a, 0x73, 0x73,
+0x20, 0x41, 0x50, 0x41, 0x50, 0x20, 0x27, 0x6b, 0x6c, 0x27, 0x2e, 0x20, 0x48, 0x48, 0x2e, 0x6d, 0x6d, 0x2e, 0x73, 0x73,
+0x20, 0x48, 0x3a, 0x6d, 0x6d, 0x3a, 0x73, 0x73, 0x20, 0x28, 0x29, 0x48, 0x48, 0x27, 0x48, 0x27, 0x6d, 0x6d, 0x27, 0x6d,
+0x27, 0x73, 0x73, 0x27, 0x73, 0x27, 0x20, 0x48, 0x48, 0x27, 0x68, 0x27, 0x6d, 0x6d, 0x27, 0x6d, 0x69, 0x6e, 0x27, 0x73,
+0x73, 0x27, 0x73, 0x27, 0x20, 0x48, 0x48, 0x20, 0x27, 0x447, 0x430, 0x441, 0x43e, 0x432, 0x430, 0x27, 0x2c, 0x20, 0x6d, 0x6d,
+0x20, 0x27, 0x43c, 0x438, 0x43d, 0x443, 0x442, 0x430, 0x27, 0x2c, 0x20, 0x73, 0x73, 0x20, 0x27, 0x441, 0x435, 0x43a, 0x443, 0x43d,
+0x434, 0x438, 0x27, 0x20, 0x48, 0x48, 0x27, 0x68, 0x27, 0x27, 0x27, 0x6d, 0x6d, 0x3a, 0x73, 0x73, 0x20, 0x48, 0x48, 0x27,
+0x48, 0x27, 0x6d, 0x6d, 0x27, 0x27, 0x73, 0x73, 0x22, 0x20, 0x48, 0x20, 0xe19, 0xe32, 0xe2c, 0xe34, 0xe01, 0xe32, 0x20, 0x6d,
+0x20, 0xe19, 0xe32, 0xe17, 0xe35, 0x20, 0x73, 0x73, 0x20, 0xe27, 0xe34, 0xe19, 0xe32, 0xe17, 0xe35, 0x20
+};
+
+static const ushort months_data[] = {
+0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x41, 0x70, 0x72, 0x3b, 0x4d, 0x61, 0x79, 0x3b,
+0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x41, 0x75, 0x67, 0x3b, 0x53, 0x65, 0x70, 0x3b, 0x4f, 0x63, 0x74, 0x3b,
+0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x65, 0x63, 0x3b, 0x4a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x79, 0x3b, 0x46, 0x65, 0x62, 0x72,
+0x75, 0x61, 0x72, 0x79, 0x3b, 0x4d, 0x61, 0x72, 0x63, 0x68, 0x3b, 0x41, 0x70, 0x72, 0x69, 0x6c, 0x3b, 0x4d, 0x61, 0x79,
+0x3b, 0x4a, 0x75, 0x6e, 0x65, 0x3b, 0x4a, 0x75, 0x6c, 0x79, 0x3b, 0x41, 0x75, 0x67, 0x75, 0x73, 0x74, 0x3b, 0x53, 0x65,
+0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4f, 0x63, 0x74, 0x6f, 0x62, 0x65, 0x72, 0x3b, 0x4e, 0x6f, 0x76, 0x65,
+0x6d, 0x62, 0x65, 0x72, 0x3b, 0x44, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x31, 0x3b, 0x32, 0x3b, 0x33, 0x3b,
+0x34, 0x3b, 0x35, 0x3b, 0x36, 0x3b, 0x37, 0x3b, 0x38, 0x3b, 0x39, 0x3b, 0x31, 0x30, 0x3b, 0x31, 0x31, 0x3b, 0x31, 0x32,
+0x3b, 0x41, 0x6d, 0x61, 0x3b, 0x47, 0x75, 0x72, 0x3b, 0x42, 0x69, 0x74, 0x3b, 0x45, 0x6c, 0x62, 0x3b, 0x43, 0x61, 0x6d,
+0x3b, 0x57, 0x61, 0x78, 0x3b, 0x41, 0x64, 0x6f, 0x3b, 0x48, 0x61, 0x67, 0x3b, 0x46, 0x75, 0x6c, 0x3b, 0x4f, 0x6e, 0x6b,
+0x3b, 0x53, 0x61, 0x64, 0x3b, 0x4d, 0x75, 0x64, 0x3b, 0x41, 0x6d, 0x61, 0x6a, 0x6a, 0x69, 0x69, 0x3b, 0x47, 0x75, 0x72,
+0x61, 0x61, 0x6e, 0x64, 0x68, 0x61, 0x6c, 0x61, 0x3b, 0x42, 0x69, 0x74, 0x6f, 0x6f, 0x74, 0x65, 0x65, 0x73, 0x73, 0x61,
+0x3b, 0x45, 0x6c, 0x62, 0x61, 0x3b, 0x43, 0x61, 0x61, 0x6d, 0x73, 0x61, 0x3b, 0x57, 0x61, 0x78, 0x61, 0x62, 0x61, 0x6a,
+0x6a, 0x69, 0x69, 0x3b, 0x41, 0x64, 0x6f, 0x6f, 0x6c, 0x65, 0x65, 0x73, 0x73, 0x61, 0x3b, 0x48, 0x61, 0x67, 0x61, 0x79,
+0x79, 0x61, 0x3b, 0x46, 0x75, 0x75, 0x6c, 0x62, 0x61, 0x6e, 0x61, 0x3b, 0x4f, 0x6e, 0x6b, 0x6f, 0x6c, 0x6f, 0x6c, 0x65,
+0x65, 0x73, 0x73, 0x61, 0x3b, 0x53, 0x61, 0x64, 0x61, 0x61, 0x73, 0x61, 0x3b, 0x4d, 0x75, 0x64, 0x64, 0x65, 0x65, 0x3b,
+0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x51, 0x75, 0x6e, 0x3b, 0x4e, 0x61, 0x68, 0x3b,
+0x43, 0x69, 0x67, 0x3b, 0x41, 0x67, 0x64, 0x3b, 0x43, 0x61, 0x78, 0x3b, 0x51, 0x61, 0x73, 0x3b, 0x51, 0x61, 0x64, 0x3b,
+0x4c, 0x65, 0x71, 0x3b, 0x57, 0x61, 0x79, 0x3b, 0x44, 0x69, 0x74, 0x3b, 0x58, 0x69, 0x6d, 0x3b, 0x4b, 0x61, 0x78, 0x3b,
+0x51, 0x75, 0x6e, 0x78, 0x61, 0x20, 0x47, 0x61, 0x72, 0x61, 0x62, 0x6c, 0x75, 0x3b, 0x4e, 0x61, 0x68, 0x61, 0x72, 0x73,
+0x69, 0x20, 0x4b, 0x75, 0x64, 0x6f, 0x3b, 0x43, 0x69, 0x67, 0x67, 0x69, 0x6c, 0x74, 0x61, 0x20, 0x4b, 0x75, 0x64, 0x6f,
+0x3b, 0x41, 0x67, 0x64, 0x61, 0x20, 0x42, 0x61, 0x78, 0x69, 0x73, 0x73, 0x6f, 0x3b, 0x43, 0x61, 0x78, 0x61, 0x68, 0x20,
+0x41, 0x6c, 0x73, 0x61, 0x3b, 0x51, 0x61, 0x73, 0x61, 0x20, 0x44, 0x69, 0x72, 0x72, 0x69, 0x3b, 0x51, 0x61, 0x64, 0x6f,
+0x20, 0x44, 0x69, 0x72, 0x72, 0x69, 0x3b, 0x4c, 0x65, 0x71, 0x65, 0x65, 0x6e, 0x69, 0x3b, 0x57, 0x61, 0x79, 0x73, 0x75,
+0x3b, 0x44, 0x69, 0x74, 0x65, 0x6c, 0x69, 0x3b, 0x58, 0x69, 0x6d, 0x6f, 0x6c, 0x69, 0x3b, 0x4b, 0x61, 0x78, 0x78, 0x61,
+0x20, 0x47, 0x61, 0x72, 0x61, 0x62, 0x6c, 0x75, 0x3b, 0x51, 0x75, 0x6e, 0x78, 0x61, 0x20, 0x47, 0x61, 0x72, 0x61, 0x62,
+0x6c, 0x75, 0x3b, 0x4b, 0x75, 0x64, 0x6f, 0x3b, 0x43, 0x69, 0x67, 0x67, 0x69, 0x6c, 0x74, 0x61, 0x20, 0x4b, 0x75, 0x64,
+0x6f, 0x3b, 0x41, 0x67, 0x64, 0x61, 0x20, 0x42, 0x61, 0x78, 0x69, 0x73, 0x3b, 0x43, 0x61, 0x78, 0x61, 0x68, 0x20, 0x41,
+0x6c, 0x73, 0x61, 0x3b, 0x51, 0x61, 0x73, 0x61, 0x20, 0x44, 0x69, 0x72, 0x72, 0x69, 0x3b, 0x51, 0x61, 0x64, 0x6f, 0x20,
+0x44, 0x69, 0x72, 0x72, 0x69, 0x3b, 0x4c, 0x69, 0x69, 0x71, 0x65, 0x6e, 0x3b, 0x57, 0x61, 0x79, 0x73, 0x75, 0x3b, 0x44,
+0x69, 0x74, 0x65, 0x6c, 0x69, 0x3b, 0x58, 0x69, 0x6d, 0x6f, 0x6c, 0x69, 0x3b, 0x4b, 0x61, 0x78, 0x78, 0x61, 0x20, 0x47,
+0x61, 0x72, 0x61, 0x62, 0x6c, 0x75, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x41,
+0x70, 0x72, 0x3b, 0x4d, 0x65, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x41, 0x75, 0x67, 0x3b, 0x53,
+0x65, 0x70, 0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x65, 0x73, 0x3b, 0x4a, 0x61, 0x6e, 0x75, 0x61,
+0x72, 0x69, 0x65, 0x3b, 0x46, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x69, 0x65, 0x3b, 0x4d, 0x61, 0x61, 0x72, 0x74, 0x3b,
+0x41, 0x70, 0x72, 0x69, 0x6c, 0x3b, 0x4d, 0x65, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x69, 0x65, 0x3b, 0x4a, 0x75, 0x6c, 0x69,
+0x65, 0x3b, 0x41, 0x75, 0x67, 0x75, 0x73, 0x74, 0x75, 0x73, 0x3b, 0x53, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72,
+0x3b, 0x4f, 0x6b, 0x74, 0x6f, 0x62, 0x65, 0x72, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x44, 0x65,
+0x73, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x53, 0x68, 0x6b, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x50,
+0x72, 0x69, 0x3b, 0x4d, 0x61, 0x6a, 0x3b, 0x51, 0x65, 0x72, 0x3b, 0x4b, 0x6f, 0x72, 0x3b, 0x47, 0x73, 0x68, 0x3b, 0x53,
+0x68, 0x74, 0x3b, 0x54, 0x65, 0x74, 0x3b, 0x4e, 0xeb, 0x6e, 0x3b, 0x44, 0x68, 0x6a, 0x3b, 0x6a, 0x61, 0x6e, 0x61, 0x72,
+0x3b, 0x73, 0x68, 0x6b, 0x75, 0x72, 0x74, 0x3b, 0x6d, 0x61, 0x72, 0x73, 0x3b, 0x70, 0x72, 0x69, 0x6c, 0x6c, 0x3b, 0x6d,
+0x61, 0x6a, 0x3b, 0x71, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x72, 0x3b, 0x6b, 0x6f, 0x72, 0x72, 0x69, 0x6b, 0x3b, 0x67, 0x75,
+0x73, 0x68, 0x74, 0x3b, 0x73, 0x68, 0x74, 0x61, 0x74, 0x6f, 0x72, 0x3b, 0x74, 0x65, 0x74, 0x6f, 0x72, 0x3b, 0x6e, 0xeb,
+0x6e, 0x74, 0x6f, 0x72, 0x3b, 0x64, 0x68, 0x6a, 0x65, 0x74, 0x6f, 0x72, 0x3b, 0x1303, 0x1295, 0x12e9, 0x3b, 0x134c, 0x1265, 0x1229,
+0x3b, 0x121b, 0x122d, 0x127d, 0x3b, 0x12a4, 0x1355, 0x1228, 0x3b, 0x121c, 0x12ed, 0x3b, 0x1301, 0x1295, 0x3b, 0x1301, 0x120b, 0x12ed, 0x3b, 0x12a6,
+0x1308, 0x1235, 0x3b, 0x1234, 0x1355, 0x1274, 0x3b, 0x12a6, 0x12ad, 0x1270, 0x3b, 0x1296, 0x126c, 0x121d, 0x3b, 0x12f2, 0x1234, 0x121d, 0x3b, 0x1303,
+0x1295, 0x12e9, 0x12c8, 0x122a, 0x3b, 0x134c, 0x1265, 0x1229, 0x12c8, 0x122a, 0x3b, 0x121b, 0x122d, 0x127d, 0x3b, 0x12a4, 0x1355, 0x1228, 0x120d, 0x3b,
+0x121c, 0x12ed, 0x3b, 0x1301, 0x1295, 0x3b, 0x1301, 0x120b, 0x12ed, 0x3b, 0x12a6, 0x1308, 0x1235, 0x1275, 0x3b, 0x1234, 0x1355, 0x1274, 0x121d, 0x1260,
+0x122d, 0x3b, 0x12a6, 0x12ad, 0x1270, 0x12cd, 0x1260, 0x122d, 0x3b, 0x1296, 0x126c, 0x121d, 0x1260, 0x122d, 0x3b, 0x12f2, 0x1234, 0x121d, 0x1260, 0x122d,
+0x3b, 0x64a, 0x646, 0x627, 0x64a, 0x631, 0x3b, 0x641, 0x628, 0x631, 0x627, 0x64a, 0x631, 0x3b, 0x645, 0x627, 0x631, 0x633, 0x3b, 0x623,
+0x628, 0x631, 0x64a, 0x644, 0x3b, 0x645, 0x627, 0x64a, 0x648, 0x3b, 0x64a, 0x648, 0x646, 0x64a, 0x648, 0x3b, 0x64a, 0x648, 0x644, 0x64a,
+0x648, 0x3b, 0x623, 0x63a, 0x633, 0x637, 0x633, 0x3b, 0x633, 0x628, 0x62a, 0x645, 0x628, 0x631, 0x3b, 0x623, 0x643, 0x62a, 0x648, 0x628,
+0x631, 0x3b, 0x646, 0x648, 0x641, 0x645, 0x628, 0x631, 0x3b, 0x62f, 0x64a, 0x633, 0x645, 0x628, 0x631, 0x3b, 0x643, 0x627, 0x646, 0x648,
+0x646, 0x20, 0x627, 0x644, 0x62b, 0x627, 0x646, 0x64a, 0x3b, 0x634, 0x628, 0x627, 0x637, 0x3b, 0x622, 0x630, 0x627, 0x631, 0x3b, 0x646,
+0x64a, 0x633, 0x627, 0x646, 0x3b, 0x623, 0x64a, 0x627, 0x631, 0x3b, 0x62d, 0x632, 0x64a, 0x631, 0x627, 0x646, 0x3b, 0x62a, 0x645, 0x648,
+0x632, 0x3b, 0x622, 0x628, 0x3b, 0x623, 0x64a, 0x644, 0x648, 0x644, 0x3b, 0x62a, 0x634, 0x631, 0x64a, 0x646, 0x20, 0x627, 0x644, 0x623,
+0x648, 0x644, 0x3b, 0x62a, 0x634, 0x631, 0x64a, 0x646, 0x20, 0x627, 0x644, 0x62b, 0x627, 0x646, 0x64a, 0x3b, 0x643, 0x627, 0x646, 0x648,
+0x646, 0x20, 0x627, 0x644, 0x623, 0x648, 0x644, 0x3b, 0x643, 0x627, 0x646, 0x648, 0x646, 0x20, 0x627, 0x644, 0x62b, 0x627, 0x646, 0x64a,
+0x3b, 0x634, 0x628, 0x627, 0x637, 0x3b, 0x622, 0x630, 0x627, 0x631, 0x3b, 0x646, 0x64a, 0x633, 0x627, 0x646, 0x3b, 0x646, 0x648, 0x627,
+0x631, 0x3b, 0x62d, 0x632, 0x64a, 0x631, 0x627, 0x646, 0x3b, 0x62a, 0x645, 0x648, 0x632, 0x3b, 0x622, 0x628, 0x3b, 0x623, 0x64a, 0x644,
+0x648, 0x644, 0x3b, 0x62a, 0x634, 0x631, 0x64a, 0x646, 0x20, 0x627, 0x644, 0x623, 0x648, 0x644, 0x3b, 0x62a, 0x634, 0x631, 0x64a, 0x646,
+0x20, 0x627, 0x644, 0x62b, 0x627, 0x646, 0x64a, 0x3b, 0x643, 0x627, 0x646, 0x648, 0x646, 0x20, 0x627, 0x644, 0x623, 0x648, 0x644, 0x3b,
+0x545, 0x576, 0x580, 0x3b, 0x553, 0x57f, 0x580, 0x3b, 0x544, 0x580, 0x57f, 0x3b, 0x531, 0x57a, 0x580, 0x3b, 0x544, 0x575, 0x57d, 0x3b,
+0x545, 0x576, 0x57d, 0x3b, 0x545, 0x56c, 0x57d, 0x3b, 0x555, 0x563, 0x57d, 0x3b, 0x54d, 0x565, 0x57a, 0x3b, 0x540, 0x578, 0x56f, 0x3b,
+0x546, 0x578, 0x575, 0x3b, 0x534, 0x565, 0x56f, 0x3b, 0x545, 0x578, 0x582, 0x576, 0x578, 0x582, 0x561, 0x580, 0x3b, 0x553, 0x565, 0x57f,
+0x580, 0x578, 0x582, 0x561, 0x580, 0x3b, 0x544, 0x561, 0x580, 0x57f, 0x3b, 0x531, 0x57a, 0x580, 0x56b, 0x56c, 0x3b, 0x544, 0x561, 0x575,
+0x56b, 0x57d, 0x3b, 0x545, 0x578, 0x582, 0x576, 0x56b, 0x57d, 0x3b, 0x545, 0x578, 0x582, 0x56c, 0x56b, 0x57d, 0x3b, 0x555, 0x563, 0x578,
+0x57d, 0x57f, 0x578, 0x57d, 0x3b, 0x54d, 0x565, 0x57a, 0x57f, 0x565, 0x574, 0x562, 0x565, 0x580, 0x3b, 0x540, 0x578, 0x56f, 0x57f, 0x565,
+0x574, 0x562, 0x565, 0x580, 0x3b, 0x546, 0x578, 0x575, 0x565, 0x574, 0x562, 0x565, 0x580, 0x3b, 0x534, 0x565, 0x56f, 0x57f, 0x565, 0x574,
+0x562, 0x565, 0x580, 0x3b, 0x99c, 0x9be, 0x9a8, 0x9c1, 0x3b, 0x9ab, 0x9c7, 0x9ac, 0x9cd, 0x9f0, 0x9c1, 0x3b, 0x9ae, 0x9be, 0x9f0, 0x9cd,
+0x99a, 0x3b, 0x98f, 0x9aa, 0x9cd, 0x9f0, 0x9bf, 0x9b2, 0x3b, 0x9ae, 0x9c7, 0x3b, 0x99c, 0x9c1, 0x9a8, 0x3b, 0x99c, 0x9c1, 0x9b2, 0x9be,
+0x987, 0x3b, 0x986, 0x997, 0x3b, 0x9b8, 0x9c7, 0x9aa, 0x9cd, 0x99f, 0x3b, 0x985, 0x995, 0x9cd, 0x99f, 0x9cb, 0x3b, 0x9a8, 0x9ad, 0x9c7,
+0x3b, 0x9a1, 0x9bf, 0x9b8, 0x9c7, 0x3b, 0x99c, 0x9be, 0x9a8, 0x9c1, 0x9af, 0x9bc, 0x9be, 0x9f0, 0x9c0, 0x3b, 0x9ab, 0x9c7, 0x9ac, 0x9cd,
+0x9f0, 0x9c1, 0x9af, 0x9bc, 0x9be, 0x9f0, 0x9c0, 0x3b, 0x9ae, 0x9be, 0x9f0, 0x9cd, 0x99a, 0x3b, 0x98f, 0x9aa, 0x9cd, 0x9f0, 0x9bf, 0x9b2,
+0x3b, 0x9ae, 0x9c7, 0x3b, 0x99c, 0x9c1, 0x9a8, 0x3b, 0x99c, 0x9c1, 0x9b2, 0x9be, 0x987, 0x3b, 0x986, 0x997, 0x9b7, 0x9cd, 0x99f, 0x3b,
+0x9b8, 0x9c7, 0x9aa, 0x9cd, 0x99f, 0x9c7, 0x9ae, 0x9cd, 0x9ac, 0x9f0, 0x3b, 0x985, 0x995, 0x9cd, 0x99f, 0x9cb, 0x9ac, 0x9f0, 0x3b, 0x9a8,
+0x9ad, 0x9c7, 0x9ae, 0x9cd, 0x9ac, 0x9f0, 0x3b, 0x9a1, 0x9bf, 0x9b8, 0x9c7, 0x9ae, 0x9cd, 0x9ac, 0x9f0, 0x3b, 0x79, 0x61, 0x6e, 0x3b,
+0x66, 0x65, 0x76, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x61, 0x70, 0x72, 0x3b, 0x6d, 0x61, 0x79, 0x3b, 0x69, 0x79, 0x6e, 0x3b,
+0x69, 0x79, 0x6c, 0x3b, 0x61, 0x76, 0x71, 0x3b, 0x73, 0x65, 0x6e, 0x3b, 0x6f, 0x6b, 0x74, 0x3b, 0x6e, 0x6f, 0x79, 0x3b,
+0x64, 0x65, 0x6b, 0x3b, 0x59, 0x61, 0x6e, 0x76, 0x61, 0x72, 0x3b, 0x46, 0x65, 0x76, 0x72, 0x61, 0x6c, 0x3b, 0x4d, 0x61,
+0x72, 0x74, 0x3b, 0x41, 0x70, 0x72, 0x65, 0x6c, 0x3b, 0x4d, 0x61, 0x79, 0x3b, 0x130, 0x79, 0x75, 0x6e, 0x3b, 0x130, 0x79,
+0x75, 0x6c, 0x3b, 0x41, 0x76, 0x71, 0x75, 0x73, 0x74, 0x3b, 0x53, 0x65, 0x6e, 0x74, 0x79, 0x61, 0x62, 0x72, 0x3b, 0x4f,
+0x6b, 0x74, 0x79, 0x61, 0x62, 0x72, 0x3b, 0x4e, 0x6f, 0x79, 0x61, 0x62, 0x72, 0x3b, 0x44, 0x65, 0x6b, 0x61, 0x62, 0x72,
+0x3b, 0x75, 0x72, 0x74, 0x3b, 0x6f, 0x74, 0x73, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x61, 0x70, 0x69, 0x3b, 0x6d, 0x61, 0x69,
+0x3b, 0x65, 0x6b, 0x61, 0x3b, 0x75, 0x7a, 0x74, 0x3b, 0x61, 0x62, 0x75, 0x3b, 0x69, 0x72, 0x61, 0x3b, 0x75, 0x72, 0x72,
+0x3b, 0x61, 0x7a, 0x61, 0x3b, 0x61, 0x62, 0x65, 0x3b, 0x75, 0x72, 0x74, 0x61, 0x72, 0x72, 0x69, 0x6c, 0x61, 0x3b, 0x6f,
+0x74, 0x73, 0x61, 0x69, 0x6c, 0x61, 0x3b, 0x6d, 0x61, 0x72, 0x74, 0x78, 0x6f, 0x61, 0x3b, 0x61, 0x70, 0x69, 0x72, 0x69,
+0x6c, 0x61, 0x3b, 0x6d, 0x61, 0x69, 0x61, 0x74, 0x7a, 0x61, 0x3b, 0x65, 0x6b, 0x61, 0x69, 0x6e, 0x61, 0x3b, 0x75, 0x7a,
+0x74, 0x61, 0x69, 0x6c, 0x61, 0x3b, 0x61, 0x62, 0x75, 0x7a, 0x74, 0x75, 0x61, 0x3b, 0x69, 0x72, 0x61, 0x69, 0x6c, 0x61,
+0x3b, 0x75, 0x72, 0x72, 0x69, 0x61, 0x3b, 0x61, 0x7a, 0x61, 0x72, 0x6f, 0x61, 0x3b, 0x61, 0x62, 0x65, 0x6e, 0x64, 0x75,
+0x61, 0x3b, 0x99c, 0x9be, 0x9a8, 0x9c1, 0x9af, 0x9bc, 0x9be, 0x9b0, 0x9c0, 0x3b, 0x9ab, 0x9c7, 0x9ac, 0x9cd, 0x9b0, 0x9c1, 0x9af, 0x9bc,
+0x9be, 0x9b0, 0x9c0, 0x3b, 0x9ae, 0x9be, 0x9b0, 0x9cd, 0x99a, 0x3b, 0x98f, 0x9aa, 0x9cd, 0x9b0, 0x9bf, 0x9b2, 0x3b, 0x9ae, 0x9c7, 0x3b,
+0x99c, 0x9c1, 0x9a8, 0x3b, 0x99c, 0x9c1, 0x9b2, 0x9be, 0x987, 0x3b, 0x986, 0x997, 0x9b8, 0x9cd, 0x99f, 0x3b, 0x9b8, 0x9c7, 0x9aa, 0x9cd,
+0x99f, 0x9c7, 0x9ae, 0x9cd, 0x9ac, 0x9b0, 0x3b, 0x985, 0x995, 0x9cd, 0x99f, 0x9cb, 0x9ac, 0x9b0, 0x3b, 0x9a8, 0x9ad, 0x9c7, 0x9ae, 0x9cd,
+0x9ac, 0x9b0, 0x3b, 0x9a1, 0x9bf, 0x9b8, 0x9c7, 0x9ae, 0x9cd, 0x9ac, 0x9b0, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0x20, 0xf21, 0x3b, 0xf5f, 0xfb3,
+0xf0b, 0x20, 0xf22, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0x20, 0xf23, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0x20, 0xf24, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0x20,
+0xf25, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0x20, 0xf26, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0x20, 0xf27, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0x20, 0xf28, 0x3b,
+0xf5f, 0xfb3, 0xf0b, 0x20, 0xf29, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0x20, 0xf21, 0xf20, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0x20, 0xf21, 0xf21, 0x3b,
+0xf5f, 0xfb3, 0xf0b, 0x20, 0xf21, 0xf22, 0x3b, 0xf66, 0xfa4, 0xfb1, 0xf72, 0xf0b, 0xf5f, 0xfb3, 0xf5d, 0xf0b, 0xf51, 0xf44, 0xf54, 0xf0b,
+0x3b, 0xf66, 0xfa4, 0xfb1, 0xf72, 0xf0b, 0xf5f, 0xfb3, 0xf5d, 0xf0b, 0xf42, 0xf49, 0xf72, 0xf66, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf66, 0xfa4,
+0xfb1, 0xf72, 0xf0b, 0xf5f, 0xfb3, 0xf5d, 0xf0b, 0xf42, 0xf66, 0xf74, 0xf58, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf66, 0xfa4, 0xfb1, 0xf72, 0xf0b,
+0xf5f, 0xfb3, 0xf5d, 0xf0b, 0xf56, 0xf5e, 0xf72, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf66, 0xfa4, 0xfb1, 0xf72, 0xf0b, 0xf5f, 0xfb3, 0xf5d, 0xf0b,
+0xf63, 0xf94, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf66, 0xfa4, 0xfb1, 0xf72, 0xf0b, 0xf5f, 0xfb3, 0xf5d, 0xf0b, 0xf51, 0xfb2, 0xf74, 0xf42, 0xf0b,
+0xf54, 0xf0b, 0x3b, 0xf66, 0xfa4, 0xfb1, 0xf72, 0xf0b, 0xf5f, 0xfb3, 0xf5d, 0xf0b, 0xf56, 0xf51, 0xf74, 0xf53, 0xf0b, 0xf54, 0xf0b, 0x3b,
+0xf66, 0xfa4, 0xfb1, 0xf72, 0xf0b, 0xf5f, 0xfb3, 0xf5d, 0xf0b, 0xf56, 0xf62, 0xf92, 0xfb1, 0xf51, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf66, 0xfa4,
+0xfb1, 0xf72, 0xf0b, 0xf5f, 0xfb3, 0xf5d, 0xf0b, 0xf51, 0xf42, 0xf74, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf66, 0xfa4, 0xfb1, 0xf72, 0xf0b, 0xf5f,
+0xfb3, 0xf5d, 0xf0b, 0xf56, 0xf45, 0xf74, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf66, 0xfa4, 0xfb1, 0xf72, 0xf0b, 0xf5f, 0xfb3, 0xf5d, 0xf0b, 0xf56,
+0xf45, 0xf74, 0xf0b, 0xf42, 0xf45, 0xf72, 0xf42, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf66, 0xfa4, 0xfb1, 0xf72, 0xf0b, 0xf5f, 0xfb3, 0xf5d, 0xf0b,
+0xf56, 0xf45, 0xf74, 0xf0b, 0xf42, 0xf49, 0xf72, 0xf66, 0xf0b, 0xf54, 0xf0b, 0x3b, 0x44f, 0x43d, 0x2e, 0x3b, 0x444, 0x435, 0x432, 0x440,
+0x2e, 0x3b, 0x43c, 0x430, 0x440, 0x442, 0x3b, 0x430, 0x43f, 0x440, 0x2e, 0x3b, 0x43c, 0x430, 0x439, 0x3b, 0x44e, 0x43d, 0x438, 0x3b,
+0x44e, 0x43b, 0x438, 0x3b, 0x430, 0x432, 0x433, 0x2e, 0x3b, 0x441, 0x435, 0x43f, 0x442, 0x2e, 0x3b, 0x43e, 0x43a, 0x442, 0x2e, 0x3b,
+0x43d, 0x43e, 0x435, 0x43c, 0x2e, 0x3b, 0x434, 0x435, 0x43a, 0x2e, 0x3b, 0x44f, 0x43d, 0x443, 0x430, 0x440, 0x438, 0x3b, 0x444, 0x435,
+0x432, 0x440, 0x443, 0x430, 0x440, 0x438, 0x3b, 0x43c, 0x430, 0x440, 0x442, 0x3b, 0x430, 0x43f, 0x440, 0x438, 0x43b, 0x3b, 0x43c, 0x430,
+0x439, 0x3b, 0x44e, 0x43d, 0x438, 0x3b, 0x44e, 0x43b, 0x438, 0x3b, 0x430, 0x432, 0x433, 0x443, 0x441, 0x442, 0x3b, 0x441, 0x435, 0x43f,
+0x442, 0x435, 0x43c, 0x432, 0x440, 0x438, 0x3b, 0x43e, 0x43a, 0x442, 0x43e, 0x43c, 0x432, 0x440, 0x438, 0x3b, 0x43d, 0x43e, 0x435, 0x43c,
+0x432, 0x440, 0x438, 0x3b, 0x434, 0x435, 0x43a, 0x435, 0x43c, 0x432, 0x440, 0x438, 0x3b, 0x1007, 0x1014, 0x103a, 0x3b, 0x1016, 0x1031, 0x3b,
+0x1019, 0x1010, 0x103a, 0x3b, 0x1027, 0x3b, 0x1019, 0x1031, 0x3b, 0x1007, 0x103d, 0x1014, 0x103a, 0x3b, 0x1007, 0x1030, 0x3b, 0x1029, 0x3b, 0x1005,
+0x1000, 0x103a, 0x3b, 0x1021, 0x1031, 0x102c, 0x1000, 0x103a, 0x3b, 0x1014, 0x102d, 0x102f, 0x3b, 0x1012, 0x102e, 0x3b, 0x1007, 0x1014, 0x103a, 0x1014,
+0x101d, 0x102b, 0x101b, 0x102e, 0x3b, 0x1016, 0x1031, 0x1016, 0x1031, 0x102c, 0x103a, 0x101d, 0x102b, 0x101b, 0x102e, 0x3b, 0x1019, 0x1010, 0x103a, 0x3b,
+0x1027, 0x1015, 0x103c, 0x102e, 0x3b, 0x1019, 0x1031, 0x3b, 0x1007, 0x103d, 0x1014, 0x103a, 0x3b, 0x1007, 0x1030, 0x101c, 0x102d, 0x102f, 0x1004, 0x103a,
+0x3b, 0x1029, 0x1002, 0x102f, 0x1010, 0x103a, 0x3b, 0x1005, 0x1000, 0x103a, 0x1010, 0x1004, 0x103a, 0x1018, 0x102c, 0x3b, 0x1021, 0x1031, 0x102c, 0x1000,
+0x103a, 0x1010, 0x102d, 0x102f, 0x1018, 0x102c, 0x3b, 0x1014, 0x102d, 0x102f, 0x101d, 0x1004, 0x103a, 0x1018, 0x102c, 0x3b, 0x1012, 0x102e, 0x1007, 0x1004,
+0x103a, 0x1018, 0x102c, 0x3b, 0x441, 0x442, 0x443, 0x3b, 0x43b, 0x44e, 0x442, 0x3b, 0x441, 0x430, 0x43a, 0x3b, 0x43a, 0x440, 0x430, 0x3b,
+0x43c, 0x430, 0x439, 0x3b, 0x447, 0x44d, 0x440, 0x3b, 0x43b, 0x456, 0x43f, 0x3b, 0x436, 0x43d, 0x456, 0x3b, 0x432, 0x435, 0x440, 0x3b,
+0x43a, 0x430, 0x441, 0x3b, 0x43b, 0x456, 0x441, 0x3b, 0x441, 0x43d, 0x435, 0x3b, 0x441, 0x442, 0x443, 0x434, 0x437, 0x435, 0x43d, 0x44c,
+0x3b, 0x43b, 0x44e, 0x442, 0x44b, 0x3b, 0x441, 0x430, 0x43a, 0x430, 0x432, 0x456, 0x43a, 0x3b, 0x43a, 0x440, 0x430, 0x441, 0x430, 0x432,
+0x456, 0x43a, 0x3b, 0x43c, 0x430, 0x439, 0x3b, 0x447, 0x44d, 0x440, 0x432, 0x435, 0x43d, 0x44c, 0x3b, 0x43b, 0x456, 0x43f, 0x435, 0x43d,
+0x44c, 0x3b, 0x436, 0x43d, 0x456, 0x432, 0x435, 0x43d, 0x44c, 0x3b, 0x432, 0x435, 0x440, 0x430, 0x441, 0x435, 0x43d, 0x44c, 0x3b, 0x43a,
+0x430, 0x441, 0x442, 0x440, 0x44b, 0x447, 0x43d, 0x456, 0x43a, 0x3b, 0x43b, 0x456, 0x441, 0x442, 0x430, 0x43f, 0x430, 0x434, 0x3b, 0x441,
+0x43d, 0x435, 0x436, 0x430, 0x43d, 0x44c, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x442, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
+0x17e1, 0x3b, 0x17e2, 0x3b, 0x17e3, 0x3b, 0x17e4, 0x3b, 0x17e5, 0x3b, 0x17e6, 0x3b, 0x17e7, 0x3b, 0x17e8, 0x3b, 0x17e9, 0x3b, 0x17e1, 0x17e0,
+0x3b, 0x17e1, 0x17e1, 0x3b, 0x17e1, 0x17e2, 0x3b, 0x1798, 0x1780, 0x179a, 0x17b6, 0x3b, 0x1780, 0x17bb, 0x1798, 0x17d2, 0x1797, 0x17c8, 0x3b, 0x1798,
+0x17b7, 0x1793, 0x17b6, 0x3b, 0x1798, 0x17c1, 0x179f, 0x17b6, 0x3b, 0x17a7, 0x179f, 0x1797, 0x17b6, 0x3b, 0x1798, 0x17b7, 0x1790, 0x17bb, 0x1793, 0x17b6,
+0x3b, 0x1780, 0x1780, 0x17d2, 0x1780, 0x178a, 0x17b6, 0x3b, 0x179f, 0x17b8, 0x17a0, 0x17b6, 0x3b, 0x1780, 0x1789, 0x17d2, 0x1789, 0x17b6, 0x3b, 0x178f,
+0x17bb, 0x179b, 0x17b6, 0x3b, 0x179c, 0x17b7, 0x1785, 0x17d2, 0x1786, 0x17b7, 0x1780, 0x17b6, 0x3b, 0x1792, 0x17d2, 0x1793, 0x17bc, 0x3b, 0x67, 0x65,
+0x6e, 0x2e, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0xe7, 0x3b, 0x61, 0x62, 0x72, 0x2e, 0x3b, 0x6d,
+0x61, 0x69, 0x67, 0x3b, 0x6a, 0x75, 0x6e, 0x79, 0x3b, 0x6a, 0x75, 0x6c, 0x2e, 0x3b, 0x61, 0x67, 0x2e, 0x3b, 0x73, 0x65,
+0x74, 0x2e, 0x3b, 0x6f, 0x63, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76, 0x2e, 0x3b, 0x64, 0x65, 0x73, 0x2e, 0x3b, 0x67, 0x65,
+0x6e, 0x65, 0x72, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x65, 0x72, 0x3b, 0x6d, 0x61, 0x72, 0xe7, 0x3b, 0x61, 0x62, 0x72, 0x69,
+0x6c, 0x3b, 0x6d, 0x61, 0x69, 0x67, 0x3b, 0x6a, 0x75, 0x6e, 0x79, 0x3b, 0x6a, 0x75, 0x6c, 0x69, 0x6f, 0x6c, 0x3b, 0x61,
+0x67, 0x6f, 0x73, 0x74, 0x3b, 0x73, 0x65, 0x74, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x6f, 0x63, 0x74, 0x75, 0x62, 0x72,
+0x65, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x64, 0x65, 0x73, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b,
+0x31, 0x6708, 0x3b, 0x32, 0x6708, 0x3b, 0x33, 0x6708, 0x3b, 0x34, 0x6708, 0x3b, 0x35, 0x6708, 0x3b, 0x36, 0x6708, 0x3b, 0x37, 0x6708,
+0x3b, 0x38, 0x6708, 0x3b, 0x39, 0x6708, 0x3b, 0x31, 0x30, 0x6708, 0x3b, 0x31, 0x31, 0x6708, 0x3b, 0x31, 0x32, 0x6708, 0x3b, 0x73,
+0x69, 0x6a, 0x3b, 0x76, 0x65, 0x6c, 0x3b, 0x6f, 0x17e, 0x75, 0x3b, 0x74, 0x72, 0x61, 0x3b, 0x73, 0x76, 0x69, 0x3b, 0x6c,
+0x69, 0x70, 0x3b, 0x73, 0x72, 0x70, 0x3b, 0x6b, 0x6f, 0x6c, 0x3b, 0x72, 0x75, 0x6a, 0x3b, 0x6c, 0x69, 0x73, 0x3b, 0x73,
+0x74, 0x75, 0x3b, 0x70, 0x72, 0x6f, 0x3b, 0x73, 0x69, 0x6a, 0x65, 0x10d, 0x6e, 0x6a, 0x61, 0x3b, 0x76, 0x65, 0x6c, 0x6a,
+0x61, 0x10d, 0x65, 0x3b, 0x6f, 0x17e, 0x75, 0x6a, 0x6b, 0x61, 0x3b, 0x74, 0x72, 0x61, 0x76, 0x6e, 0x6a, 0x61, 0x3b, 0x73,
+0x76, 0x69, 0x62, 0x6e, 0x6a, 0x61, 0x3b, 0x6c, 0x69, 0x70, 0x6e, 0x6a, 0x61, 0x3b, 0x73, 0x72, 0x70, 0x6e, 0x6a, 0x61,
+0x3b, 0x6b, 0x6f, 0x6c, 0x6f, 0x76, 0x6f, 0x7a, 0x61, 0x3b, 0x72, 0x75, 0x6a, 0x6e, 0x61, 0x3b, 0x6c, 0x69, 0x73, 0x74,
+0x6f, 0x70, 0x61, 0x64, 0x61, 0x3b, 0x73, 0x74, 0x75, 0x64, 0x65, 0x6e, 0x6f, 0x67, 0x61, 0x3b, 0x70, 0x72, 0x6f, 0x73,
+0x69, 0x6e, 0x63, 0x61, 0x3b, 0x6c, 0x65, 0x64, 0x6e, 0x61, 0x3b, 0xfa, 0x6e, 0x6f, 0x72, 0x61, 0x3b, 0x62, 0x159, 0x65,
+0x7a, 0x6e, 0x61, 0x3b, 0x64, 0x75, 0x62, 0x6e, 0x61, 0x3b, 0x6b, 0x76, 0x11b, 0x74, 0x6e, 0x61, 0x3b, 0x10d, 0x65, 0x72,
+0x76, 0x6e, 0x61, 0x3b, 0x10d, 0x65, 0x72, 0x76, 0x65, 0x6e, 0x63, 0x65, 0x3b, 0x73, 0x72, 0x70, 0x6e, 0x61, 0x3b, 0x7a,
+0xe1, 0x159, 0xed, 0x3b, 0x159, 0xed, 0x6a, 0x6e, 0x61, 0x3b, 0x6c, 0x69, 0x73, 0x74, 0x6f, 0x70, 0x61, 0x64, 0x75, 0x3b,
+0x70, 0x72, 0x6f, 0x73, 0x69, 0x6e, 0x63, 0x65, 0x3b, 0x6a, 0x61, 0x6e, 0x3b, 0x66, 0x65, 0x62, 0x3b, 0x6d, 0x61, 0x72,
+0x3b, 0x61, 0x70, 0x72, 0x3b, 0x6d, 0x61, 0x6a, 0x3b, 0x6a, 0x75, 0x6e, 0x3b, 0x6a, 0x75, 0x6c, 0x3b, 0x61, 0x75, 0x67,
+0x3b, 0x73, 0x65, 0x70, 0x3b, 0x6f, 0x6b, 0x74, 0x3b, 0x6e, 0x6f, 0x76, 0x3b, 0x64, 0x65, 0x63, 0x3b, 0x6a, 0x61, 0x6e,
+0x75, 0x61, 0x72, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x3b, 0x6d, 0x61, 0x72, 0x74, 0x73, 0x3b, 0x61, 0x70,
+0x72, 0x69, 0x6c, 0x3b, 0x6d, 0x61, 0x6a, 0x3b, 0x6a, 0x75, 0x6e, 0x69, 0x3b, 0x6a, 0x75, 0x6c, 0x69, 0x3b, 0x61, 0x75,
+0x67, 0x75, 0x73, 0x74, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x6f, 0x6b, 0x74, 0x6f, 0x62,
+0x65, 0x72, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x64, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x65, 0x72,
+0x3b, 0x6a, 0x61, 0x6e, 0x3b, 0x66, 0x65, 0x62, 0x3b, 0x6d, 0x72, 0x74, 0x3b, 0x61, 0x70, 0x72, 0x3b, 0x6d, 0x65, 0x69,
+0x3b, 0x6a, 0x75, 0x6e, 0x3b, 0x6a, 0x75, 0x6c, 0x3b, 0x61, 0x75, 0x67, 0x3b, 0x73, 0x65, 0x70, 0x3b, 0x6f, 0x6b, 0x74,
+0x3b, 0x6e, 0x6f, 0x76, 0x3b, 0x64, 0x65, 0x63, 0x3b, 0x6a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x69, 0x3b, 0x66, 0x65, 0x62,
+0x72, 0x75, 0x61, 0x72, 0x69, 0x3b, 0x6d, 0x61, 0x61, 0x72, 0x74, 0x3b, 0x61, 0x70, 0x72, 0x69, 0x6c, 0x3b, 0x6d, 0x65,
+0x69, 0x3b, 0x6a, 0x75, 0x6e, 0x69, 0x3b, 0x6a, 0x75, 0x6c, 0x69, 0x3b, 0x61, 0x75, 0x67, 0x75, 0x73, 0x74, 0x75, 0x73,
+0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x6f, 0x6b, 0x74, 0x6f, 0x62, 0x65, 0x72, 0x3b, 0x6e,
+0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x64, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x6a, 0x61, 0x61,
+0x6e, 0x3b, 0x76, 0x65, 0x65, 0x62, 0x72, 0x3b, 0x6d, 0xe4, 0x72, 0x74, 0x73, 0x3b, 0x61, 0x70, 0x72, 0x3b, 0x6d, 0x61,
+0x69, 0x3b, 0x6a, 0x75, 0x75, 0x6e, 0x69, 0x3b, 0x6a, 0x75, 0x75, 0x6c, 0x69, 0x3b, 0x61, 0x75, 0x67, 0x3b, 0x73, 0x65,
+0x70, 0x74, 0x3b, 0x6f, 0x6b, 0x74, 0x3b, 0x6e, 0x6f, 0x76, 0x3b, 0x64, 0x65, 0x74, 0x73, 0x3b, 0x6a, 0x61, 0x61, 0x6e,
+0x75, 0x61, 0x72, 0x3b, 0x76, 0x65, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x3b, 0x6d, 0xe4, 0x72, 0x74, 0x73, 0x3b, 0x61,
+0x70, 0x72, 0x69, 0x6c, 0x6c, 0x3b, 0x6d, 0x61, 0x69, 0x3b, 0x6a, 0x75, 0x75, 0x6e, 0x69, 0x3b, 0x6a, 0x75, 0x75, 0x6c,
+0x69, 0x3b, 0x61, 0x75, 0x67, 0x75, 0x73, 0x74, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x6f,
+0x6b, 0x74, 0x6f, 0x6f, 0x62, 0x65, 0x72, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x64, 0x65, 0x74,
+0x73, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x6a, 0x61, 0x6e, 0x3b, 0x66, 0x65, 0x62, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x61,
+0x70, 0x72, 0x3b, 0x6d, 0x61, 0x69, 0x3b, 0x6a, 0x75, 0x6e, 0x3b, 0x6a, 0x75, 0x6c, 0x3b, 0x61, 0x75, 0x67, 0x3b, 0x73,
+0x65, 0x70, 0x3b, 0x6f, 0x6b, 0x74, 0x3b, 0x6e, 0x6f, 0x76, 0x3b, 0x64, 0x65, 0x73, 0x3b, 0x6a, 0x61, 0x6e, 0x75, 0x61,
+0x72, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x3b, 0x6d, 0x61, 0x72, 0x73, 0x3b, 0x61, 0x70, 0x72, 0xed, 0x6c,
+0x3b, 0x6d, 0x61, 0x69, 0x3b, 0x6a, 0x75, 0x6e, 0x69, 0x3b, 0x6a, 0x75, 0x6c, 0x69, 0x3b, 0x61, 0x75, 0x67, 0x75, 0x73,
+0x74, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x6f, 0x6b, 0x74, 0x6f, 0x62, 0x65, 0x72, 0x3b,
+0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x64, 0x65, 0x73, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x74, 0x61,
+0x6d, 0x6d, 0x69, 0x3b, 0x68, 0x65, 0x6c, 0x6d, 0x69, 0x3b, 0x6d, 0x61, 0x61, 0x6c, 0x69, 0x73, 0x3b, 0x68, 0x75, 0x68,
+0x74, 0x69, 0x3b, 0x74, 0x6f, 0x75, 0x6b, 0x6f, 0x3b, 0x6b, 0x65, 0x73, 0xe4, 0x3b, 0x68, 0x65, 0x69, 0x6e, 0xe4, 0x3b,
+0x65, 0x6c, 0x6f, 0x3b, 0x73, 0x79, 0x79, 0x73, 0x3b, 0x6c, 0x6f, 0x6b, 0x61, 0x3b, 0x6d, 0x61, 0x72, 0x72, 0x61, 0x73,
+0x3b, 0x6a, 0x6f, 0x75, 0x6c, 0x75, 0x3b, 0x74, 0x61, 0x6d, 0x6d, 0x69, 0x6b, 0x75, 0x75, 0x74, 0x61, 0x3b, 0x68, 0x65,
+0x6c, 0x6d, 0x69, 0x6b, 0x75, 0x75, 0x74, 0x61, 0x3b, 0x6d, 0x61, 0x61, 0x6c, 0x69, 0x73, 0x6b, 0x75, 0x75, 0x74, 0x61,
+0x3b, 0x68, 0x75, 0x68, 0x74, 0x69, 0x6b, 0x75, 0x75, 0x74, 0x61, 0x3b, 0x74, 0x6f, 0x75, 0x6b, 0x6f, 0x6b, 0x75, 0x75,
+0x74, 0x61, 0x3b, 0x6b, 0x65, 0x73, 0xe4, 0x6b, 0x75, 0x75, 0x74, 0x61, 0x3b, 0x68, 0x65, 0x69, 0x6e, 0xe4, 0x6b, 0x75,
+0x75, 0x74, 0x61, 0x3b, 0x65, 0x6c, 0x6f, 0x6b, 0x75, 0x75, 0x74, 0x61, 0x3b, 0x73, 0x79, 0x79, 0x73, 0x6b, 0x75, 0x75,
+0x74, 0x61, 0x3b, 0x6c, 0x6f, 0x6b, 0x61, 0x6b, 0x75, 0x75, 0x74, 0x61, 0x3b, 0x6d, 0x61, 0x72, 0x72, 0x61, 0x73, 0x6b,
+0x75, 0x75, 0x74, 0x61, 0x3b, 0x6a, 0x6f, 0x75, 0x6c, 0x75, 0x6b, 0x75, 0x75, 0x74, 0x61, 0x3b, 0x6a, 0x61, 0x6e, 0x76,
+0x2e, 0x3b, 0x66, 0xe9, 0x76, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x73, 0x3b, 0x61, 0x76, 0x72, 0x2e, 0x3b, 0x6d, 0x61,
+0x69, 0x3b, 0x6a, 0x75, 0x69, 0x6e, 0x3b, 0x6a, 0x75, 0x69, 0x6c, 0x2e, 0x3b, 0x61, 0x6f, 0xfb, 0x74, 0x3b, 0x73, 0x65,
+0x70, 0x74, 0x2e, 0x3b, 0x6f, 0x63, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76, 0x2e, 0x3b, 0x64, 0xe9, 0x63, 0x2e, 0x3b, 0x6a,
+0x61, 0x6e, 0x76, 0x69, 0x65, 0x72, 0x3b, 0x66, 0xe9, 0x76, 0x72, 0x69, 0x65, 0x72, 0x3b, 0x6d, 0x61, 0x72, 0x73, 0x3b,
+0x61, 0x76, 0x72, 0x69, 0x6c, 0x3b, 0x6d, 0x61, 0x69, 0x3b, 0x6a, 0x75, 0x69, 0x6e, 0x3b, 0x6a, 0x75, 0x69, 0x6c, 0x6c,
+0x65, 0x74, 0x3b, 0x61, 0x6f, 0xfb, 0x74, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x6f, 0x63,
+0x74, 0x6f, 0x62, 0x72, 0x65, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x64, 0xe9, 0x63, 0x65, 0x6d,
+0x62, 0x72, 0x65, 0x3b, 0x58, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x41, 0x62, 0x72, 0x3b,
+0x4d, 0x61, 0x69, 0x3b, 0x58, 0x75, 0xf1, 0x3b, 0x58, 0x75, 0x6c, 0x3b, 0x41, 0x67, 0x6f, 0x3b, 0x53, 0x65, 0x74, 0x3b,
+0x4f, 0x75, 0x74, 0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x65, 0x63, 0x3b, 0x58, 0x61, 0x6e, 0x65, 0x69, 0x72, 0x6f, 0x3b,
+0x46, 0x65, 0x62, 0x72, 0x65, 0x69, 0x72, 0x6f, 0x3b, 0x4d, 0x61, 0x72, 0x7a, 0x6f, 0x3b, 0x41, 0x62, 0x72, 0x69, 0x6c,
+0x3b, 0x4d, 0x61, 0x69, 0x6f, 0x3b, 0x58, 0x75, 0xf1, 0x6f, 0x3b, 0x58, 0x75, 0x6c, 0x6c, 0x6f, 0x3b, 0x41, 0x67, 0x6f,
+0x73, 0x74, 0x6f, 0x3b, 0x53, 0x65, 0x74, 0x65, 0x6d, 0x62, 0x72, 0x6f, 0x3b, 0x4f, 0x75, 0x74, 0x75, 0x62, 0x72, 0x6f,
+0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x72, 0x6f, 0x3b, 0x44, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x72, 0x6f, 0x3b, 0x10d8,
+0x10d0, 0x10dc, 0x3b, 0x10d7, 0x10d4, 0x10d1, 0x3b, 0x10db, 0x10d0, 0x10e0, 0x3b, 0x10d0, 0x10de, 0x10e0, 0x3b, 0x10db, 0x10d0, 0x10d8, 0x3b, 0x10d8,
+0x10d5, 0x10dc, 0x3b, 0x10d8, 0x10d5, 0x10da, 0x3b, 0x10d0, 0x10d2, 0x10d5, 0x3b, 0x10e1, 0x10d4, 0x10e5, 0x3b, 0x10dd, 0x10e5, 0x10e2, 0x3b, 0x10dc,
+0x10dd, 0x10d4, 0x3b, 0x10d3, 0x10d4, 0x10d9, 0x3b, 0x10d8, 0x10d0, 0x10dc, 0x10d5, 0x10d0, 0x10e0, 0x10d8, 0x3b, 0x10d7, 0x10d4, 0x10d1, 0x10d4, 0x10e0,
+0x10d5, 0x10d0, 0x10da, 0x10d8, 0x3b, 0x10db, 0x10d0, 0x10e0, 0x10e2, 0x10d8, 0x3b, 0x10d0, 0x10de, 0x10e0, 0x10d8, 0x10da, 0x10d8, 0x3b, 0x10db, 0x10d0,
+0x10d8, 0x10e1, 0x10d8, 0x3b, 0x10d8, 0x10d5, 0x10dc, 0x10d8, 0x10e1, 0x10d8, 0x3b, 0x10d8, 0x10d5, 0x10da, 0x10d8, 0x10e1, 0x10d8, 0x3b, 0x10d0, 0x10d2,
+0x10d5, 0x10d8, 0x10e1, 0x10e2, 0x10dd, 0x3b, 0x10e1, 0x10d4, 0x10e5, 0x10e2, 0x10d4, 0x10db, 0x10d1, 0x10d4, 0x10e0, 0x10d8, 0x3b, 0x10dd, 0x10e5, 0x10e2,
+0x10dd, 0x10db, 0x10d1, 0x10d4, 0x10e0, 0x10d8, 0x3b, 0x10dc, 0x10dd, 0x10d4, 0x10db, 0x10d1, 0x10d4, 0x10e0, 0x10d8, 0x3b, 0x10d3, 0x10d4, 0x10d9, 0x10d4,
+0x10db, 0x10d1, 0x10d4, 0x10e0, 0x10d8, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0x72, 0x7a, 0x3b, 0x41, 0x70,
+0x72, 0x3b, 0x4d, 0x61, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x41, 0x75, 0x67, 0x3b, 0x53, 0x65,
+0x70, 0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x65, 0x7a, 0x3b, 0x4a, 0x61, 0x6e, 0x75, 0x61, 0x72,
+0x3b, 0x46, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x3b, 0x4d, 0xe4, 0x72, 0x7a, 0x3b, 0x41, 0x70, 0x72, 0x69, 0x6c, 0x3b,
+0x4d, 0x61, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x69, 0x3b, 0x4a, 0x75, 0x6c, 0x69, 0x3b, 0x41, 0x75, 0x67, 0x75, 0x73, 0x74,
+0x3b, 0x53, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4f, 0x6b, 0x74, 0x6f, 0x62, 0x65, 0x72, 0x3b, 0x4e,
+0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x44, 0x65, 0x7a, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4a, 0xe4, 0x6e,
+0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0xe4, 0x72, 0x3b, 0x41, 0x70, 0x72, 0x3b, 0x4d, 0x61, 0x69, 0x3b, 0x4a, 0x75, 0x6e,
+0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x41, 0x75, 0x67, 0x3b, 0x53, 0x65, 0x70, 0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x76,
+0x3b, 0x44, 0x65, 0x7a, 0x3b, 0x4a, 0xe4, 0x6e, 0x6e, 0x65, 0x72, 0x3b, 0x46, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x3b,
+0x4d, 0xe4, 0x72, 0x7a, 0x3b, 0x41, 0x70, 0x72, 0x69, 0x6c, 0x3b, 0x4d, 0x61, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x69, 0x3b,
+0x4a, 0x75, 0x6c, 0x69, 0x3b, 0x41, 0x75, 0x67, 0x75, 0x73, 0x74, 0x3b, 0x53, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65,
+0x72, 0x3b, 0x4f, 0x6b, 0x74, 0x6f, 0x62, 0x65, 0x72, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x44,
+0x65, 0x7a, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0xe4, 0x72, 0x3b,
+0x41, 0x70, 0x72, 0x3b, 0x4d, 0x61, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x41, 0x75, 0x67, 0x3b,
+0x53, 0x65, 0x70, 0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x65, 0x7a, 0x3b, 0x399, 0x3b1, 0x3bd, 0x3b,
+0x3a6, 0x3b5, 0x3b2, 0x3b, 0x39c, 0x3b1, 0x3c1, 0x3b, 0x391, 0x3c0, 0x3c1, 0x3b, 0x39c, 0x3b1, 0x3ca, 0x3b, 0x399, 0x3bf, 0x3c5, 0x3bd,
+0x3b, 0x399, 0x3bf, 0x3c5, 0x3bb, 0x3b, 0x391, 0x3c5, 0x3b3, 0x3b, 0x3a3, 0x3b5, 0x3c0, 0x3b, 0x39f, 0x3ba, 0x3c4, 0x3b, 0x39d, 0x3bf,
+0x3b5, 0x3b, 0x394, 0x3b5, 0x3ba, 0x3b, 0x399, 0x3b1, 0x3bd, 0x3bf, 0x3c5, 0x3b1, 0x3c1, 0x3af, 0x3bf, 0x3c5, 0x3b, 0x3a6, 0x3b5, 0x3b2,
+0x3c1, 0x3bf, 0x3c5, 0x3b1, 0x3c1, 0x3af, 0x3bf, 0x3c5, 0x3b, 0x39c, 0x3b1, 0x3c1, 0x3c4, 0x3af, 0x3bf, 0x3c5, 0x3b, 0x391, 0x3c0, 0x3c1,
+0x3b9, 0x3bb, 0x3af, 0x3bf, 0x3c5, 0x3b, 0x39c, 0x3b1, 0x390, 0x3bf, 0x3c5, 0x3b, 0x399, 0x3bf, 0x3c5, 0x3bd, 0x3af, 0x3bf, 0x3c5, 0x3b,
+0x399, 0x3bf, 0x3c5, 0x3bb, 0x3af, 0x3bf, 0x3c5, 0x3b, 0x391, 0x3c5, 0x3b3, 0x3bf, 0x3cd, 0x3c3, 0x3c4, 0x3bf, 0x3c5, 0x3b, 0x3a3, 0x3b5,
+0x3c0, 0x3c4, 0x3b5, 0x3bc, 0x3b2, 0x3c1, 0x3af, 0x3bf, 0x3c5, 0x3b, 0x39f, 0x3ba, 0x3c4, 0x3c9, 0x3b2, 0x3c1, 0x3af, 0x3bf, 0x3c5, 0x3b,
+0x39d, 0x3bf, 0x3b5, 0x3bc, 0x3b2, 0x3c1, 0x3af, 0x3bf, 0x3c5, 0x3b, 0x394, 0x3b5, 0x3ba, 0x3b5, 0x3bc, 0x3b2, 0x3c1, 0x3af, 0x3bf, 0x3c5,
+0x3b, 0x6a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x69, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x69, 0x3b, 0x6d, 0x61,
+0x72, 0x74, 0x73, 0x69, 0x3b, 0x61, 0x70, 0x72, 0x69, 0x6c, 0x69, 0x3b, 0x6d, 0x61, 0x6a, 0x69, 0x3b, 0x6a, 0x75, 0x6e,
+0x69, 0x3b, 0x6a, 0x75, 0x6c, 0x69, 0x3b, 0x61, 0x75, 0x67, 0x75, 0x73, 0x74, 0x75, 0x73, 0x69, 0x3b, 0x73, 0x65, 0x70,
+0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x69, 0x3b, 0x6f, 0x6b, 0x74, 0x6f, 0x62, 0x65, 0x72, 0x69, 0x3b, 0x6e, 0x6f, 0x76,
+0x65, 0x6d, 0x62, 0x65, 0x72, 0x69, 0x3b, 0x64, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x69, 0x3b, 0xa9c, 0xabe, 0xaa8,
+0xacd, 0xaaf, 0xac1, 0x3b, 0xaab, 0xac7, 0xaac, 0xacd, 0xab0, 0xac1, 0x3b, 0xaae, 0xabe, 0xab0, 0xacd, 0xa9a, 0x3b, 0xa8f, 0xaaa, 0xacd,
+0xab0, 0xabf, 0xab2, 0x3b, 0xaae, 0xac7, 0x3b, 0xa9c, 0xac2, 0xaa8, 0x3b, 0xa9c, 0xac1, 0xab2, 0xabe, 0xa88, 0x3b, 0xa91, 0xa97, 0xab8,
+0xacd, 0xa9f, 0x3b, 0xab8, 0xaaa, 0xacd, 0xa9f, 0xac7, 0x3b, 0xa91, 0xa95, 0xacd, 0xa9f, 0xacb, 0x3b, 0xaa8, 0xab5, 0xac7, 0x3b, 0xaa1,
+0xabf, 0xab8, 0xac7, 0x3b, 0xa9c, 0xabe, 0xaa8, 0xacd, 0xaaf, 0xac1, 0xa86, 0xab0, 0xac0, 0x3b, 0xaab, 0xac7, 0xaac, 0xacd, 0xab0, 0xac1,
+0xa86, 0xab0, 0xac0, 0x3b, 0xaae, 0xabe, 0xab0, 0xacd, 0xa9a, 0x3b, 0xa8f, 0xaaa, 0xacd, 0xab0, 0xabf, 0xab2, 0x3b, 0xaae, 0xac7, 0x3b,
+0xa9c, 0xac2, 0xaa8, 0x3b, 0xa9c, 0xac1, 0xab2, 0xabe, 0xa88, 0x3b, 0xa91, 0xa97, 0xab8, 0xacd, 0xa9f, 0x3b, 0xab8, 0xaaa, 0xacd, 0xa9f,
+0xac7, 0xaae, 0xacd, 0xaac, 0xab0, 0x3b, 0xa91, 0xa95, 0xacd, 0xa9f, 0xacd, 0xaac, 0xab0, 0x3b, 0xaa8, 0xab5, 0xac7, 0xaae, 0xacd, 0xaac,
+0xab0, 0x3b, 0xaa1, 0xabf, 0xab8, 0xac7, 0xaae, 0xacd, 0xaac, 0xab0, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x61, 0x62, 0x3b, 0x4d,
+0x61, 0x72, 0x3b, 0x41, 0x66, 0x72, 0x3b, 0x4d, 0x61, 0x79, 0x3b, 0x59, 0x75, 0x6e, 0x3b, 0x59, 0x75, 0x6c, 0x3b, 0x41,
+0x75, 0x67, 0x3b, 0x53, 0x61, 0x74, 0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e, 0x75, 0x77, 0x3b, 0x44, 0x69, 0x73, 0x3b, 0x4a,
+0x61, 0x6e, 0x61, 0x69, 0x72, 0x75, 0x3b, 0x46, 0x61, 0x62, 0x72, 0x61, 0x69, 0x72, 0x75, 0x3b, 0x4d, 0x61, 0x72, 0x69,
+0x73, 0x3b, 0x41, 0x66, 0x72, 0x69, 0x6c, 0x75, 0x3b, 0x4d, 0x61, 0x79, 0x75, 0x3b, 0x59, 0x75, 0x6e, 0x69, 0x3b, 0x59,
+0x75, 0x6c, 0x69, 0x3b, 0x41, 0x75, 0x67, 0x75, 0x73, 0x74, 0x61, 0x3b, 0x53, 0x61, 0x74, 0x75, 0x6d, 0x62, 0x61, 0x3b,
+0x4f, 0x6b, 0x74, 0x6f, 0x62, 0x61, 0x3b, 0x4e, 0x75, 0x77, 0x61, 0x6d, 0x62, 0x61, 0x3b, 0x44, 0x69, 0x73, 0x61, 0x6d,
+0x62, 0x61, 0x3b, 0x5d9, 0x5e0, 0x5d5, 0x3b, 0x5e4, 0x5d1, 0x5e8, 0x3b, 0x5de, 0x5e8, 0x5e5, 0x3b, 0x5d0, 0x5e4, 0x5e8, 0x3b, 0x5de,
+0x5d0, 0x5d9, 0x3b, 0x5d9, 0x5d5, 0x5e0, 0x3b, 0x5d9, 0x5d5, 0x5dc, 0x3b, 0x5d0, 0x5d5, 0x5d2, 0x3b, 0x5e1, 0x5e4, 0x5d8, 0x3b, 0x5d0,
+0x5d5, 0x5e7, 0x3b, 0x5e0, 0x5d5, 0x5d1, 0x3b, 0x5d3, 0x5e6, 0x5de, 0x3b, 0x5d9, 0x5e0, 0x5d5, 0x5d0, 0x5e8, 0x3b, 0x5e4, 0x5d1, 0x5e8,
+0x5d5, 0x5d0, 0x5e8, 0x3b, 0x5de, 0x5e8, 0x5e5, 0x3b, 0x5d0, 0x5e4, 0x5e8, 0x5d9, 0x5dc, 0x3b, 0x5de, 0x5d0, 0x5d9, 0x3b, 0x5d9, 0x5d5,
+0x5e0, 0x5d9, 0x3b, 0x5d9, 0x5d5, 0x5dc, 0x5d9, 0x3b, 0x5d0, 0x5d5, 0x5d2, 0x5d5, 0x5e1, 0x5d8, 0x3b, 0x5e1, 0x5e4, 0x5d8, 0x5de, 0x5d1,
+0x5e8, 0x3b, 0x5d0, 0x5d5, 0x5e7, 0x5d8, 0x5d5, 0x5d1, 0x5e8, 0x3b, 0x5e0, 0x5d5, 0x5d1, 0x5de, 0x5d1, 0x5e8, 0x3b, 0x5d3, 0x5e6, 0x5de,
+0x5d1, 0x5e8, 0x3b, 0x91c, 0x928, 0x935, 0x930, 0x940, 0x3b, 0x92b, 0x930, 0x935, 0x930, 0x940, 0x3b, 0x92e, 0x93e, 0x930, 0x94d, 0x91a,
+0x3b, 0x905, 0x92a, 0x94d, 0x930, 0x948, 0x932, 0x3b, 0x92e, 0x908, 0x3b, 0x91c, 0x942, 0x928, 0x3b, 0x91c, 0x941, 0x932, 0x93e, 0x908,
+0x3b, 0x905, 0x917, 0x938, 0x94d, 0x924, 0x3b, 0x938, 0x93f, 0x924, 0x92e, 0x94d, 0x92c, 0x930, 0x3b, 0x905, 0x915, 0x94d, 0x924, 0x942,
+0x92c, 0x930, 0x3b, 0x928, 0x935, 0x92e, 0x94d, 0x92c, 0x930, 0x3b, 0x926, 0x93f, 0x938, 0x92e, 0x94d, 0x92c, 0x930, 0x3b, 0x6a, 0x61,
+0x6e, 0x2e, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x2e, 0x3b, 0x6d, 0xe1, 0x72, 0x63, 0x2e, 0x3b, 0xe1, 0x70, 0x72, 0x2e, 0x3b,
+0x6d, 0xe1, 0x6a, 0x2e, 0x3b, 0x6a, 0xfa, 0x6e, 0x2e, 0x3b, 0x6a, 0xfa, 0x6c, 0x2e, 0x3b, 0x61, 0x75, 0x67, 0x2e, 0x3b,
+0x73, 0x7a, 0x65, 0x70, 0x74, 0x2e, 0x3b, 0x6f, 0x6b, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76, 0x2e, 0x3b, 0x64, 0x65, 0x63,
+0x2e, 0x3b, 0x6a, 0x61, 0x6e, 0x75, 0xe1, 0x72, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x75, 0xe1, 0x72, 0x3b, 0x6d, 0xe1, 0x72,
+0x63, 0x69, 0x75, 0x73, 0x3b, 0xe1, 0x70, 0x72, 0x69, 0x6c, 0x69, 0x73, 0x3b, 0x6d, 0xe1, 0x6a, 0x75, 0x73, 0x3b, 0x6a,
+0xfa, 0x6e, 0x69, 0x75, 0x73, 0x3b, 0x6a, 0xfa, 0x6c, 0x69, 0x75, 0x73, 0x3b, 0x61, 0x75, 0x67, 0x75, 0x73, 0x7a, 0x74,
+0x75, 0x73, 0x3b, 0x73, 0x7a, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x6f, 0x6b, 0x74, 0xf3, 0x62, 0x65,
+0x72, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x64, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b,
+0x6a, 0x61, 0x6e, 0x3b, 0x66, 0x65, 0x62, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x61, 0x70, 0x72, 0x3b, 0x6d, 0x61, 0xed, 0x3b,
+0x6a, 0xfa, 0x6e, 0x3b, 0x6a, 0xfa, 0x6c, 0x3b, 0xe1, 0x67, 0xfa, 0x3b, 0x73, 0x65, 0x70, 0x3b, 0x6f, 0x6b, 0x74, 0x3b,
+0x6e, 0xf3, 0x76, 0x3b, 0x64, 0x65, 0x73, 0x3b, 0x6a, 0x61, 0x6e, 0xfa, 0x61, 0x72, 0x3b, 0x66, 0x65, 0x62, 0x72, 0xfa,
+0x61, 0x72, 0x3b, 0x6d, 0x61, 0x72, 0x73, 0x3b, 0x61, 0x70, 0x72, 0xed, 0x6c, 0x3b, 0x6d, 0x61, 0xed, 0x3b, 0x6a, 0xfa,
+0x6e, 0xed, 0x3b, 0x6a, 0xfa, 0x6c, 0xed, 0x3b, 0xe1, 0x67, 0xfa, 0x73, 0x74, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d,
+0x62, 0x65, 0x72, 0x3b, 0x6f, 0x6b, 0x74, 0xf3, 0x62, 0x65, 0x72, 0x3b, 0x6e, 0xf3, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72,
+0x3b, 0x64, 0x65, 0x73, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0x61,
+0x72, 0x3b, 0x41, 0x70, 0x72, 0x3b, 0x4d, 0x65, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x41, 0x67,
+0x75, 0x3b, 0x53, 0x65, 0x70, 0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x65, 0x73, 0x3b, 0x4a, 0x61,
+0x6e, 0x75, 0x61, 0x72, 0x69, 0x3b, 0x46, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x69, 0x3b, 0x4d, 0x61, 0x72, 0x65, 0x74,
+0x3b, 0x41, 0x70, 0x72, 0x69, 0x6c, 0x3b, 0x4d, 0x65, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x69, 0x3b, 0x4a, 0x75, 0x6c, 0x69,
+0x3b, 0x41, 0x67, 0x75, 0x73, 0x74, 0x75, 0x73, 0x3b, 0x53, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4f,
+0x6b, 0x74, 0x6f, 0x62, 0x65, 0x72, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x44, 0x65, 0x73, 0x65,
+0x6d, 0x62, 0x65, 0x72, 0x3b, 0x45, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x61, 0x62, 0x68, 0x3b, 0x4d, 0xe1, 0x72, 0x74, 0x61,
+0x3b, 0x41, 0x69, 0x62, 0x3b, 0x42, 0x65, 0x61, 0x6c, 0x3b, 0x4d, 0x65, 0x69, 0x74, 0x68, 0x3b, 0x49, 0xfa, 0x69, 0x6c,
+0x3b, 0x4c, 0xfa, 0x6e, 0x3b, 0x4d, 0x46, 0xf3, 0x6d, 0x68, 0x3b, 0x44, 0x46, 0xf3, 0x6d, 0x68, 0x3b, 0x53, 0x61, 0x6d,
+0x68, 0x3b, 0x4e, 0x6f, 0x6c, 0x6c, 0x3b, 0x45, 0x61, 0x6e, 0xe1, 0x69, 0x72, 0x3b, 0x46, 0x65, 0x61, 0x62, 0x68, 0x72,
+0x61, 0x3b, 0x4d, 0xe1, 0x72, 0x74, 0x61, 0x3b, 0x41, 0x69, 0x62, 0x72, 0x65, 0xe1, 0x6e, 0x3b, 0x42, 0x65, 0x61, 0x6c,
+0x74, 0x61, 0x69, 0x6e, 0x65, 0x3b, 0x4d, 0x65, 0x69, 0x74, 0x68, 0x65, 0x61, 0x6d, 0x68, 0x3b, 0x49, 0xfa, 0x69, 0x6c,
+0x3b, 0x4c, 0xfa, 0x6e, 0x61, 0x73, 0x61, 0x3b, 0x4d, 0x65, 0xe1, 0x6e, 0x20, 0x46, 0xf3, 0x6d, 0x68, 0x61, 0x69, 0x72,
+0x3b, 0x44, 0x65, 0x69, 0x72, 0x65, 0x61, 0x64, 0x68, 0x20, 0x46, 0xf3, 0x6d, 0x68, 0x61, 0x69, 0x72, 0x3b, 0x53, 0x61,
+0x6d, 0x68, 0x61, 0x69, 0x6e, 0x3b, 0x4e, 0x6f, 0x6c, 0x6c, 0x61, 0x69, 0x67, 0x3b, 0x67, 0x65, 0x6e, 0x3b, 0x66, 0x65,
+0x62, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x61, 0x70, 0x72, 0x3b, 0x6d, 0x61, 0x67, 0x3b, 0x67, 0x69, 0x75, 0x3b, 0x6c, 0x75,
+0x67, 0x3b, 0x61, 0x67, 0x6f, 0x3b, 0x73, 0x65, 0x74, 0x3b, 0x6f, 0x74, 0x74, 0x3b, 0x6e, 0x6f, 0x76, 0x3b, 0x64, 0x69,
+0x63, 0x3b, 0x67, 0x65, 0x6e, 0x6e, 0x61, 0x69, 0x6f, 0x3b, 0x66, 0x65, 0x62, 0x62, 0x72, 0x61, 0x69, 0x6f, 0x3b, 0x6d,
+0x61, 0x72, 0x7a, 0x6f, 0x3b, 0x61, 0x70, 0x72, 0x69, 0x6c, 0x65, 0x3b, 0x6d, 0x61, 0x67, 0x67, 0x69, 0x6f, 0x3b, 0x67,
+0x69, 0x75, 0x67, 0x6e, 0x6f, 0x3b, 0x4c, 0x75, 0x67, 0x6c, 0x69, 0x6f, 0x3b, 0x61, 0x67, 0x6f, 0x73, 0x74, 0x6f, 0x3b,
+0x73, 0x65, 0x74, 0x74, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x6f, 0x74, 0x74, 0x6f, 0x62, 0x72, 0x65, 0x3b, 0x6e, 0x6f,
+0x76, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x64, 0x69, 0x63, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0xc9c, 0xca8, 0xcb5, 0xcb0,
+0xcc0, 0x3b, 0xcab, 0xcc6, 0xcac, 0xccd, 0xcb0, 0xcb5, 0xcb0, 0xcc0, 0x3b, 0xcae, 0xcbe, 0xcb0, 0xccd, 0xc9a, 0xccd, 0x3b, 0xc8e, 0xcaa,
+0xccd, 0xcb0, 0xcbf, 0xcb2, 0xccd, 0x3b, 0xcae, 0xcc6, 0x3b, 0xc9c, 0xcc2, 0xca8, 0xccd, 0x3b, 0xc9c, 0xcc1, 0xcb2, 0xcc8, 0x3b, 0xc86,
+0xc97, 0xcb8, 0xccd, 0xc9f, 0xccd, 0x3b, 0xcb8, 0xcaa, 0xccd, 0xc9f, 0xcc6, 0xc82, 0xcac, 0xcb0, 0xccd, 0x3b, 0xc85, 0xc95, 0xccd, 0xc9f,
+0xccb, 0xcac, 0xcb0, 0xccd, 0x3b, 0xca8, 0xcb5, 0xcc6, 0xc82, 0xcac, 0xcb0, 0xccd, 0x3b, 0xca1, 0xcbf, 0xcb8, 0xcc6, 0xc82, 0xcac, 0xcb0,
+0xccd, 0x3b, 0x49b, 0x430, 0x4a3, 0x2e, 0x3b, 0x430, 0x49b, 0x43f, 0x2e, 0x3b, 0x43d, 0x430, 0x443, 0x2e, 0x3b, 0x441, 0x4d9, 0x443,
+0x2e, 0x3b, 0x43c, 0x430, 0x43c, 0x2e, 0x3b, 0x43c, 0x430, 0x443, 0x2e, 0x3b, 0x448, 0x456, 0x43b, 0x2e, 0x3b, 0x442, 0x430, 0x43c,
+0x2e, 0x3b, 0x49b, 0x44b, 0x440, 0x2e, 0x3b, 0x49b, 0x430, 0x437, 0x2e, 0x3b, 0x49b, 0x430, 0x440, 0x2e, 0x3b, 0x436, 0x435, 0x43b,
+0x442, 0x2e, 0x3b, 0x49b, 0x430, 0x4a3, 0x442, 0x430, 0x440, 0x3b, 0x430, 0x49b, 0x43f, 0x430, 0x43d, 0x3b, 0x43d, 0x430, 0x443, 0x440,
+0x44b, 0x437, 0x3b, 0x441, 0x4d9, 0x443, 0x456, 0x440, 0x3b, 0x43c, 0x430, 0x43c, 0x44b, 0x440, 0x3b, 0x43c, 0x430, 0x443, 0x441, 0x44b,
+0x43c, 0x3b, 0x448, 0x456, 0x43b, 0x434, 0x435, 0x3b, 0x442, 0x430, 0x43c, 0x44b, 0x437, 0x3b, 0x49b, 0x44b, 0x440, 0x43a, 0x4af, 0x439,
+0x435, 0x43a, 0x3b, 0x49b, 0x430, 0x437, 0x430, 0x43d, 0x3b, 0x49b, 0x430, 0x440, 0x430, 0x448, 0x430, 0x3b, 0x436, 0x435, 0x43b, 0x442,
+0x43e, 0x49b, 0x441, 0x430, 0x43d, 0x3b, 0x6d, 0x75, 0x74, 0x2e, 0x3b, 0x67, 0x61, 0x73, 0x2e, 0x3b, 0x77, 0x65, 0x72, 0x2e,
+0x3b, 0x6d, 0x61, 0x74, 0x2e, 0x3b, 0x67, 0x69, 0x63, 0x2e, 0x3b, 0x6b, 0x61, 0x6d, 0x2e, 0x3b, 0x6e, 0x79, 0x61, 0x2e,
+0x3b, 0x6b, 0x61, 0x6e, 0x2e, 0x3b, 0x6e, 0x7a, 0x65, 0x2e, 0x3b, 0x75, 0x6b, 0x77, 0x2e, 0x3b, 0x75, 0x67, 0x75, 0x2e,
+0x3b, 0x75, 0x6b, 0x75, 0x2e, 0x3b, 0x4d, 0x75, 0x74, 0x61, 0x72, 0x61, 0x6d, 0x61, 0x3b, 0x47, 0x61, 0x73, 0x68, 0x79,
+0x61, 0x6e, 0x74, 0x61, 0x72, 0x65, 0x3b, 0x57, 0x65, 0x72, 0x75, 0x72, 0x77, 0x65, 0x3b, 0x4d, 0x61, 0x74, 0x61, 0x3b,
+0x47, 0x69, 0x63, 0x75, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x3b, 0x4b, 0x61, 0x6d, 0x65, 0x6e, 0x61, 0x3b, 0x4e, 0x79, 0x61,
+0x6b, 0x61, 0x6e, 0x67, 0x61, 0x3b, 0x4b, 0x61, 0x6e, 0x61, 0x6d, 0x61, 0x3b, 0x4e, 0x7a, 0x65, 0x6c, 0x69, 0x3b, 0x55,
+0x6b, 0x77, 0x61, 0x6b, 0x69, 0x72, 0x61, 0x3b, 0x55, 0x67, 0x75, 0x73, 0x68, 0x79, 0x69, 0x6e, 0x67, 0x6f, 0x3b, 0x55,
+0x6b, 0x75, 0x62, 0x6f, 0x7a, 0x61, 0x3b, 0x31, 0xc6d4, 0x3b, 0x32, 0xc6d4, 0x3b, 0x33, 0xc6d4, 0x3b, 0x34, 0xc6d4, 0x3b, 0x35,
+0xc6d4, 0x3b, 0x36, 0xc6d4, 0x3b, 0x37, 0xc6d4, 0x3b, 0x38, 0xc6d4, 0x3b, 0x39, 0xc6d4, 0x3b, 0x31, 0x30, 0xc6d4, 0x3b, 0x31, 0x31,
+0xc6d4, 0x3b, 0x31, 0x32, 0xc6d4, 0x3b, 0xea1, 0x2e, 0xe81, 0x2e, 0x3b, 0xe81, 0x2e, 0xe9e, 0x2e, 0x3b, 0xea1, 0xeb5, 0x2e, 0xe99,
+0x2e, 0x3b, 0xea1, 0x2e, 0xeaa, 0x2e, 0x2e, 0x3b, 0xe9e, 0x2e, 0xe9e, 0x2e, 0x3b, 0xea1, 0xeb4, 0x2e, 0xe96, 0x2e, 0x3b, 0xe81,
+0x2e, 0xea5, 0x2e, 0x3b, 0xeaa, 0x2e, 0xeab, 0x2e, 0x3b, 0xe81, 0x2e, 0xe8d, 0x2e, 0x3b, 0xe95, 0x2e, 0xea5, 0x2e, 0x3b, 0xe9e,
+0x2e, 0xe88, 0x2e, 0x3b, 0xe97, 0x2e, 0xea7, 0x2e, 0x3b, 0xea1, 0xeb1, 0xe87, 0xe81, 0xead, 0xe99, 0x3b, 0xe81, 0xeb8, 0xea1, 0xe9e,
+0xeb2, 0x3b, 0xea1, 0xeb5, 0xe99, 0xeb2, 0x3b, 0xec0, 0xea1, 0xeaa, 0xeb2, 0x3b, 0xe9e, 0xeb6, 0xe94, 0xeaa, 0xeb0, 0xe9e, 0xeb2, 0x3b,
+0xea1, 0xeb4, 0xe96, 0xeb8, 0xe99, 0xeb2, 0x3b, 0xe81, 0xecd, 0xea5, 0xeb0, 0xe81, 0xebb, 0xe94, 0x3b, 0xeaa, 0xeb4, 0xe87, 0xeab, 0xeb2,
+0x3b, 0xe81, 0xeb1, 0xe99, 0xe8d, 0xeb2, 0x3b, 0xe95, 0xeb8, 0xea5, 0xeb2, 0x3b, 0xe9e, 0xeb0, 0xe88, 0xeb4, 0xe81, 0x3b, 0xe97, 0xeb1,
+0xe99, 0xea7, 0xeb2, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x41, 0x70, 0x72, 0x3b,
+0x4d, 0x61, 0x69, 0x3b, 0x4a, 0x16b, 0x6e, 0x3b, 0x4a, 0x16b, 0x6c, 0x3b, 0x41, 0x75, 0x67, 0x3b, 0x53, 0x65, 0x70, 0x3b,
+0x4f, 0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x65, 0x63, 0x3b, 0x6a, 0x61, 0x6e, 0x76, 0x101, 0x72, 0x69, 0x73,
+0x3b, 0x66, 0x65, 0x62, 0x72, 0x75, 0x101, 0x72, 0x69, 0x73, 0x3b, 0x6d, 0x61, 0x72, 0x74, 0x73, 0x3b, 0x61, 0x70, 0x72,
+0x12b, 0x6c, 0x69, 0x73, 0x3b, 0x6d, 0x61, 0x69, 0x6a, 0x73, 0x3b, 0x6a, 0x16b, 0x6e, 0x69, 0x6a, 0x73, 0x3b, 0x6a, 0x16b,
+0x6c, 0x69, 0x6a, 0x73, 0x3b, 0x61, 0x75, 0x67, 0x75, 0x73, 0x74, 0x73, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62,
+0x72, 0x69, 0x73, 0x3b, 0x6f, 0x6b, 0x74, 0x6f, 0x62, 0x72, 0x69, 0x73, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x72,
+0x69, 0x73, 0x3b, 0x64, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x72, 0x69, 0x73, 0x3b, 0x73, 0x31, 0x3b, 0x73, 0x32, 0x3b, 0x73,
+0x33, 0x3b, 0x73, 0x34, 0x3b, 0x73, 0x35, 0x3b, 0x73, 0x36, 0x3b, 0x73, 0x37, 0x3b, 0x73, 0x38, 0x3b, 0x73, 0x39, 0x3b,
+0x73, 0x31, 0x30, 0x3b, 0x73, 0x31, 0x31, 0x3b, 0x73, 0x31, 0x32, 0x3b, 0x73, 0xe1, 0x6e, 0x7a, 0xe1, 0x20, 0x79, 0x61,
+0x20, 0x79, 0x61, 0x6d, 0x62, 0x6f, 0x3b, 0x73, 0xe1, 0x6e, 0x7a, 0xe1, 0x20, 0x79, 0x61, 0x20, 0x6d, 0xed, 0x62, 0x61,
+0x6c, 0xe9, 0x3b, 0x73, 0xe1, 0x6e, 0x7a, 0xe1, 0x20, 0x79, 0x61, 0x20, 0x6d, 0xed, 0x73, 0xe1, 0x74, 0x6f, 0x3b, 0x73,
+0xe1, 0x6e, 0x7a, 0xe1, 0x20, 0x79, 0x61, 0x20, 0x6d, 0xed, 0x6e, 0x65, 0x69, 0x3b, 0x73, 0xe1, 0x6e, 0x7a, 0xe1, 0x20,
+0x79, 0x61, 0x20, 0x6d, 0xed, 0x74, 0xe1, 0x6e, 0x6f, 0x3b, 0x73, 0xe1, 0x6e, 0x7a, 0xe1, 0x20, 0x79, 0x61, 0x20, 0x6d,
+0x6f, 0x74, 0xf3, 0x62, 0xe1, 0x3b, 0x73, 0xe1, 0x6e, 0x7a, 0xe1, 0x20, 0x79, 0x61, 0x20, 0x6e, 0x73, 0x61, 0x6d, 0x62,
+0x6f, 0x3b, 0x73, 0xe1, 0x6e, 0x7a, 0xe1, 0x20, 0x79, 0x61, 0x20, 0x6d, 0x77, 0x61, 0x6d, 0x62, 0x65, 0x3b, 0x73, 0xe1,
+0x6e, 0x7a, 0xe1, 0x20, 0x79, 0x61, 0x20, 0x6c, 0x69, 0x62, 0x77, 0x61, 0x3b, 0x73, 0xe1, 0x6e, 0x7a, 0xe1, 0x20, 0x79,
+0x61, 0x20, 0x7a, 0xf3, 0x6d, 0x69, 0x3b, 0x73, 0xe1, 0x6e, 0x7a, 0xe1, 0x20, 0x79, 0x61, 0x20, 0x7a, 0xf3, 0x6d, 0x69,
+0x20, 0x6e, 0x61, 0x20, 0x6d, 0x254, 0x30c, 0x6b, 0x254, 0x301, 0x3b, 0x73, 0xe1, 0x6e, 0x7a, 0xe1, 0x20, 0x79, 0x61, 0x20,
+0x7a, 0xf3, 0x6d, 0x69, 0x20, 0x6e, 0x61, 0x20, 0x6d, 0xed, 0x62, 0x61, 0x6c, 0xe9, 0x3b, 0x53, 0x61, 0x75, 0x3b, 0x56,
+0x61, 0x73, 0x3b, 0x4b, 0x6f, 0x76, 0x3b, 0x42, 0x61, 0x6c, 0x3b, 0x47, 0x65, 0x67, 0x3b, 0x42, 0x69, 0x72, 0x3b, 0x4c,
+0x69, 0x65, 0x3b, 0x52, 0x67, 0x70, 0x3b, 0x52, 0x67, 0x73, 0x3b, 0x53, 0x70, 0x6c, 0x3b, 0x4c, 0x61, 0x70, 0x3b, 0x47,
+0x72, 0x64, 0x3b, 0x73, 0x61, 0x75, 0x73, 0x69, 0x6f, 0x3b, 0x76, 0x61, 0x73, 0x61, 0x72, 0x69, 0x6f, 0x3b, 0x6b, 0x6f,
+0x76, 0x6f, 0x3b, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x64, 0x17e, 0x69, 0x6f, 0x3b, 0x67, 0x65, 0x67, 0x75, 0x17e, 0x117, 0x73,
+0x3b, 0x62, 0x69, 0x72, 0x17e, 0x65, 0x6c, 0x69, 0x6f, 0x3b, 0x6c, 0x69, 0x65, 0x70, 0x6f, 0x73, 0x3b, 0x72, 0x75, 0x67,
+0x70, 0x6a, 0x16b, 0x10d, 0x69, 0x6f, 0x3b, 0x72, 0x75, 0x67, 0x73, 0x117, 0x6a, 0x6f, 0x3b, 0x73, 0x70, 0x61, 0x6c, 0x69,
+0x6f, 0x3b, 0x6c, 0x61, 0x70, 0x6b, 0x72, 0x69, 0x10d, 0x69, 0x6f, 0x3b, 0x67, 0x72, 0x75, 0x6f, 0x64, 0x17e, 0x69, 0x6f,
+0x3b, 0x458, 0x430, 0x43d, 0x2e, 0x3b, 0x444, 0x435, 0x432, 0x2e, 0x3b, 0x43c, 0x430, 0x440, 0x2e, 0x3b, 0x430, 0x43f, 0x440, 0x2e,
+0x3b, 0x43c, 0x430, 0x458, 0x3b, 0x458, 0x443, 0x43d, 0x2e, 0x3b, 0x458, 0x443, 0x43b, 0x2e, 0x3b, 0x430, 0x432, 0x433, 0x2e, 0x3b,
+0x441, 0x435, 0x43f, 0x442, 0x2e, 0x3b, 0x43e, 0x43a, 0x442, 0x2e, 0x3b, 0x43d, 0x43e, 0x435, 0x43c, 0x2e, 0x3b, 0x434, 0x435, 0x43a,
+0x435, 0x43c, 0x2e, 0x3b, 0x458, 0x430, 0x43d, 0x443, 0x430, 0x440, 0x438, 0x3b, 0x444, 0x435, 0x432, 0x440, 0x443, 0x430, 0x440, 0x438,
+0x3b, 0x43c, 0x430, 0x440, 0x442, 0x3b, 0x430, 0x43f, 0x440, 0x438, 0x43b, 0x3b, 0x43c, 0x430, 0x458, 0x3b, 0x458, 0x443, 0x43d, 0x438,
+0x3b, 0x458, 0x443, 0x43b, 0x438, 0x3b, 0x430, 0x432, 0x433, 0x443, 0x441, 0x442, 0x3b, 0x441, 0x435, 0x43f, 0x442, 0x435, 0x43c, 0x432,
+0x440, 0x438, 0x3b, 0x43e, 0x43a, 0x442, 0x43e, 0x43c, 0x432, 0x440, 0x438, 0x3b, 0x43d, 0x43e, 0x435, 0x43c, 0x432, 0x440, 0x438, 0x3b,
+0x434, 0x435, 0x43a, 0x435, 0x43c, 0x432, 0x440, 0x438, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x441, 0x3b, 0x3b,
+0x43d, 0x3b, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0x61, 0x63, 0x3b, 0x41, 0x70, 0x72, 0x3b, 0x4d,
+0x65, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x4f, 0x67, 0x6f, 0x73, 0x3b, 0x53, 0x65, 0x70, 0x3b,
+0x4f, 0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x69, 0x73, 0x3b, 0x4a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x69, 0x3b,
+0x46, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x69, 0x3b, 0x4d, 0x61, 0x63, 0x3b, 0x41, 0x70, 0x72, 0x69, 0x6c, 0x3b, 0x4d,
+0x65, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x61, 0x69, 0x3b, 0x4f, 0x67, 0x6f, 0x73, 0x3b, 0x53, 0x65,
+0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4f, 0x6b, 0x74, 0x6f, 0x62, 0x65, 0x72, 0x3b, 0x4e, 0x6f, 0x76, 0x65,
+0x6d, 0x62, 0x65, 0x72, 0x3b, 0x44, 0x69, 0x73, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0xd1c, 0xd28, 0xd41, 0x3b, 0xd2b, 0xd46,
+0xd2c, 0xd4d, 0xd30, 0xd41, 0x3b, 0xd2e, 0xd3e, 0xd30, 0xd4d, 0x200d, 0x3b, 0xd0f, 0xd2a, 0xd4d, 0xd30, 0xd3f, 0x3b, 0xd2e, 0xd47, 0xd2f,
+0xd4d, 0x3b, 0xd1c, 0xd42, 0xd23, 0xd4d, 0x200d, 0x3b, 0xd1c, 0xd42, 0xd32, 0xd48, 0x3b, 0xd06, 0xd17, 0x3b, 0xd38, 0xd46, 0xd2a, 0xd4d,
+0xd31, 0xd4d, 0xd31, 0xd02, 0x3b, 0xd12, 0xd15, 0xd4d, 0xd1f, 0xd4b, 0x3b, 0xd28, 0xd35, 0xd02, 0x3b, 0xd21, 0xd3f, 0xd38, 0xd02, 0x3b,
+0xd1c, 0xd28, 0xd41, 0xd35, 0xd30, 0xd3f, 0x3b, 0xd2b, 0xd46, 0xd2c, 0xd4d, 0xd30, 0xd41, 0xd35, 0xd30, 0xd3f, 0x3b, 0xd2e, 0xd3e, 0xd30,
+0xd4d, 0x200d, 0xd1a, 0xd4d, 0xd1a, 0xd4d, 0x3b, 0xd0f, 0xd2a, 0xd4d, 0xd30, 0xd3f, 0xd32, 0xd4d, 0x200d, 0x3b, 0xd2e, 0xd47, 0xd2f, 0xd4d,
+0x3b, 0xd1c, 0xd42, 0xd23, 0xd4d, 0x200d, 0x3b, 0xd1c, 0xd42, 0xd32, 0xd48, 0x3b, 0xd13, 0xd17, 0xd38, 0xd4d, 0xd31, 0xd4d, 0xd31, 0xd4d,
+0x3b, 0xd38, 0xd46, 0xd2a, 0xd4d, 0xd31, 0xd4d, 0xd31, 0xd02, 0xd2c, 0xd30, 0xd4d, 0x200d, 0x3b, 0xd12, 0xd15, 0xd4d, 0xd1f, 0xd4b, 0xd2c,
+0xd30, 0xd4d, 0x200d, 0x3b, 0xd28, 0xd35, 0xd02, 0xd2c, 0xd30, 0xd4d, 0x200d, 0x3b, 0xd21, 0xd3f, 0xd38, 0xd02, 0xd2c, 0xd30, 0xd4d, 0x200d,
+0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x72, 0x61, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x41, 0x70, 0x72, 0x3b, 0x4d, 0x65, 0x6a,
+0x3b, 0x120, 0x75, 0x6e, 0x3b, 0x4c, 0x75, 0x6c, 0x3b, 0x41, 0x77, 0x69, 0x3b, 0x53, 0x65, 0x74, 0x3b, 0x4f, 0x74, 0x74,
+0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x69, 0x10b, 0x3b, 0x4a, 0x61, 0x6e, 0x6e, 0x61, 0x72, 0x3b, 0x46, 0x72, 0x61, 0x72,
+0x3b, 0x4d, 0x61, 0x72, 0x7a, 0x75, 0x3b, 0x41, 0x70, 0x72, 0x69, 0x6c, 0x3b, 0x4d, 0x65, 0x6a, 0x6a, 0x75, 0x3b, 0x120,
+0x75, 0x6e, 0x6a, 0x75, 0x3b, 0x4c, 0x75, 0x6c, 0x6a, 0x75, 0x3b, 0x41, 0x77, 0x69, 0x73, 0x73, 0x75, 0x3b, 0x53, 0x65,
+0x74, 0x74, 0x65, 0x6d, 0x62, 0x72, 0x75, 0x3b, 0x4f, 0x74, 0x74, 0x75, 0x62, 0x72, 0x75, 0x3b, 0x4e, 0x6f, 0x76, 0x65,
+0x6d, 0x62, 0x72, 0x75, 0x3b, 0x44, 0x69, 0x10b, 0x65, 0x6d, 0x62, 0x72, 0x75, 0x3b, 0x91c, 0x93e, 0x928, 0x947, 0x935, 0x93e,
+0x930, 0x940, 0x3b, 0x92b, 0x947, 0x92c, 0x94d, 0x930, 0x941, 0x935, 0x93e, 0x930, 0x940, 0x3b, 0x92e, 0x93e, 0x930, 0x94d, 0x91a, 0x3b,
+0x90f, 0x92a, 0x94d, 0x930, 0x93f, 0x932, 0x3b, 0x92e, 0x947, 0x3b, 0x91c, 0x942, 0x928, 0x3b, 0x91c, 0x941, 0x932, 0x948, 0x3b, 0x913,
+0x917, 0x938, 0x94d, 0x91f, 0x3b, 0x938, 0x947, 0x92a, 0x94d, 0x91f, 0x947, 0x902, 0x92c, 0x930, 0x3b, 0x913, 0x915, 0x94d, 0x91f, 0x94b,
+0x92c, 0x930, 0x3b, 0x928, 0x94b, 0x935, 0x94d, 0x939, 0x947, 0x902, 0x92c, 0x930, 0x3b, 0x921, 0x93f, 0x938, 0x947, 0x902, 0x92c, 0x930,
+0x3b, 0x445, 0x443, 0x43b, 0x3b, 0x4af, 0x445, 0x44d, 0x3b, 0x431, 0x430, 0x440, 0x3b, 0x442, 0x443, 0x443, 0x3b, 0x43b, 0x443, 0x443,
+0x3b, 0x43c, 0x43e, 0x433, 0x3b, 0x43c, 0x43e, 0x440, 0x3b, 0x445, 0x43e, 0x43d, 0x3b, 0x431, 0x438, 0x447, 0x3b, 0x442, 0x430, 0x445,
+0x3b, 0x43d, 0x43e, 0x445, 0x3b, 0x433, 0x430, 0x445, 0x3b, 0x425, 0x443, 0x43b, 0x433, 0x430, 0x43d, 0x430, 0x3b, 0x4ae, 0x445, 0x44d,
+0x440, 0x3b, 0x411, 0x430, 0x440, 0x3b, 0x422, 0x443, 0x443, 0x43b, 0x430, 0x439, 0x3b, 0x41b, 0x443, 0x443, 0x3b, 0x41c, 0x43e, 0x433,
+0x43e, 0x439, 0x3b, 0x41c, 0x43e, 0x440, 0x44c, 0x3b, 0x425, 0x43e, 0x43d, 0x44c, 0x3b, 0x411, 0x438, 0x447, 0x3b, 0x422, 0x430, 0x445,
+0x438, 0x430, 0x3b, 0x41d, 0x43e, 0x445, 0x43e, 0x439, 0x3b, 0x413, 0x430, 0x445, 0x430, 0x439, 0x3b, 0x91c, 0x928, 0x3b, 0x92b, 0x947,
+0x92c, 0x3b, 0x92e, 0x93e, 0x930, 0x94d, 0x91a, 0x3b, 0x905, 0x92a, 0x94d, 0x930, 0x93f, 0x3b, 0x92e, 0x947, 0x3b, 0x91c, 0x941, 0x928,
+0x3b, 0x91c, 0x941, 0x932, 0x93e, 0x3b, 0x905, 0x917, 0x3b, 0x938, 0x947, 0x92a, 0x94d, 0x91f, 0x3b, 0x905, 0x915, 0x94d, 0x91f, 0x94b,
+0x3b, 0x928, 0x94b, 0x92d, 0x947, 0x3b, 0x921, 0x93f, 0x938, 0x947, 0x3b, 0x91c, 0x928, 0x935, 0x930, 0x940, 0x3b, 0x92b, 0x947, 0x92c,
+0x94d, 0x930, 0x941, 0x905, 0x930, 0x940, 0x3b, 0x92e, 0x93e, 0x930, 0x94d, 0x91a, 0x3b, 0x905, 0x92a, 0x94d, 0x930, 0x93f, 0x932, 0x3b,
+0x92e, 0x947, 0x3b, 0x91c, 0x941, 0x928, 0x3b, 0x91c, 0x941, 0x932, 0x93e, 0x908, 0x3b, 0x905, 0x917, 0x938, 0x94d, 0x924, 0x3b, 0x938,
+0x947, 0x92a, 0x94d, 0x91f, 0x947, 0x92e, 0x94d, 0x92c, 0x930, 0x3b, 0x905, 0x915, 0x94d, 0x91f, 0x94b, 0x92c, 0x930, 0x3b, 0x928, 0x94b,
+0x92d, 0x947, 0x92e, 0x94d, 0x92c, 0x930, 0x3b, 0x921, 0x93f, 0x938, 0x947, 0x92e, 0x94d, 0x92c, 0x930, 0x3b, 0x6a, 0x61, 0x6e, 0x2e,
+0x3b, 0x66, 0x65, 0x62, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x73, 0x3b, 0x61, 0x70, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x69, 0x3b,
+0x6a, 0x75, 0x6e, 0x69, 0x3b, 0x6a, 0x75, 0x6c, 0x69, 0x3b, 0x61, 0x75, 0x67, 0x2e, 0x3b, 0x73, 0x65, 0x70, 0x2e, 0x3b,
+0x6f, 0x6b, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76, 0x2e, 0x3b, 0x64, 0x65, 0x73, 0x2e, 0x3b, 0x6a, 0x61, 0x6e, 0x75, 0x61,
+0x72, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x3b, 0x6d, 0x61, 0x72, 0x73, 0x3b, 0x61, 0x70, 0x72, 0x69, 0x6c,
+0x3b, 0x6d, 0x61, 0x69, 0x3b, 0x6a, 0x75, 0x6e, 0x69, 0x3b, 0x6a, 0x75, 0x6c, 0x69, 0x3b, 0x61, 0x75, 0x67, 0x75, 0x73,
+0x74, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x6f, 0x6b, 0x74, 0x6f, 0x62, 0x65, 0x72, 0x3b,
+0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x64, 0x65, 0x73, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0xb1c, 0xb3e,
+0xb28, 0xb41, 0xb06, 0xb30, 0xb40, 0x3b, 0xb2b, 0xb47, 0xb2c, 0xb4d, 0xb30, 0xb41, 0xb5f, 0xb3e, 0xb30, 0xb40, 0x3b, 0xb2e, 0xb3e, 0xb30,
+0xb4d, 0xb1a, 0xb4d, 0xb1a, 0x3b, 0xb05, 0xb2a, 0xb4d, 0xb30, 0xb47, 0xb32, 0x3b, 0xb2e, 0xb47, 0x3b, 0xb1c, 0xb41, 0xb28, 0x3b, 0xb1c,
+0xb41, 0xb32, 0xb3e, 0xb07, 0x3b, 0xb05, 0xb17, 0xb37, 0xb4d, 0xb1f, 0x3b, 0xb38, 0xb47, 0xb2a, 0xb4d, 0xb1f, 0xb47, 0xb2e, 0xb4d, 0xb2c,
+0xb30, 0x3b, 0xb05, 0xb15, 0xb4d, 0xb1f, 0xb4b, 0xb2c, 0xb30, 0x3b, 0xb28, 0xb2d, 0xb47, 0xb2e, 0xb4d, 0xb2c, 0xb30, 0x3b, 0xb21, 0xb3f,
+0xb38, 0xb47, 0xb2e, 0xb4d, 0xb2c, 0xb30, 0x3b, 0x31, 0x3b, 0x32, 0x3b, 0x33, 0x3b, 0x34, 0x3b, 0x645, 0x640, 0x6cc, 0x3b, 0x62c,
+0x648, 0x646, 0x3b, 0x37, 0x3b, 0x38, 0x3b, 0x39, 0x3b, 0x31, 0x30, 0x3b, 0x31, 0x31, 0x3b, 0x31, 0x32, 0x3b, 0x62c, 0x646,
+0x648, 0x631, 0x64a, 0x3b, 0x641, 0x628, 0x631, 0x648, 0x631, 0x64a, 0x3b, 0x645, 0x627, 0x631, 0x686, 0x3b, 0x627, 0x67e, 0x631, 0x6cc,
+0x644, 0x3b, 0x645, 0x6cc, 0x3b, 0x62c, 0x648, 0x646, 0x3b, 0x62c, 0x648, 0x644, 0x627, 0x6cc, 0x3b, 0x627, 0x6ab, 0x633, 0x62a, 0x3b,
+0x633, 0x67e, 0x62a, 0x645, 0x628, 0x631, 0x3b, 0x627, 0x6a9, 0x62a, 0x648, 0x628, 0x631, 0x3b, 0x646, 0x648, 0x645, 0x628, 0x631, 0x3b,
+0x62f, 0x633, 0x645, 0x628, 0x631, 0x3b, 0x698, 0x627, 0x646, 0x648, 0x6cc, 0x647, 0x654, 0x3b, 0x641, 0x648, 0x631, 0x6cc, 0x647, 0x654,
+0x3b, 0x645, 0x627, 0x631, 0x633, 0x3b, 0x622, 0x648, 0x631, 0x6cc, 0x644, 0x3b, 0x645, 0x647, 0x654, 0x3b, 0x698, 0x648, 0x626, 0x646,
+0x3b, 0x698, 0x648, 0x626, 0x6cc, 0x647, 0x654, 0x3b, 0x627, 0x648, 0x62a, 0x3b, 0x633, 0x67e, 0x62a, 0x627, 0x645, 0x628, 0x631, 0x3b,
+0x627, 0x6a9, 0x62a, 0x628, 0x631, 0x3b, 0x646, 0x648, 0x627, 0x645, 0x628, 0x631, 0x3b, 0x62f, 0x633, 0x627, 0x645, 0x628, 0x631, 0x3b,
+0x62c, 0x646, 0x648, 0x3b, 0x641, 0x648, 0x631, 0x6cc, 0x647, 0x654, 0x3b, 0x645, 0x627, 0x631, 0x633, 0x3b, 0x622, 0x648, 0x631, 0x6cc,
+0x644, 0x3b, 0x645, 0x640, 0x6cc, 0x3b, 0x62c, 0x648, 0x646, 0x3b, 0x62c, 0x648, 0x644, 0x3b, 0x627, 0x648, 0x62a, 0x3b, 0x633, 0x67e,
+0x62a, 0x627, 0x645, 0x628, 0x631, 0x3b, 0x627, 0x6a9, 0x62a, 0x628, 0x631, 0x3b, 0x646, 0x648, 0x627, 0x645, 0x628, 0x631, 0x3b, 0x62f,
+0x633, 0x645, 0x3b, 0x62c, 0x646, 0x648, 0x631, 0x6cc, 0x3b, 0x641, 0x628, 0x631, 0x648, 0x631, 0x6cc, 0x3b, 0x645, 0x627, 0x631, 0x686,
+0x3b, 0x627, 0x67e, 0x631, 0x6cc, 0x644, 0x3b, 0x645, 0x6cc, 0x3b, 0x62c, 0x648, 0x646, 0x3b, 0x62c, 0x648, 0x644, 0x627, 0x6cc, 0x3b,
+0x627, 0x6af, 0x633, 0x62a, 0x3b, 0x633, 0x67e, 0x62a, 0x645, 0x628, 0x631, 0x3b, 0x627, 0x6a9, 0x62a, 0x648, 0x628, 0x631, 0x3b, 0x646,
+0x648, 0x645, 0x628, 0x631, 0x3b, 0x62f, 0x633, 0x645, 0x628, 0x631, 0x3b, 0x73, 0x74, 0x79, 0x3b, 0x6c, 0x75, 0x74, 0x3b, 0x6d,
+0x61, 0x72, 0x3b, 0x6b, 0x77, 0x69, 0x3b, 0x6d, 0x61, 0x6a, 0x3b, 0x63, 0x7a, 0x65, 0x3b, 0x6c, 0x69, 0x70, 0x3b, 0x73,
+0x69, 0x65, 0x3b, 0x77, 0x72, 0x7a, 0x3b, 0x70, 0x61, 0x17a, 0x3b, 0x6c, 0x69, 0x73, 0x3b, 0x67, 0x72, 0x75, 0x3b, 0x73,
+0x74, 0x79, 0x63, 0x7a, 0x6e, 0x69, 0x61, 0x3b, 0x6c, 0x75, 0x74, 0x65, 0x67, 0x6f, 0x3b, 0x6d, 0x61, 0x72, 0x63, 0x61,
+0x3b, 0x6b, 0x77, 0x69, 0x65, 0x74, 0x6e, 0x69, 0x61, 0x3b, 0x6d, 0x61, 0x6a, 0x61, 0x3b, 0x63, 0x7a, 0x65, 0x72, 0x77,
+0x63, 0x61, 0x3b, 0x6c, 0x69, 0x70, 0x63, 0x61, 0x3b, 0x73, 0x69, 0x65, 0x72, 0x70, 0x6e, 0x69, 0x61, 0x3b, 0x77, 0x72,
+0x7a, 0x65, 0x15b, 0x6e, 0x69, 0x61, 0x3b, 0x70, 0x61, 0x17a, 0x64, 0x7a, 0x69, 0x65, 0x72, 0x6e, 0x69, 0x6b, 0x61, 0x3b,
+0x6c, 0x69, 0x73, 0x74, 0x6f, 0x70, 0x61, 0x64, 0x61, 0x3b, 0x67, 0x72, 0x75, 0x64, 0x6e, 0x69, 0x61, 0x3b, 0x4a, 0x61,
+0x6e, 0x3b, 0x46, 0x65, 0x76, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x41, 0x62, 0x72, 0x3b, 0x4d, 0x61, 0x69, 0x3b, 0x4a, 0x75,
+0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x41, 0x67, 0x6f, 0x3b, 0x53, 0x65, 0x74, 0x3b, 0x4f, 0x75, 0x74, 0x3b, 0x4e, 0x6f,
+0x76, 0x3b, 0x44, 0x65, 0x7a, 0x3b, 0x4a, 0x61, 0x6e, 0x65, 0x69, 0x72, 0x6f, 0x3b, 0x46, 0x65, 0x76, 0x65, 0x72, 0x65,
+0x69, 0x72, 0x6f, 0x3b, 0x4d, 0x61, 0x72, 0xe7, 0x6f, 0x3b, 0x41, 0x62, 0x72, 0x69, 0x6c, 0x3b, 0x4d, 0x61, 0x69, 0x6f,
+0x3b, 0x4a, 0x75, 0x6e, 0x68, 0x6f, 0x3b, 0x4a, 0x75, 0x6c, 0x68, 0x6f, 0x3b, 0x41, 0x67, 0x6f, 0x73, 0x74, 0x6f, 0x3b,
+0x53, 0x65, 0x74, 0x65, 0x6d, 0x62, 0x72, 0x6f, 0x3b, 0x4f, 0x75, 0x74, 0x75, 0x62, 0x72, 0x6f, 0x3b, 0x4e, 0x6f, 0x76,
+0x65, 0x6d, 0x62, 0x72, 0x6f, 0x3b, 0x44, 0x65, 0x7a, 0x65, 0x6d, 0x62, 0x72, 0x6f, 0x3b, 0x6a, 0x61, 0x6e, 0x3b, 0x66,
+0x65, 0x76, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x61, 0x62, 0x72, 0x3b, 0x6d, 0x61, 0x69, 0x3b, 0x6a, 0x75, 0x6e, 0x3b, 0x6a,
+0x75, 0x6c, 0x3b, 0x61, 0x67, 0x6f, 0x3b, 0x73, 0x65, 0x74, 0x3b, 0x6f, 0x75, 0x74, 0x3b, 0x6e, 0x6f, 0x76, 0x3b, 0x64,
+0x65, 0x7a, 0x3b, 0x6a, 0x61, 0x6e, 0x65, 0x69, 0x72, 0x6f, 0x3b, 0x66, 0x65, 0x76, 0x65, 0x72, 0x65, 0x69, 0x72, 0x6f,
+0x3b, 0x6d, 0x61, 0x72, 0xe7, 0x6f, 0x3b, 0x61, 0x62, 0x72, 0x69, 0x6c, 0x3b, 0x6d, 0x61, 0x69, 0x6f, 0x3b, 0x6a, 0x75,
+0x6e, 0x68, 0x6f, 0x3b, 0x6a, 0x75, 0x6c, 0x68, 0x6f, 0x3b, 0x61, 0x67, 0x6f, 0x73, 0x74, 0x6f, 0x3b, 0x73, 0x65, 0x74,
+0x65, 0x6d, 0x62, 0x72, 0x6f, 0x3b, 0x6f, 0x75, 0x74, 0x75, 0x62, 0x72, 0x6f, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62,
+0x72, 0x6f, 0x3b, 0x64, 0x65, 0x7a, 0x65, 0x6d, 0x62, 0x72, 0x6f, 0x3b, 0xa1c, 0xa28, 0xa35, 0xa30, 0xa40, 0x3b, 0xa2b, 0xa3c,
+0xa30, 0xa35, 0xa30, 0xa40, 0x3b, 0xa2e, 0xa3e, 0xa30, 0xa1a, 0x3b, 0xa05, 0xa2a, 0xa4d, 0xa30, 0xa48, 0xa32, 0x3b, 0xa2e, 0xa08, 0x3b,
+0xa1c, 0xa42, 0xa28, 0x3b, 0xa1c, 0xa41, 0xa32, 0xa3e, 0xa08, 0x3b, 0xa05, 0xa17, 0xa38, 0xa24, 0x3b, 0xa38, 0xa24, 0xa70, 0xa2c, 0xa30,
+0x3b, 0xa05, 0xa15, 0xa24, 0xa42, 0xa2c, 0xa30, 0x3b, 0xa28, 0xa35, 0xa70, 0xa2c, 0xa30, 0x3b, 0xa26, 0xa38, 0xa70, 0xa2c, 0xa30, 0x3b,
+0x69, 0x61, 0x6e, 0x2e, 0x3b, 0x66, 0x65, 0x62, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x2e, 0x3b, 0x61, 0x70, 0x72, 0x2e, 0x3b,
+0x6d, 0x61, 0x69, 0x3b, 0x69, 0x75, 0x6e, 0x2e, 0x3b, 0x69, 0x75, 0x6c, 0x2e, 0x3b, 0x61, 0x75, 0x67, 0x2e, 0x3b, 0x73,
+0x65, 0x70, 0x74, 0x2e, 0x3b, 0x6f, 0x63, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76, 0x2e, 0x3b, 0x64, 0x65, 0x63, 0x2e, 0x3b,
+0x69, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x69, 0x65, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x69, 0x65, 0x3b, 0x6d,
+0x61, 0x72, 0x74, 0x69, 0x65, 0x3b, 0x61, 0x70, 0x72, 0x69, 0x6c, 0x69, 0x65, 0x3b, 0x6d, 0x61, 0x69, 0x3b, 0x69, 0x75,
+0x6e, 0x69, 0x65, 0x3b, 0x69, 0x75, 0x6c, 0x69, 0x65, 0x3b, 0x61, 0x75, 0x67, 0x75, 0x73, 0x74, 0x3b, 0x73, 0x65, 0x70,
+0x74, 0x65, 0x6d, 0x62, 0x72, 0x69, 0x65, 0x3b, 0x6f, 0x63, 0x74, 0x6f, 0x6d, 0x62, 0x72, 0x69, 0x65, 0x3b, 0x6e, 0x6f,
+0x69, 0x65, 0x6d, 0x62, 0x72, 0x69, 0x65, 0x3b, 0x64, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x72, 0x69, 0x65, 0x3b, 0x44f, 0x43d,
+0x432, 0x2e, 0x3b, 0x444, 0x435, 0x432, 0x440, 0x2e, 0x3b, 0x43c, 0x430, 0x440, 0x442, 0x430, 0x3b, 0x430, 0x43f, 0x440, 0x2e, 0x3b,
+0x43c, 0x430, 0x44f, 0x3b, 0x438, 0x44e, 0x43d, 0x44f, 0x3b, 0x438, 0x44e, 0x43b, 0x44f, 0x3b, 0x430, 0x432, 0x433, 0x2e, 0x3b, 0x441,
+0x435, 0x43d, 0x442, 0x2e, 0x3b, 0x43e, 0x43a, 0x442, 0x2e, 0x3b, 0x43d, 0x43e, 0x44f, 0x431, 0x2e, 0x3b, 0x434, 0x435, 0x43a, 0x2e,
+0x3b, 0x44f, 0x43d, 0x432, 0x430, 0x440, 0x44f, 0x3b, 0x444, 0x435, 0x432, 0x440, 0x430, 0x43b, 0x44f, 0x3b, 0x43c, 0x430, 0x440, 0x442,
+0x430, 0x3b, 0x430, 0x43f, 0x440, 0x435, 0x43b, 0x44f, 0x3b, 0x43c, 0x430, 0x44f, 0x3b, 0x438, 0x44e, 0x43d, 0x44f, 0x3b, 0x438, 0x44e,
+0x43b, 0x44f, 0x3b, 0x430, 0x432, 0x433, 0x443, 0x441, 0x442, 0x430, 0x3b, 0x441, 0x435, 0x43d, 0x442, 0x44f, 0x431, 0x440, 0x44f, 0x3b,
+0x43e, 0x43a, 0x442, 0x44f, 0x431, 0x440, 0x44f, 0x3b, 0x43d, 0x43e, 0x44f, 0x431, 0x440, 0x44f, 0x3b, 0x434, 0x435, 0x43a, 0x430, 0x431,
+0x440, 0x44f, 0x3b, 0x458, 0x430, 0x43d, 0x3b, 0x444, 0x435, 0x431, 0x3b, 0x43c, 0x430, 0x440, 0x3b, 0x430, 0x43f, 0x440, 0x3b, 0x43c,
+0x430, 0x458, 0x3b, 0x458, 0x443, 0x43d, 0x3b, 0x458, 0x443, 0x43b, 0x3b, 0x430, 0x432, 0x433, 0x3b, 0x441, 0x435, 0x43f, 0x3b, 0x43e,
+0x43a, 0x442, 0x3b, 0x43d, 0x43e, 0x432, 0x3b, 0x434, 0x435, 0x446, 0x3b, 0x458, 0x430, 0x43d, 0x443, 0x430, 0x440, 0x3b, 0x444, 0x435,
+0x431, 0x440, 0x443, 0x430, 0x440, 0x3b, 0x43c, 0x430, 0x440, 0x442, 0x3b, 0x430, 0x43f, 0x440, 0x438, 0x43b, 0x3b, 0x43c, 0x430, 0x458,
+0x3b, 0x458, 0x443, 0x43d, 0x3b, 0x458, 0x443, 0x43b, 0x3b, 0x430, 0x432, 0x433, 0x443, 0x441, 0x442, 0x3b, 0x441, 0x435, 0x43f, 0x442,
+0x435, 0x43c, 0x431, 0x430, 0x440, 0x3b, 0x43e, 0x43a, 0x442, 0x43e, 0x431, 0x430, 0x440, 0x3b, 0x43d, 0x43e, 0x432, 0x435, 0x43c, 0x431,
+0x430, 0x440, 0x3b, 0x434, 0x435, 0x446, 0x435, 0x43c, 0x431, 0x430, 0x440, 0x3b, 0x458, 0x430, 0x43d, 0x443, 0x430, 0x440, 0x3b, 0x444,
+0x435, 0x431, 0x440, 0x443, 0x430, 0x440, 0x3b, 0x43c, 0x430, 0x440, 0x442, 0x3b, 0x430, 0x43f, 0x440, 0x438, 0x43b, 0x3b, 0x43c, 0x430,
+0x458, 0x3b, 0x458, 0x443, 0x43d, 0x438, 0x3b, 0x458, 0x443, 0x43b, 0x438, 0x3b, 0x430, 0x432, 0x433, 0x443, 0x441, 0x442, 0x3b, 0x441,
+0x435, 0x43f, 0x442, 0x435, 0x43c, 0x431, 0x430, 0x440, 0x3b, 0x43e, 0x43a, 0x442, 0x43e, 0x431, 0x430, 0x440, 0x3b, 0x43d, 0x43e, 0x432,
+0x435, 0x43c, 0x431, 0x430, 0x440, 0x3b, 0x434, 0x435, 0x446, 0x435, 0x43c, 0x431, 0x430, 0x440, 0x3b, 0x6a, 0x61, 0x6e, 0x3b, 0x66,
+0x65, 0x62, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x61, 0x70, 0x72, 0x3b, 0x6d, 0x61, 0x6a, 0x3b, 0x6a, 0x75, 0x6e, 0x3b, 0x6a,
+0x75, 0x6c, 0x3b, 0x61, 0x76, 0x67, 0x3b, 0x73, 0x65, 0x70, 0x3b, 0x6f, 0x6b, 0x74, 0x3b, 0x6e, 0x6f, 0x76, 0x3b, 0x64,
+0x65, 0x63, 0x3b, 0x6a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x3b, 0x6d, 0x61,
+0x72, 0x74, 0x3b, 0x61, 0x70, 0x72, 0x69, 0x6c, 0x3b, 0x6d, 0x61, 0x6a, 0x3b, 0x6a, 0x75, 0x6e, 0x3b, 0x6a, 0x75, 0x6c,
+0x3b, 0x61, 0x76, 0x67, 0x75, 0x73, 0x74, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x61, 0x72, 0x3b, 0x6f, 0x6b,
+0x74, 0x6f, 0x62, 0x61, 0x72, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x61, 0x72, 0x3b, 0x64, 0x65, 0x63, 0x65, 0x6d,
+0x62, 0x61, 0x72, 0x3b, 0x50, 0x68, 0x65, 0x3b, 0x4b, 0x6f, 0x6c, 0x3b, 0x55, 0x62, 0x65, 0x3b, 0x4d, 0x6d, 0x65, 0x3b,
+0x4d, 0x6f, 0x74, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x55, 0x70, 0x75, 0x3b, 0x50, 0x68, 0x61, 0x3b, 0x4c, 0x65, 0x6f, 0x3b,
+0x4d, 0x70, 0x68, 0x3b, 0x50, 0x75, 0x6e, 0x3b, 0x54, 0x73, 0x68, 0x3b, 0x50, 0x68, 0x65, 0x73, 0x65, 0x6b, 0x67, 0x6f,
+0x6e, 0x67, 0x3b, 0x48, 0x6c, 0x61, 0x6b, 0x6f, 0x6c, 0x61, 0x3b, 0x48, 0x6c, 0x61, 0x6b, 0x75, 0x62, 0x65, 0x6c, 0x65,
+0x3b, 0x4d, 0x6d, 0x65, 0x73, 0x65, 0x3b, 0x4d, 0x6f, 0x74, 0x73, 0x68, 0x65, 0x61, 0x6e, 0x6f, 0x6e, 0x67, 0x3b, 0x50,
+0x68, 0x75, 0x70, 0x6a, 0x61, 0x6e, 0x65, 0x3b, 0x50, 0x68, 0x75, 0x70, 0x75, 0x3b, 0x50, 0x68, 0x61, 0x74, 0x61, 0x3b,
+0x4c, 0x65, 0x6f, 0x74, 0x73, 0x68, 0x65, 0x3b, 0x4d, 0x70, 0x68, 0x61, 0x6c, 0x61, 0x6e, 0x65, 0x3b, 0x50, 0x75, 0x6e,
+0x64, 0x75, 0x6e, 0x67, 0x77, 0x61, 0x6e, 0x65, 0x3b, 0x54, 0x73, 0x68, 0x69, 0x74, 0x77, 0x65, 0x3b, 0x46, 0x65, 0x72,
+0x3b, 0x54, 0x6c, 0x68, 0x3b, 0x4d, 0x6f, 0x70, 0x3b, 0x4d, 0x6f, 0x72, 0x3b, 0x4d, 0x6f, 0x74, 0x3b, 0x53, 0x65, 0x65,
+0x3b, 0x50, 0x68, 0x75, 0x3b, 0x50, 0x68, 0x61, 0x3b, 0x4c, 0x77, 0x65, 0x3b, 0x44, 0x69, 0x70, 0x3b, 0x4e, 0x67, 0x77,
+0x3b, 0x53, 0x65, 0x64, 0x3b, 0x46, 0x65, 0x72, 0x69, 0x6b, 0x67, 0x6f, 0x6e, 0x67, 0x3b, 0x54, 0x6c, 0x68, 0x61, 0x6b,
+0x6f, 0x6c, 0x65, 0x3b, 0x4d, 0x6f, 0x70, 0x69, 0x74, 0x6c, 0x6f, 0x3b, 0x4d, 0x6f, 0x72, 0x61, 0x6e, 0x61, 0x6e, 0x67,
+0x3b, 0x4d, 0x6f, 0x74, 0x73, 0x68, 0x65, 0x67, 0x61, 0x6e, 0x61, 0x6e, 0x67, 0x3b, 0x53, 0x65, 0x65, 0x74, 0x65, 0x62,
+0x6f, 0x73, 0x69, 0x67, 0x6f, 0x3b, 0x50, 0x68, 0x75, 0x6b, 0x77, 0x69, 0x3b, 0x50, 0x68, 0x61, 0x74, 0x77, 0x65, 0x3b,
+0x4c, 0x77, 0x65, 0x74, 0x73, 0x65, 0x3b, 0x44, 0x69, 0x70, 0x68, 0x61, 0x6c, 0x61, 0x6e, 0x65, 0x3b, 0x4e, 0x67, 0x77,
+0x61, 0x6e, 0x61, 0x74, 0x73, 0x65, 0x6c, 0x65, 0x3b, 0x53, 0x65, 0x64, 0x69, 0x6d, 0x6f, 0x6e, 0x74, 0x68, 0x6f, 0x6c,
+0x65, 0x3b, 0xda2, 0xdb1, 0x3b, 0xdb4, 0xdd9, 0xdb6, 0x3b, 0xdb8, 0xdcf, 0xdbb, 0xdca, 0xdad, 0x3b, 0xd85, 0xdb4, 0xdca, 0x200d, 0xdbb,
+0xdda, 0xdbd, 0x3b, 0xdb8, 0xdd0, 0xdba, 0x3b, 0xda2, 0xdd6, 0xdb1, 0x3b, 0xda2, 0xdd6, 0xdbd, 0x3b, 0xd85, 0xd9c, 0xddd, 0x3b, 0xdc3,
+0xdd0, 0xdb4, 0x3b, 0xd94, 0xd9a, 0x3b, 0xdb1, 0xddc, 0xdc0, 0xdd0, 0x3b, 0xdaf, 0xdd9, 0xdc3, 0xdd0, 0x3b, 0xda2, 0xdb1, 0xdc0, 0xdcf,
+0xdbb, 0x3b, 0xdb4, 0xdd9, 0xdb6, 0xdbb, 0xdc0, 0xdcf, 0xdbb, 0x3b, 0xdb8, 0xdcf, 0xdbb, 0xdca, 0xdad, 0x3b, 0xd85, 0xdb4, 0xdca, 0x200d,
+0xdbb, 0xdda, 0xdbd, 0xdca, 0x3b, 0xdb8, 0xdd0, 0xdba, 0xdd2, 0x3b, 0xda2, 0xdd6, 0xdb1, 0x3b, 0xda2, 0xdd6, 0xdbd, 0xdd2, 0x3b, 0xd85,
+0xd9c, 0xddd, 0xdc3, 0xdca, 0xdad, 0xdd4, 0x3b, 0xdc3, 0xdd0, 0xdb4, 0xdca, 0xdad, 0xdd0, 0xdb8, 0xdca, 0xdb6, 0xdbb, 0xdca, 0x3b, 0xd94,
+0xd9a, 0xdca, 0xdad, 0xddd, 0xdb6, 0xdbb, 0xdca, 0x3b, 0xdb1, 0xddc, 0xdc0, 0xdd0, 0xdb8, 0xdca, 0xdb6, 0xdbb, 0xdca, 0x3b, 0xdaf, 0xdd9,
+0xdc3, 0xdd0, 0xdb8, 0xdca, 0xdb6, 0xdbb, 0xdca, 0x3b, 0x42, 0x68, 0x69, 0x3b, 0x56, 0x61, 0x6e, 0x3b, 0x56, 0x6f, 0x6c, 0x3b,
+0x4d, 0x61, 0x62, 0x3b, 0x4e, 0x6b, 0x68, 0x3b, 0x4e, 0x68, 0x6c, 0x3b, 0x4b, 0x68, 0x6f, 0x3b, 0x4e, 0x67, 0x63, 0x3b,
+0x4e, 0x79, 0x6f, 0x3b, 0x4d, 0x70, 0x68, 0x3b, 0x4c, 0x77, 0x65, 0x3b, 0x4e, 0x67, 0x6f, 0x3b, 0x42, 0x68, 0x69, 0x6d,
+0x62, 0x69, 0x64, 0x76, 0x77, 0x61, 0x6e, 0x65, 0x3b, 0x69, 0x4e, 0x64, 0x6c, 0x6f, 0x76, 0x61, 0x6e, 0x61, 0x3b, 0x69,
+0x4e, 0x64, 0x6c, 0x6f, 0x76, 0x75, 0x2d, 0x6c, 0x65, 0x6e, 0x6b, 0x68, 0x75, 0x6c, 0x75, 0x3b, 0x4d, 0x61, 0x62, 0x61,
+0x73, 0x61, 0x3b, 0x69, 0x4e, 0x6b, 0x68, 0x77, 0x65, 0x6b, 0x68, 0x77, 0x65, 0x74, 0x69, 0x3b, 0x69, 0x4e, 0x68, 0x6c,
+0x61, 0x62, 0x61, 0x3b, 0x4b, 0x68, 0x6f, 0x6c, 0x77, 0x61, 0x6e, 0x65, 0x3b, 0x69, 0x4e, 0x67, 0x63, 0x69, 0x3b, 0x69,
+0x4e, 0x79, 0x6f, 0x6e, 0x69, 0x3b, 0x69, 0x4d, 0x70, 0x68, 0x61, 0x6c, 0x61, 0x3b, 0x4c, 0x77, 0x65, 0x74, 0x69, 0x3b,
+0x69, 0x4e, 0x67, 0x6f, 0x6e, 0x67, 0x6f, 0x6e, 0x69, 0x3b, 0x6a, 0x61, 0x6e, 0x3b, 0x66, 0x65, 0x62, 0x3b, 0x6d, 0x61,
+0x72, 0x3b, 0x61, 0x70, 0x72, 0x3b, 0x6d, 0xe1, 0x6a, 0x3b, 0x6a, 0xfa, 0x6e, 0x3b, 0x6a, 0xfa, 0x6c, 0x3b, 0x61, 0x75,
+0x67, 0x3b, 0x73, 0x65, 0x70, 0x3b, 0x6f, 0x6b, 0x74, 0x3b, 0x6e, 0x6f, 0x76, 0x3b, 0x64, 0x65, 0x63, 0x3b, 0x6a, 0x61,
+0x6e, 0x75, 0xe1, 0x72, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x75, 0xe1, 0x72, 0x3b, 0x6d, 0x61, 0x72, 0x65, 0x63, 0x3b, 0x61,
+0x70, 0x72, 0xed, 0x6c, 0x3b, 0x6d, 0xe1, 0x6a, 0x3b, 0x6a, 0xfa, 0x6e, 0x3b, 0x6a, 0xfa, 0x6c, 0x3b, 0x61, 0x75, 0x67,
+0x75, 0x73, 0x74, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x6f, 0x6b, 0x74, 0xf3, 0x62, 0x65,
+0x72, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x64, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b,
+0x6a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x3b, 0x6d, 0x61, 0x72, 0x65, 0x63,
+0x3b, 0x61, 0x70, 0x72, 0x69, 0x6c, 0x3b, 0x6d, 0x61, 0x6a, 0x3b, 0x6a, 0x75, 0x6e, 0x69, 0x6a, 0x3b, 0x6a, 0x75, 0x6c,
+0x69, 0x6a, 0x3b, 0x61, 0x76, 0x67, 0x75, 0x73, 0x74, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b,
+0x6f, 0x6b, 0x74, 0x6f, 0x62, 0x65, 0x72, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x64, 0x65, 0x63,
+0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4b, 0x6f, 0x62, 0x3b, 0x4c, 0x61, 0x62, 0x3b, 0x53, 0x61, 0x64, 0x3b, 0x41, 0x66,
+0x72, 0x3b, 0x53, 0x68, 0x61, 0x3b, 0x4c, 0x69, 0x78, 0x3b, 0x54, 0x6f, 0x64, 0x3b, 0x53, 0x69, 0x64, 0x3b, 0x53, 0x61,
+0x67, 0x3b, 0x54, 0x6f, 0x62, 0x3b, 0x4b, 0x49, 0x54, 0x3b, 0x4c, 0x49, 0x54, 0x3b, 0x42, 0x69, 0x73, 0x68, 0x61, 0x20,
+0x4b, 0x6f, 0x6f, 0x62, 0x61, 0x61, 0x64, 0x3b, 0x42, 0x69, 0x73, 0x68, 0x61, 0x20, 0x4c, 0x61, 0x62, 0x61, 0x61, 0x64,
+0x3b, 0x42, 0x69, 0x73, 0x68, 0x61, 0x20, 0x53, 0x61, 0x64, 0x64, 0x65, 0x78, 0x61, 0x61, 0x64, 0x3b, 0x42, 0x69, 0x73,
+0x68, 0x61, 0x20, 0x41, 0x66, 0x72, 0x61, 0x61, 0x64, 0x3b, 0x42, 0x69, 0x73, 0x68, 0x61, 0x20, 0x53, 0x68, 0x61, 0x6e,
+0x61, 0x61, 0x64, 0x3b, 0x42, 0x69, 0x73, 0x68, 0x61, 0x20, 0x4c, 0x69, 0x78, 0x61, 0x61, 0x64, 0x3b, 0x42, 0x69, 0x73,
+0x68, 0x61, 0x20, 0x54, 0x6f, 0x64, 0x6f, 0x62, 0x61, 0x61, 0x64, 0x3b, 0x42, 0x69, 0x73, 0x68, 0x61, 0x20, 0x53, 0x69,
+0x64, 0x65, 0x65, 0x64, 0x61, 0x61, 0x64, 0x3b, 0x42, 0x69, 0x73, 0x68, 0x61, 0x20, 0x53, 0x61, 0x67, 0x61, 0x61, 0x6c,
+0x61, 0x61, 0x64, 0x3b, 0x42, 0x69, 0x73, 0x68, 0x61, 0x20, 0x54, 0x6f, 0x62, 0x6e, 0x61, 0x61, 0x64, 0x3b, 0x42, 0x69,
+0x73, 0x68, 0x61, 0x20, 0x4b, 0x6f, 0x77, 0x20, 0x69, 0x79, 0x6f, 0x20, 0x54, 0x6f, 0x62, 0x6e, 0x61, 0x61, 0x64, 0x3b,
+0x42, 0x69, 0x73, 0x68, 0x61, 0x20, 0x4c, 0x61, 0x62, 0x61, 0x20, 0x69, 0x79, 0x6f, 0x20, 0x54, 0x6f, 0x62, 0x6e, 0x61,
+0x61, 0x64, 0x3b, 0x65, 0x6e, 0x65, 0x3b, 0x66, 0x65, 0x62, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x61, 0x62, 0x72, 0x3b, 0x6d,
+0x61, 0x79, 0x3b, 0x6a, 0x75, 0x6e, 0x3b, 0x6a, 0x75, 0x6c, 0x3b, 0x61, 0x67, 0x6f, 0x3b, 0x73, 0x65, 0x70, 0x3b, 0x6f,
+0x63, 0x74, 0x3b, 0x6e, 0x6f, 0x76, 0x3b, 0x64, 0x69, 0x63, 0x3b, 0x65, 0x6e, 0x65, 0x72, 0x6f, 0x3b, 0x66, 0x65, 0x62,
+0x72, 0x65, 0x72, 0x6f, 0x3b, 0x6d, 0x61, 0x72, 0x7a, 0x6f, 0x3b, 0x61, 0x62, 0x72, 0x69, 0x6c, 0x3b, 0x6d, 0x61, 0x79,
+0x6f, 0x3b, 0x6a, 0x75, 0x6e, 0x69, 0x6f, 0x3b, 0x6a, 0x75, 0x6c, 0x69, 0x6f, 0x3b, 0x61, 0x67, 0x6f, 0x73, 0x74, 0x6f,
+0x3b, 0x73, 0x65, 0x70, 0x74, 0x69, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x6f, 0x63, 0x74, 0x75, 0x62, 0x72, 0x65, 0x3b,
+0x6e, 0x6f, 0x76, 0x69, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x64, 0x69, 0x63, 0x69, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b,
+0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0x61, 0x63, 0x3b, 0x41, 0x70, 0x72, 0x3b, 0x4d, 0x65, 0x69, 0x3b,
+0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x41, 0x67, 0x6f, 0x3b, 0x53, 0x65, 0x70, 0x3b, 0x4f, 0x6b, 0x74, 0x3b,
+0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x65, 0x73, 0x3b, 0x4a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x69, 0x3b, 0x46, 0x65, 0x62, 0x72,
+0x75, 0x61, 0x72, 0x69, 0x3b, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x3b, 0x41, 0x70, 0x72, 0x69, 0x6c, 0x69, 0x3b, 0x4d, 0x65,
+0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x69, 0x3b, 0x4a, 0x75, 0x6c, 0x61, 0x69, 0x3b, 0x41, 0x67, 0x6f, 0x73, 0x74, 0x69, 0x3b,
+0x53, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x4f, 0x6b, 0x74, 0x6f, 0x62, 0x61, 0x3b, 0x4e, 0x6f, 0x76, 0x65,
+0x6d, 0x62, 0x61, 0x3b, 0x44, 0x65, 0x73, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x6a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x69, 0x3b,
+0x66, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x69, 0x3b, 0x6d, 0x61, 0x72, 0x73, 0x3b, 0x61, 0x70, 0x72, 0x69, 0x6c, 0x3b,
+0x6d, 0x61, 0x6a, 0x3b, 0x6a, 0x75, 0x6e, 0x69, 0x3b, 0x6a, 0x75, 0x6c, 0x69, 0x3b, 0x61, 0x75, 0x67, 0x75, 0x73, 0x74,
+0x69, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x6f, 0x6b, 0x74, 0x6f, 0x62, 0x65, 0x72, 0x3b,
+0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x64, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x42f, 0x43d,
+0x432, 0x3b, 0x424, 0x435, 0x432, 0x3b, 0x41c, 0x430, 0x440, 0x3b, 0x410, 0x43f, 0x440, 0x3b, 0x41c, 0x430, 0x439, 0x3b, 0x418, 0x44e,
+0x43d, 0x3b, 0x418, 0x44e, 0x43b, 0x3b, 0x410, 0x432, 0x433, 0x3b, 0x421, 0x435, 0x43d, 0x3b, 0x41e, 0x43a, 0x442, 0x3b, 0x41d, 0x43e,
+0x44f, 0x3b, 0x414, 0x435, 0x43a, 0x3b, 0x42f, 0x43d, 0x432, 0x430, 0x440, 0x3b, 0x424, 0x435, 0x432, 0x440, 0x430, 0x43b, 0x3b, 0x41c,
+0x430, 0x440, 0x442, 0x3b, 0x410, 0x43f, 0x440, 0x435, 0x43b, 0x3b, 0x41c, 0x430, 0x439, 0x3b, 0x418, 0x44e, 0x43d, 0x3b, 0x418, 0x44e,
+0x43b, 0x3b, 0x410, 0x432, 0x433, 0x443, 0x441, 0x442, 0x3b, 0x421, 0x435, 0x43d, 0x442, 0x44f, 0x431, 0x440, 0x3b, 0x41e, 0x43a, 0x442,
+0x44f, 0x431, 0x440, 0x3b, 0x41d, 0x43e, 0x44f, 0x431, 0x440, 0x3b, 0x414, 0x435, 0x43a, 0x430, 0x431, 0x440, 0x3b, 0xb9c, 0xba9, 0x2e,
+0x3b, 0xbaa, 0xbbf, 0xbaa, 0xbcd, 0x2e, 0x3b, 0xbae, 0xbbe, 0xbb0, 0xbcd, 0x2e, 0x3b, 0xb8f, 0xbaa, 0xbcd, 0x2e, 0x3b, 0xbae, 0xbc7,
+0x3b, 0xb9c, 0xbc2, 0xba9, 0xbcd, 0x3b, 0xb9c, 0xbc2, 0xbb2, 0xbc8, 0x3b, 0xb86, 0xb95, 0x2e, 0x3b, 0xb9a, 0xbc6, 0xbaa, 0xbcd, 0x2e,
+0x3b, 0xb85, 0xb95, 0xbcd, 0x2e, 0x3b, 0xba8, 0xbb5, 0x2e, 0x3b, 0xb9f, 0xbbf, 0xb9a, 0x2e, 0x3b, 0xb9c, 0xba9, 0xbb5, 0xbb0, 0xbbf,
+0x3b, 0xbaa, 0xbbf, 0xbaa, 0xbcd, 0xbb0, 0xbb5, 0xbb0, 0xbbf, 0x3b, 0xbae, 0xbbe, 0xbb0, 0xbcd, 0xb9a, 0xbcd, 0x3b, 0xb8f, 0xbaa, 0xbcd,
+0xbb0, 0xbb2, 0xbcd, 0x3b, 0xbae, 0xbc7, 0x3b, 0xb9c, 0xbc2, 0xba9, 0xbcd, 0x3b, 0xb9c, 0xbc2, 0xbb2, 0xbc8, 0x3b, 0xb86, 0xb95, 0xbb8,
+0xbcd, 0xb9f, 0xbcd, 0x3b, 0xb9a, 0xbc6, 0xbaa, 0xbcd, 0xb9f, 0xbae, 0xbcd, 0xbaa, 0xbb0, 0xbcd, 0x3b, 0xb85, 0xb95, 0xbcd, 0xb9f, 0xbcb,
+0xbaa, 0xbb0, 0xbcd, 0x3b, 0xba8, 0xbb5, 0xbae, 0xbcd, 0xbaa, 0xbb0, 0xbcd, 0x3b, 0xb9f, 0xbbf, 0xb9a, 0xbae, 0xbcd, 0xbaa, 0xbb0, 0xbcd,
+0x3b, 0xc1c, 0xc28, 0xc35, 0xc30, 0xc3f, 0x3b, 0xc2b, 0xc3f, 0xc2c, 0xc4d, 0xc30, 0xc35, 0xc30, 0xc3f, 0x3b, 0xc2e, 0xc3e, 0xc30, 0xc4d,
+0xc1a, 0xc3f, 0x3b, 0xc0f, 0xc2a, 0xc4d, 0xc30, 0xc3f, 0xc32, 0xc4d, 0x3b, 0xc2e, 0xc47, 0x3b, 0xc1c, 0xc42, 0xc28, 0xc4d, 0x3b, 0xc1c,
+0xc42, 0xc32, 0xc48, 0x3b, 0xc06, 0xc17, 0xc38, 0xc4d, 0xc1f, 0xc41, 0x3b, 0xc38, 0xc46, 0xc2a, 0xc4d, 0xc1f, 0xc46, 0xc02, 0xc2c, 0xc30,
+0xc4d, 0x3b, 0xc05, 0xc15, 0xc4d, 0xc1f, 0xc4b, 0xc2c, 0xc30, 0xc4d, 0x3b, 0xc28, 0xc35, 0xc02, 0xc2c, 0xc30, 0xc4d, 0x3b, 0xc21, 0xc3f,
+0xc38, 0xc46, 0xc02, 0xc2c, 0xc30, 0xc4d, 0x3b, 0xe21, 0x2e, 0xe04, 0x2e, 0x3b, 0xe01, 0x2e, 0xe1e, 0x2e, 0x3b, 0xe21, 0xe35, 0x2e,
+0xe04, 0x2e, 0x3b, 0xe40, 0xe21, 0x2e, 0xe22, 0x2e, 0x3b, 0xe1e, 0x2e, 0xe04, 0x2e, 0x3b, 0xe21, 0xe34, 0x2e, 0xe22, 0x2e, 0x3b,
+0xe01, 0x2e, 0xe04, 0x2e, 0x3b, 0xe2a, 0x2e, 0xe04, 0x2e, 0x3b, 0xe01, 0x2e, 0xe22, 0x2e, 0x3b, 0xe15, 0x2e, 0xe04, 0x2e, 0x3b,
+0xe1e, 0x2e, 0xe22, 0x2e, 0x3b, 0xe18, 0x2e, 0xe04, 0x2e, 0x3b, 0xe21, 0xe01, 0xe23, 0xe32, 0xe04, 0xe21, 0x3b, 0xe01, 0xe38, 0xe21,
+0xe20, 0xe32, 0xe1e, 0xe31, 0xe19, 0xe18, 0xe4c, 0x3b, 0xe21, 0xe35, 0xe19, 0xe32, 0xe04, 0xe21, 0x3b, 0xe40, 0xe21, 0xe29, 0xe32, 0xe22,
+0xe19, 0x3b, 0xe1e, 0xe24, 0xe29, 0xe20, 0xe32, 0xe04, 0xe21, 0x3b, 0xe21, 0xe34, 0xe16, 0xe38, 0xe19, 0xe32, 0xe22, 0xe19, 0x3b, 0xe01,
+0xe23, 0xe01, 0xe0e, 0xe32, 0xe04, 0xe21, 0x3b, 0xe2a, 0xe34, 0xe07, 0xe2b, 0xe32, 0xe04, 0xe21, 0x3b, 0xe01, 0xe31, 0xe19, 0xe22, 0xe32,
+0xe22, 0xe19, 0x3b, 0xe15, 0xe38, 0xe25, 0xe32, 0xe04, 0xe21, 0x3b, 0xe1e, 0xe24, 0xe28, 0xe08, 0xe34, 0xe01, 0xe32, 0xe22, 0xe19, 0x3b,
+0xe18, 0xe31, 0xe19, 0xe27, 0xe32, 0xe04, 0xe21, 0x3b, 0x1325, 0x122a, 0x3b, 0x1208, 0x12ab, 0x1272, 0x3b, 0x1218, 0x130b, 0x1262, 0x3b, 0x121a,
+0x12eb, 0x12dd, 0x3b, 0x130d, 0x1295, 0x1266, 0x3b, 0x1230, 0x1290, 0x3b, 0x1213, 0x121d, 0x1208, 0x3b, 0x1290, 0x1213, 0x1230, 0x3b, 0x1218, 0x1235,
+0x12a8, 0x3b, 0x1325, 0x1245, 0x121d, 0x3b, 0x1215, 0x12f3, 0x122d, 0x3b, 0x1273, 0x1215, 0x1233, 0x3b, 0x1325, 0x122a, 0x3b, 0x1208, 0x12ab, 0x1272,
+0x1275, 0x3b, 0x1218, 0x130b, 0x1262, 0x1275, 0x3b, 0x121a, 0x12eb, 0x12dd, 0x12eb, 0x3b, 0x130d, 0x1295, 0x1266, 0x1275, 0x3b, 0x1230, 0x1290, 0x3b,
+0x1213, 0x121d, 0x1208, 0x3b, 0x1290, 0x1213, 0x1230, 0x3b, 0x1218, 0x1235, 0x12a8, 0x1228, 0x121d, 0x3b, 0x1325, 0x1245, 0x121d, 0x1272, 0x3b, 0x1215,
+0x12f3, 0x122d, 0x3b, 0x1273, 0x1215, 0x1233, 0x1235, 0x3b, 0x53, 0x101, 0x6e, 0x3b, 0x46, 0x113, 0x70, 0x3b, 0x4d, 0x61, 0x2bb, 0x61,
+0x3b, 0x2bb, 0x45, 0x70, 0x65, 0x3b, 0x4d, 0x113, 0x3b, 0x53, 0x75, 0x6e, 0x3b, 0x53, 0x69, 0x75, 0x3b, 0x2bb, 0x41, 0x6f,
+0x6b, 0x3b, 0x53, 0x113, 0x70, 0x3b, 0x2bb, 0x4f, 0x6b, 0x61, 0x3b, 0x4e, 0x14d, 0x76, 0x3b, 0x54, 0x69, 0x73, 0x3b, 0x53,
+0x101, 0x6e, 0x75, 0x61, 0x6c, 0x69, 0x3b, 0x46, 0x113, 0x70, 0x75, 0x65, 0x6c, 0x69, 0x3b, 0x4d, 0x61, 0x2bb, 0x61, 0x73,
+0x69, 0x3b, 0x2bb, 0x45, 0x70, 0x65, 0x6c, 0x65, 0x6c, 0x69, 0x3b, 0x4d, 0x113, 0x3b, 0x53, 0x75, 0x6e, 0x65, 0x3b, 0x53,
+0x69, 0x75, 0x6c, 0x61, 0x69, 0x3b, 0x2bb, 0x41, 0x6f, 0x6b, 0x6f, 0x73, 0x69, 0x3b, 0x53, 0x113, 0x70, 0x69, 0x74, 0x65,
+0x6d, 0x61, 0x3b, 0x2bb, 0x4f, 0x6b, 0x61, 0x74, 0x6f, 0x70, 0x61, 0x3b, 0x4e, 0x14d, 0x76, 0x65, 0x6d, 0x61, 0x3b, 0x54,
+0x69, 0x73, 0x65, 0x6d, 0x61, 0x3b, 0x53, 0x75, 0x6e, 0x3b, 0x59, 0x61, 0x6e, 0x3b, 0x4b, 0x75, 0x6c, 0x3b, 0x44, 0x7a,
+0x69, 0x3b, 0x4d, 0x75, 0x64, 0x3b, 0x4b, 0x68, 0x6f, 0x3b, 0x4d, 0x61, 0x77, 0x3b, 0x4d, 0x68, 0x61, 0x3b, 0x4e, 0x64,
+0x7a, 0x3b, 0x4e, 0x68, 0x6c, 0x3b, 0x48, 0x75, 0x6b, 0x3b, 0x4e, 0x27, 0x77, 0x3b, 0x53, 0x75, 0x6e, 0x67, 0x75, 0x74,
+0x69, 0x3b, 0x4e, 0x79, 0x65, 0x6e, 0x79, 0x65, 0x6e, 0x79, 0x61, 0x6e, 0x69, 0x3b, 0x4e, 0x79, 0x65, 0x6e, 0x79, 0x61,
+0x6e, 0x6b, 0x75, 0x6c, 0x75, 0x3b, 0x44, 0x7a, 0x69, 0x76, 0x61, 0x6d, 0x69, 0x73, 0x6f, 0x6b, 0x6f, 0x3b, 0x4d, 0x75,
+0x64, 0x79, 0x61, 0x78, 0x69, 0x68, 0x69, 0x3b, 0x4b, 0x68, 0x6f, 0x74, 0x61, 0x76, 0x75, 0x78, 0x69, 0x6b, 0x61, 0x3b,
+0x4d, 0x61, 0x77, 0x75, 0x77, 0x61, 0x6e, 0x69, 0x3b, 0x4d, 0x68, 0x61, 0x77, 0x75, 0x72, 0x69, 0x3b, 0x4e, 0x64, 0x7a,
+0x68, 0x61, 0x74, 0x69, 0x3b, 0x4e, 0x68, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x6c, 0x61, 0x3b, 0x48, 0x75, 0x6b, 0x75, 0x72,
+0x69, 0x3b, 0x4e, 0x27, 0x77, 0x65, 0x6e, 0x64, 0x7a, 0x61, 0x6d, 0x68, 0x61, 0x6c, 0x61, 0x3b, 0x4f, 0x63, 0x61, 0x3b,
+0x15e, 0x75, 0x62, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x4e, 0x69, 0x73, 0x3b, 0x4d, 0x61, 0x79, 0x3b, 0x48, 0x61, 0x7a, 0x3b,
+0x54, 0x65, 0x6d, 0x3b, 0x41, 0x11f, 0x75, 0x3b, 0x45, 0x79, 0x6c, 0x3b, 0x45, 0x6b, 0x69, 0x3b, 0x4b, 0x61, 0x73, 0x3b,
+0x41, 0x72, 0x61, 0x3b, 0x4f, 0x63, 0x61, 0x6b, 0x3b, 0x15e, 0x75, 0x62, 0x61, 0x74, 0x3b, 0x4d, 0x61, 0x72, 0x74, 0x3b,
+0x4e, 0x69, 0x73, 0x61, 0x6e, 0x3b, 0x4d, 0x61, 0x79, 0x131, 0x73, 0x3b, 0x48, 0x61, 0x7a, 0x69, 0x72, 0x61, 0x6e, 0x3b,
+0x54, 0x65, 0x6d, 0x6d, 0x75, 0x7a, 0x3b, 0x41, 0x11f, 0x75, 0x73, 0x74, 0x6f, 0x73, 0x3b, 0x45, 0x79, 0x6c, 0xfc, 0x6c,
+0x3b, 0x45, 0x6b, 0x69, 0x6d, 0x3b, 0x4b, 0x61, 0x73, 0x131, 0x6d, 0x3b, 0x41, 0x72, 0x61, 0x6c, 0x131, 0x6b, 0x3b, 0x441,
+0x456, 0x447, 0x2e, 0x3b, 0x43b, 0x44e, 0x442, 0x2e, 0x3b, 0x431, 0x435, 0x440, 0x2e, 0x3b, 0x43a, 0x432, 0x456, 0x442, 0x2e, 0x3b,
+0x442, 0x440, 0x430, 0x432, 0x2e, 0x3b, 0x447, 0x435, 0x440, 0x432, 0x2e, 0x3b, 0x43b, 0x438, 0x43f, 0x2e, 0x3b, 0x441, 0x435, 0x440,
+0x43f, 0x2e, 0x3b, 0x432, 0x435, 0x440, 0x2e, 0x3b, 0x436, 0x43e, 0x432, 0x442, 0x2e, 0x3b, 0x43b, 0x438, 0x441, 0x442, 0x2e, 0x3b,
+0x433, 0x440, 0x443, 0x434, 0x2e, 0x3b, 0x441, 0x456, 0x447, 0x43d, 0x44f, 0x3b, 0x43b, 0x44e, 0x442, 0x43e, 0x433, 0x43e, 0x3b, 0x431,
+0x435, 0x440, 0x435, 0x437, 0x43d, 0x44f, 0x3b, 0x43a, 0x432, 0x456, 0x442, 0x43d, 0x44f, 0x3b, 0x442, 0x440, 0x430, 0x432, 0x43d, 0x44f,
+0x3b, 0x447, 0x435, 0x440, 0x432, 0x43d, 0x44f, 0x3b, 0x43b, 0x438, 0x43f, 0x43d, 0x44f, 0x3b, 0x441, 0x435, 0x440, 0x43f, 0x43d, 0x44f,
+0x3b, 0x432, 0x435, 0x440, 0x435, 0x441, 0x43d, 0x44f, 0x3b, 0x436, 0x43e, 0x432, 0x442, 0x43d, 0x44f, 0x3b, 0x43b, 0x438, 0x441, 0x442,
+0x43e, 0x43f, 0x430, 0x434, 0x430, 0x3b, 0x433, 0x440, 0x443, 0x434, 0x43d, 0x44f, 0x3b, 0x62c, 0x646, 0x648, 0x631, 0x6cc, 0x3b, 0x641,
+0x631, 0x648, 0x631, 0x6cc, 0x3b, 0x645, 0x627, 0x631, 0x20, 0x686, 0x3b, 0x627, 0x67e, 0x631, 0x64a, 0x644, 0x3b, 0x645, 0x626, 0x3b,
+0x62c, 0x648, 0x646, 0x3b, 0x62c, 0x648, 0x644, 0x627, 0x626, 0x3b, 0x627, 0x6af, 0x633, 0x62a, 0x3b, 0x633, 0x62a, 0x645, 0x628, 0x631,
+0x3b, 0x627, 0x6a9, 0x62a, 0x648, 0x628, 0x631, 0x3b, 0x646, 0x648, 0x645, 0x628, 0x631, 0x3b, 0x62f, 0x633, 0x645, 0x628, 0x631, 0x3b,
+0x41c, 0x443, 0x4b3, 0x430, 0x440, 0x440, 0x430, 0x43c, 0x3b, 0x421, 0x430, 0x444, 0x430, 0x440, 0x3b, 0x420, 0x430, 0x431, 0x438, 0x443,
+0x43b, 0x2d, 0x430, 0x432, 0x432, 0x430, 0x43b, 0x3b, 0x420, 0x430, 0x431, 0x438, 0x443, 0x43b, 0x2d, 0x43e, 0x445, 0x438, 0x440, 0x3b,
+0x416, 0x443, 0x43c, 0x43e, 0x434, 0x438, 0x443, 0x43b, 0x2d, 0x443, 0x43b, 0x43e, 0x3b, 0x416, 0x443, 0x43c, 0x43e, 0x434, 0x438, 0x443,
+0x43b, 0x2d, 0x443, 0x445, 0x440, 0x43e, 0x3b, 0x420, 0x430, 0x436, 0x430, 0x431, 0x3b, 0x428, 0x430, 0x44a, 0x431, 0x43e, 0x43d, 0x3b,
+0x420, 0x430, 0x43c, 0x430, 0x437, 0x43e, 0x43d, 0x3b, 0x428, 0x430, 0x432, 0x432, 0x43e, 0x43b, 0x3b, 0x417, 0x438, 0x43b, 0x2d, 0x49b,
+0x430, 0x44a, 0x434, 0x430, 0x3b, 0x417, 0x438, 0x43b, 0x2d, 0x4b3, 0x438, 0x436, 0x436, 0x430, 0x3b, 0x74, 0x68, 0x67, 0x20, 0x31,
+0x3b, 0x74, 0x68, 0x67, 0x20, 0x32, 0x3b, 0x74, 0x68, 0x67, 0x20, 0x33, 0x3b, 0x74, 0x68, 0x67, 0x20, 0x34, 0x3b, 0x74,
+0x68, 0x67, 0x20, 0x35, 0x3b, 0x74, 0x68, 0x67, 0x20, 0x36, 0x3b, 0x74, 0x68, 0x67, 0x20, 0x37, 0x3b, 0x74, 0x68, 0x67,
+0x20, 0x38, 0x3b, 0x74, 0x68, 0x67, 0x20, 0x39, 0x3b, 0x74, 0x68, 0x67, 0x20, 0x31, 0x30, 0x3b, 0x74, 0x68, 0x67, 0x20,
+0x31, 0x31, 0x3b, 0x74, 0x68, 0x67, 0x20, 0x31, 0x32, 0x3b, 0x74, 0x68, 0xe1, 0x6e, 0x67, 0x20, 0x6d, 0x1ed9, 0x74, 0x3b,
+0x74, 0x68, 0xe1, 0x6e, 0x67, 0x20, 0x68, 0x61, 0x69, 0x3b, 0x74, 0x68, 0xe1, 0x6e, 0x67, 0x20, 0x62, 0x61, 0x3b, 0x74,
+0x68, 0xe1, 0x6e, 0x67, 0x20, 0x74, 0x1b0, 0x3b, 0x74, 0x68, 0xe1, 0x6e, 0x67, 0x20, 0x6e, 0x103, 0x6d, 0x3b, 0x74, 0x68,
+0xe1, 0x6e, 0x67, 0x20, 0x73, 0xe1, 0x75, 0x3b, 0x74, 0x68, 0xe1, 0x6e, 0x67, 0x20, 0x62, 0x1ea3, 0x79, 0x3b, 0x74, 0x68,
+0xe1, 0x6e, 0x67, 0x20, 0x74, 0xe1, 0x6d, 0x3b, 0x74, 0x68, 0xe1, 0x6e, 0x67, 0x20, 0x63, 0x68, 0xed, 0x6e, 0x3b, 0x74,
+0x68, 0xe1, 0x6e, 0x67, 0x20, 0x6d, 0x1b0, 0x1edd, 0x69, 0x3b, 0x74, 0x68, 0xe1, 0x6e, 0x67, 0x20, 0x6d, 0x1b0, 0x1edd, 0x69,
+0x20, 0x6d, 0x1ed9, 0x74, 0x3b, 0x74, 0x68, 0xe1, 0x6e, 0x67, 0x20, 0x6d, 0x1b0, 0x1edd, 0x69, 0x20, 0x68, 0x61, 0x69, 0x3b,
+0x49, 0x6f, 0x6e, 0x3b, 0x43, 0x68, 0x77, 0x65, 0x66, 0x3b, 0x4d, 0x61, 0x77, 0x72, 0x74, 0x68, 0x3b, 0x45, 0x62, 0x72,
+0x69, 0x6c, 0x6c, 0x3b, 0x4d, 0x61, 0x69, 0x3b, 0x4d, 0x65, 0x68, 0x3b, 0x47, 0x6f, 0x72, 0x66, 0x66, 0x3b, 0x41, 0x77,
+0x73, 0x74, 0x3b, 0x4d, 0x65, 0x64, 0x69, 0x3b, 0x48, 0x79, 0x64, 0x3b, 0x54, 0x61, 0x63, 0x68, 0x3b, 0x52, 0x68, 0x61,
+0x67, 0x3b, 0x49, 0x6f, 0x6e, 0x61, 0x77, 0x72, 0x3b, 0x43, 0x68, 0x77, 0x65, 0x66, 0x72, 0x6f, 0x72, 0x3b, 0x4d, 0x61,
+0x77, 0x72, 0x74, 0x68, 0x3b, 0x45, 0x62, 0x72, 0x69, 0x6c, 0x6c, 0x3b, 0x4d, 0x61, 0x69, 0x3b, 0x4d, 0x65, 0x68, 0x65,
+0x66, 0x69, 0x6e, 0x3b, 0x47, 0x6f, 0x72, 0x66, 0x66, 0x65, 0x6e, 0x61, 0x66, 0x3b, 0x41, 0x77, 0x73, 0x74, 0x3b, 0x4d,
+0x65, 0x64, 0x69, 0x3b, 0x48, 0x79, 0x64, 0x72, 0x65, 0x66, 0x3b, 0x54, 0x61, 0x63, 0x68, 0x77, 0x65, 0x64, 0x64, 0x3b,
+0x52, 0x68, 0x61, 0x67, 0x66, 0x79, 0x72, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0x61, 0x74, 0x3b,
+0x45, 0x70, 0x72, 0x3b, 0x4d, 0x65, 0x79, 0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x41, 0x67, 0x61, 0x3b,
+0x53, 0x65, 0x70, 0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x69, 0x73, 0x3b, 0x4a, 0x61, 0x6e, 0x79,
+0x75, 0x77, 0x61, 0x72, 0x69, 0x3b, 0x46, 0x65, 0x62, 0x72, 0x75, 0x77, 0x61, 0x72, 0x69, 0x3b, 0x4d, 0x61, 0x74, 0x73,
+0x68, 0x69, 0x3b, 0x45, 0x70, 0x72, 0x65, 0x6c, 0x69, 0x3b, 0x4d, 0x65, 0x79, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x69, 0x3b,
+0x4a, 0x75, 0x6c, 0x61, 0x79, 0x69, 0x3b, 0x41, 0x67, 0x61, 0x73, 0x74, 0x69, 0x3b, 0x53, 0x65, 0x70, 0x74, 0x65, 0x6d,
+0x62, 0x61, 0x3b, 0x4f, 0x6b, 0x74, 0x68, 0x6f, 0x62, 0x61, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x44,
+0x69, 0x73, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x1e62, 0x1eb9, 0x301, 0x72, 0x1eb9, 0x301, 0x3b, 0xc8, 0x72, 0xe8, 0x6c, 0xe8, 0x3b,
+0x1eb8, 0x72, 0x1eb9, 0x300, 0x6e, 0xe0, 0x3b, 0xcc, 0x67, 0x62, 0xe9, 0x3b, 0x1eb8, 0x300, 0x62, 0x69, 0x62, 0x69, 0x3b, 0xd2,
+0x6b, 0xfa, 0x64, 0x75, 0x3b, 0x41, 0x67, 0x1eb9, 0x6d, 0x1ecd, 0x3b, 0xd2, 0x67, 0xfa, 0x6e, 0x3b, 0x4f, 0x77, 0x65, 0x77,
+0x65, 0x3b, 0x1ecc, 0x300, 0x77, 0xe0, 0x72, 0xe0, 0x3b, 0x42, 0xe9, 0x6c, 0xfa, 0x3b, 0x1ecc, 0x300, 0x70, 0x1eb9, 0x300, 0x3b,
+0x4f, 0x1e63, 0xf9, 0x20, 0x1e62, 0x1eb9, 0x301, 0x72, 0x1eb9, 0x301, 0x3b, 0x4f, 0x1e63, 0xf9, 0x20, 0xc8, 0x72, 0xe8, 0x6c, 0xe8,
+0x3b, 0x4f, 0x1e63, 0xf9, 0x20, 0x1eb8, 0x72, 0x1eb9, 0x300, 0x6e, 0xe0, 0x3b, 0x4f, 0x1e63, 0xf9, 0x20, 0xcc, 0x67, 0x62, 0xe9,
+0x3b, 0x4f, 0x1e63, 0xf9, 0x20, 0x1eb8, 0x300, 0x62, 0x69, 0x62, 0x69, 0x3b, 0x4f, 0x1e63, 0xf9, 0x20, 0xd2, 0x6b, 0xfa, 0x64,
+0x75, 0x3b, 0x4f, 0x1e63, 0xf9, 0x20, 0x41, 0x67, 0x1eb9, 0x6d, 0x1ecd, 0x3b, 0x4f, 0x1e63, 0xf9, 0x20, 0xd2, 0x67, 0xfa, 0x6e,
+0x3b, 0x4f, 0x1e63, 0xf9, 0x20, 0x4f, 0x77, 0x65, 0x77, 0x65, 0x3b, 0x4f, 0x1e63, 0xf9, 0x20, 0x1ecc, 0x300, 0x77, 0xe0, 0x72,
+0xe0, 0x3b, 0x4f, 0x1e63, 0xf9, 0x20, 0x42, 0xe9, 0x6c, 0xfa, 0x3b, 0x4f, 0x1e63, 0xf9, 0x20, 0x1ecc, 0x300, 0x70, 0x1eb9, 0x300,
+0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0x61, 0x73, 0x3b, 0x41, 0x70, 0x72, 0x3b, 0x4d, 0x65, 0x79,
+0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x41, 0x67, 0x61, 0x3b, 0x53, 0x65, 0x70, 0x3b, 0x4f, 0x6b, 0x74,
+0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x69, 0x73, 0x3b, 0x4a, 0x61, 0x6e, 0x75, 0x77, 0x61, 0x72, 0x69, 0x3b, 0x46, 0x65,
+0x62, 0x72, 0x75, 0x77, 0x61, 0x72, 0x69, 0x3b, 0x4d, 0x61, 0x73, 0x68, 0x69, 0x3b, 0x41, 0x70, 0x72, 0x65, 0x6c, 0x69,
+0x3b, 0x4d, 0x65, 0x79, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x69, 0x3b, 0x4a, 0x75, 0x6c, 0x61, 0x79, 0x69, 0x3b, 0x41, 0x67,
+0x61, 0x73, 0x74, 0x69, 0x3b, 0x53, 0x65, 0x70, 0x74, 0x68, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x4f, 0x6b, 0x74, 0x68, 0x6f,
+0x62, 0x61, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x44, 0x69, 0x73, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x4a,
+0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x41, 0x70, 0x72, 0x3b, 0x4d, 0x61, 0x6a, 0x3b, 0x4a,
+0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x41, 0x76, 0x67, 0x3b, 0x53, 0x65, 0x70, 0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e,
+0x6f, 0x76, 0x3b, 0x44, 0x65, 0x63, 0x3b, 0x4a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x3b, 0x46, 0x65, 0x62, 0x72, 0x75, 0x61,
+0x72, 0x3b, 0x4d, 0x61, 0x72, 0x74, 0x3b, 0x41, 0x70, 0x72, 0x69, 0x6c, 0x3b, 0x4d, 0x61, 0x6a, 0x3b, 0x4a, 0x75, 0x6e,
+0x69, 0x3b, 0x4a, 0x75, 0x6c, 0x69, 0x3b, 0x41, 0x76, 0x67, 0x75, 0x73, 0x74, 0x3b, 0x53, 0x65, 0x70, 0x74, 0x65, 0x6d,
+0x62, 0x61, 0x72, 0x3b, 0x4f, 0x6b, 0x74, 0x6f, 0x62, 0x61, 0x72, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x61, 0x72,
+0x3b, 0x44, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x61, 0x72, 0x3b, 0x4a, 0x2d, 0x67, 0x75, 0x65, 0x72, 0x3b, 0x54, 0x2d, 0x61,
+0x72, 0x72, 0x65, 0x65, 0x3b, 0x4d, 0x61, 0x79, 0x72, 0x6e, 0x74, 0x3b, 0x41, 0x76, 0x72, 0x72, 0x69, 0x6c, 0x3b, 0x42,
+0x6f, 0x61, 0x6c, 0x64, 0x79, 0x6e, 0x3b, 0x4d, 0x2d, 0x73, 0x6f, 0x75, 0x72, 0x65, 0x65, 0x3b, 0x4a, 0x2d, 0x73, 0x6f,
+0x75, 0x72, 0x65, 0x65, 0x3b, 0x4c, 0x75, 0x61, 0x6e, 0x69, 0x73, 0x74, 0x79, 0x6e, 0x3b, 0x4d, 0x2d, 0x66, 0x6f, 0x75,
+0x79, 0x69, 0x72, 0x3b, 0x4a, 0x2d, 0x66, 0x6f, 0x75, 0x79, 0x69, 0x72, 0x3b, 0x4d, 0x2e, 0x48, 0x6f, 0x75, 0x6e, 0x65,
+0x79, 0x3b, 0x4d, 0x2e, 0x4e, 0x6f, 0x6c, 0x6c, 0x69, 0x63, 0x6b, 0x3b, 0x4a, 0x65, 0x72, 0x72, 0x65, 0x79, 0x2d, 0x67,
+0x65, 0x75, 0x72, 0x65, 0x65, 0x3b, 0x54, 0x6f, 0x73, 0x68, 0x69, 0x61, 0x67, 0x68, 0x74, 0x2d, 0x61, 0x72, 0x72, 0x65,
+0x65, 0x3b, 0x4d, 0x61, 0x79, 0x72, 0x6e, 0x74, 0x3b, 0x41, 0x76, 0x65, 0x72, 0x69, 0x6c, 0x3b, 0x42, 0x6f, 0x61, 0x6c,
+0x64, 0x79, 0x6e, 0x3b, 0x4d, 0x65, 0x61, 0x6e, 0x2d, 0x73, 0x6f, 0x75, 0x72, 0x65, 0x65, 0x3b, 0x4a, 0x65, 0x72, 0x72,
+0x65, 0x79, 0x2d, 0x73, 0x6f, 0x75, 0x72, 0x65, 0x65, 0x3b, 0x4c, 0x75, 0x61, 0x6e, 0x69, 0x73, 0x74, 0x79, 0x6e, 0x3b,
+0x4d, 0x65, 0x61, 0x6e, 0x2d, 0x66, 0x6f, 0x75, 0x79, 0x69, 0x72, 0x3b, 0x4a, 0x65, 0x72, 0x72, 0x65, 0x79, 0x2d, 0x66,
+0x6f, 0x75, 0x79, 0x69, 0x72, 0x3b, 0x4d, 0x65, 0x65, 0x20, 0x48, 0x6f, 0x75, 0x6e, 0x65, 0x79, 0x3b, 0x4d, 0x65, 0x65,
+0x20, 0x6e, 0x79, 0x20, 0x4e, 0x6f, 0x6c, 0x6c, 0x69, 0x63, 0x6b, 0x3b, 0x47, 0x65, 0x6e, 0x3b, 0x57, 0x68, 0x65, 0x3b,
+0x4d, 0x65, 0x72, 0x3b, 0x45, 0x62, 0x72, 0x3b, 0x4d, 0x65, 0x3b, 0x45, 0x66, 0x6e, 0x3b, 0x47, 0x6f, 0x72, 0x3b, 0x45,
+0x73, 0x74, 0x3b, 0x47, 0x77, 0x6e, 0x3b, 0x48, 0x65, 0x64, 0x3b, 0x44, 0x75, 0x3b, 0x4b, 0x65, 0x76, 0x3b, 0x4d, 0x79,
+0x73, 0x20, 0x47, 0x65, 0x6e, 0x76, 0x65, 0x72, 0x3b, 0x4d, 0x79, 0x73, 0x20, 0x57, 0x68, 0x65, 0x76, 0x72, 0x65, 0x6c,
+0x3b, 0x4d, 0x79, 0x73, 0x20, 0x4d, 0x65, 0x72, 0x74, 0x68, 0x3b, 0x4d, 0x79, 0x73, 0x20, 0x45, 0x62, 0x72, 0x65, 0x6c,
+0x3b, 0x4d, 0x79, 0x73, 0x20, 0x4d, 0x65, 0x3b, 0x4d, 0x79, 0x73, 0x20, 0x45, 0x66, 0x61, 0x6e, 0x3b, 0x4d, 0x79, 0x73,
+0x20, 0x47, 0x6f, 0x72, 0x74, 0x68, 0x65, 0x72, 0x65, 0x6e, 0x3b, 0x4d, 0x79, 0x65, 0x20, 0x45, 0x73, 0x74, 0x3b, 0x4d,
+0x79, 0x73, 0x20, 0x47, 0x77, 0x79, 0x6e, 0x67, 0x61, 0x6c, 0x61, 0x3b, 0x4d, 0x79, 0x73, 0x20, 0x48, 0x65, 0x64, 0x72,
+0x61, 0x3b, 0x4d, 0x79, 0x73, 0x20, 0x44, 0x75, 0x3b, 0x4d, 0x79, 0x73, 0x20, 0x4b, 0x65, 0x76, 0x61, 0x72, 0x64, 0x68,
+0x75, 0x3b, 0x53, 0x2d, 0x186, 0x3b, 0x4b, 0x2d, 0x186, 0x3b, 0x45, 0x2d, 0x186, 0x3b, 0x45, 0x2d, 0x4f, 0x3b, 0x45, 0x2d,
+0x4b, 0x3b, 0x4f, 0x2d, 0x41, 0x3b, 0x41, 0x2d, 0x4b, 0x3b, 0x44, 0x2d, 0x186, 0x3b, 0x46, 0x2d, 0x190, 0x3b, 0x186, 0x2d,
+0x41, 0x3b, 0x186, 0x2d, 0x4f, 0x3b, 0x4d, 0x2d, 0x186, 0x3b, 0x53, 0x61, 0x6e, 0x64, 0x61, 0x2d, 0x186, 0x70, 0x25b, 0x70,
+0x254, 0x6e, 0x3b, 0x4b, 0x77, 0x61, 0x6b, 0x77, 0x61, 0x72, 0x2d, 0x186, 0x67, 0x79, 0x65, 0x66, 0x75, 0x6f, 0x3b, 0x45,
+0x62, 0x254, 0x77, 0x2d, 0x186, 0x62, 0x65, 0x6e, 0x65, 0x6d, 0x3b, 0x45, 0x62, 0x254, 0x62, 0x69, 0x72, 0x61, 0x2d, 0x4f,
+0x66, 0x6f, 0x72, 0x69, 0x73, 0x75, 0x6f, 0x3b, 0x45, 0x73, 0x75, 0x73, 0x6f, 0x77, 0x20, 0x41, 0x6b, 0x65, 0x74, 0x73,
+0x65, 0x61, 0x62, 0x61, 0x2d, 0x4b, 0x254, 0x74, 0x254, 0x6e, 0x69, 0x6d, 0x62, 0x61, 0x3b, 0x4f, 0x62, 0x69, 0x72, 0x61,
+0x64, 0x65, 0x2d, 0x41, 0x79, 0x25b, 0x77, 0x6f, 0x68, 0x6f, 0x6d, 0x75, 0x6d, 0x75, 0x3b, 0x41, 0x79, 0x25b, 0x77, 0x6f,
+0x68, 0x6f, 0x2d, 0x4b, 0x69, 0x74, 0x61, 0x77, 0x6f, 0x6e, 0x73, 0x61, 0x3b, 0x44, 0x69, 0x66, 0x75, 0x75, 0x2d, 0x186,
+0x73, 0x61, 0x6e, 0x64, 0x61, 0x61, 0x3b, 0x46, 0x61, 0x6e, 0x6b, 0x77, 0x61, 0x2d, 0x190, 0x62, 0x254, 0x3b, 0x186, 0x62,
+0x25b, 0x73, 0x25b, 0x2d, 0x41, 0x68, 0x69, 0x6e, 0x69, 0x6d, 0x65, 0x3b, 0x186, 0x62, 0x65, 0x72, 0x25b, 0x66, 0x25b, 0x77,
+0x2d, 0x4f, 0x62, 0x75, 0x62, 0x75, 0x6f, 0x3b, 0x4d, 0x75, 0x6d, 0x75, 0x2d, 0x186, 0x70, 0x25b, 0x6e, 0x69, 0x6d, 0x62,
+0x61, 0x3b, 0x91c, 0x93e, 0x928, 0x947, 0x935, 0x93e, 0x930, 0x940, 0x3b, 0x92b, 0x947, 0x92c, 0x943, 0x935, 0x93e, 0x930, 0x940, 0x3b,
+0x92e, 0x93e, 0x930, 0x94d, 0x91a, 0x3b, 0x90f, 0x92a, 0x94d, 0x930, 0x93f, 0x932, 0x3b, 0x92e, 0x947, 0x3b, 0x91c, 0x942, 0x928, 0x3b,
+0x91c, 0x941, 0x932, 0x948, 0x3b, 0x913, 0x917, 0x938, 0x94d, 0x91f, 0x3b, 0x938, 0x947, 0x92a, 0x94d, 0x91f, 0x947, 0x902, 0x92c, 0x930,
+0x3b, 0x913, 0x915, 0x94d, 0x91f, 0x94b, 0x92c, 0x930, 0x3b, 0x928, 0x94b, 0x935, 0x94d, 0x939, 0x947, 0x902, 0x92c, 0x930, 0x3b, 0x921,
+0x93f, 0x938, 0x947, 0x902, 0x92c, 0x930, 0x3b, 0x41, 0x68, 0x61, 0x3b, 0x4f, 0x66, 0x6c, 0x3b, 0x4f, 0x63, 0x68, 0x3b, 0x41,
+0x62, 0x65, 0x3b, 0x41, 0x67, 0x62, 0x3b, 0x4f, 0x74, 0x75, 0x3b, 0x4d, 0x61, 0x61, 0x3b, 0x4d, 0x61, 0x6e, 0x3b, 0x47,
+0x62, 0x6f, 0x3b, 0x41, 0x6e, 0x74, 0x3b, 0x41, 0x6c, 0x65, 0x3b, 0x41, 0x66, 0x75, 0x3b, 0x41, 0x68, 0x61, 0x72, 0x61,
+0x62, 0x61, 0x74, 0x61, 0x3b, 0x4f, 0x66, 0x6c, 0x6f, 0x3b, 0x4f, 0x63, 0x68, 0x6f, 0x6b, 0x72, 0x69, 0x6b, 0x72, 0x69,
+0x3b, 0x41, 0x62, 0x65, 0x69, 0x62, 0x65, 0x65, 0x3b, 0x41, 0x67, 0x62, 0x65, 0x69, 0x6e, 0x61, 0x61, 0x3b, 0x4f, 0x74,
+0x75, 0x6b, 0x77, 0x61, 0x64, 0x61, 0x6e, 0x3b, 0x4d, 0x61, 0x61, 0x77, 0x65, 0x3b, 0x4d, 0x61, 0x6e, 0x79, 0x61, 0x77,
+0x61, 0x6c, 0x65, 0x3b, 0x47, 0x62, 0x6f, 0x3b, 0x41, 0x6e, 0x74, 0x6f, 0x6e, 0x3b, 0x41, 0x6c, 0x65, 0x6d, 0x6c, 0x65,
+0x3b, 0x41, 0x66, 0x75, 0x61, 0x62, 0x65, 0x65, 0x3b, 0x4a, 0x65, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0x61, 0x61,
+0x3b, 0x45, 0x70, 0x72, 0x3b, 0x4d, 0x65, 0x65, 0x3b, 0x4a, 0x75, 0x75, 0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x1ecc, 0x67, 0x1ecd,
+0x3b, 0x53, 0x65, 0x70, 0x3b, 0x1ecc, 0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x69, 0x73, 0x3b, 0x4a, 0x65, 0x6e,
+0x1ee5, 0x77, 0x61, 0x72, 0x1ecb, 0x3b, 0x46, 0x65, 0x62, 0x72, 0x1ee5, 0x77, 0x61, 0x72, 0x1ecb, 0x3b, 0x4d, 0x61, 0x61, 0x63,
+0x68, 0x1ecb, 0x3b, 0x45, 0x70, 0x72, 0x65, 0x6c, 0x3b, 0x4d, 0x65, 0x65, 0x3b, 0x4a, 0x75, 0x75, 0x6e, 0x3b, 0x4a, 0x75,
+0x6c, 0x61, 0x1ecb, 0x3b, 0x1ecc, 0x67, 0x1ecd, 0x1ecd, 0x73, 0x74, 0x3b, 0x53, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x61, 0x3b,
+0x1ecc, 0x6b, 0x74, 0x6f, 0x62, 0x61, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x44, 0x69, 0x73, 0x65, 0x6d,
+0x62, 0x61, 0x3b, 0x4d, 0x77, 0x65, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6d, 0x62, 0x65, 0x65, 0x3b, 0x4d, 0x77, 0x65, 0x69,
+0x20, 0x77, 0x61, 0x20, 0x6b, 0x65, 0x6c, 0x69, 0x3b, 0x4d, 0x77, 0x65, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x74,
+0x61, 0x74, 0x75, 0x3b, 0x4d, 0x77, 0x65, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x6e, 0x6e, 0x65, 0x3b, 0x4d, 0x77,
+0x65, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x74, 0x61, 0x6e, 0x6f, 0x3b, 0x4d, 0x77, 0x65, 0x69, 0x20, 0x77, 0x61,
+0x20, 0x74, 0x68, 0x61, 0x6e, 0x74, 0x68, 0x61, 0x74, 0x75, 0x3b, 0x4d, 0x77, 0x65, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6d,
+0x75, 0x6f, 0x6e, 0x7a, 0x61, 0x3b, 0x4d, 0x77, 0x65, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6e, 0x79, 0x61, 0x6e, 0x79, 0x61,
+0x3b, 0x4d, 0x77, 0x65, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x65, 0x6e, 0x64, 0x61, 0x3b, 0x4d, 0x77, 0x65, 0x69, 0x20,
+0x77, 0x61, 0x20, 0x69, 0x6b, 0x75, 0x6d, 0x69, 0x3b, 0x4d, 0x77, 0x65, 0x69, 0x20, 0x77, 0x61, 0x20, 0x69, 0x6b, 0x75,
+0x6d, 0x69, 0x20, 0x6e, 0x61, 0x20, 0x69, 0x6d, 0x77, 0x65, 0x3b, 0x4d, 0x77, 0x65, 0x69, 0x20, 0x77, 0x61, 0x20, 0x69,
+0x6b, 0x75, 0x6d, 0x69, 0x20, 0x6e, 0x61, 0x20, 0x69, 0x6c, 0x69, 0x3b, 0x70f, 0x71f, 0x722, 0xa0, 0x70f, 0x712, 0x3b, 0x72b,
+0x712, 0x71b, 0x3b, 0x710, 0x715, 0x72a, 0x3b, 0x722, 0x71d, 0x723, 0x722, 0x3b, 0x710, 0x71d, 0x72a, 0x3b, 0x71a, 0x719, 0x71d, 0x72a,
+0x722, 0x3b, 0x72c, 0x721, 0x718, 0x719, 0x3b, 0x710, 0x712, 0x3b, 0x710, 0x71d, 0x720, 0x718, 0x720, 0x3b, 0x70f, 0x72c, 0x72b, 0xa0,
+0x70f, 0x710, 0x3b, 0x70f, 0x72c, 0x72b, 0xa0, 0x70f, 0x712, 0x3b, 0x70f, 0x71f, 0x722, 0xa0, 0x70f, 0x710, 0x3b, 0x70f, 0x71f, 0x722,
+0x20, 0x70f, 0x712, 0x3b, 0x72b, 0x712, 0x71b, 0x3b, 0x710, 0x715, 0x72a, 0x3b, 0x722, 0x71d, 0x723, 0x722, 0x3b, 0x710, 0x71d, 0x72a,
+0x3b, 0x71a, 0x719, 0x71d, 0x72a, 0x722, 0x3b, 0x72c, 0x721, 0x718, 0x719, 0x3b, 0x710, 0x712, 0x3b, 0x710, 0x71d, 0x720, 0x718, 0x720,
+0x3b, 0x70f, 0x72c, 0x72b, 0x20, 0x70f, 0x710, 0x3b, 0x70f, 0x72c, 0x72b, 0x20, 0x70f, 0x712, 0x3b, 0x70f, 0x71f, 0x722, 0x20, 0x70f,
+0x710, 0x3b, 0x120d, 0x12f0, 0x1275, 0x3b, 0x12ab, 0x1265, 0x12bd, 0x3b, 0x12ad, 0x1265, 0x120b, 0x3b, 0x134b, 0x1305, 0x12ba, 0x3b, 0x12ad, 0x1262,
+0x1245, 0x3b, 0x121d, 0x2f, 0x1275, 0x3b, 0x12b0, 0x122d, 0x3b, 0x121b, 0x122d, 0x12eb, 0x3b, 0x12eb, 0x12b8, 0x1292, 0x3b, 0x1218, 0x1270, 0x1209,
+0x3b, 0x121d, 0x2f, 0x121d, 0x3b, 0x1270, 0x1215, 0x1233, 0x3b, 0x120d, 0x12f0, 0x1275, 0x122a, 0x3b, 0x12ab, 0x1265, 0x12bd, 0x1265, 0x1272, 0x3b,
+0x12ad, 0x1265, 0x120b, 0x3b, 0x134b, 0x1305, 0x12ba, 0x122a, 0x3b, 0x12ad, 0x1262, 0x1245, 0x122a, 0x3b, 0x121d, 0x12aa, 0x12a4, 0x120d, 0x20, 0x1275,
+0x131f, 0x1292, 0x122a, 0x3b, 0x12b0, 0x122d, 0x12a9, 0x3b, 0x121b, 0x122d, 0x12eb, 0x121d, 0x20, 0x1275, 0x122a, 0x3b, 0x12eb, 0x12b8, 0x1292, 0x20,
+0x1218, 0x1233, 0x1245, 0x1208, 0x122a, 0x3b, 0x1218, 0x1270, 0x1209, 0x3b, 0x121d, 0x12aa, 0x12a4, 0x120d, 0x20, 0x1218, 0x123d, 0x12c8, 0x122a, 0x3b,
+0x1270, 0x1215, 0x1233, 0x1235, 0x122a, 0x3b, 0x1320, 0x1210, 0x1228, 0x3b, 0x12a8, 0x1270, 0x1270, 0x3b, 0x1218, 0x1308, 0x1260, 0x3b, 0x12a0, 0x1280,
+0x12d8, 0x3b, 0x130d, 0x1295, 0x1263, 0x3b, 0x1220, 0x1295, 0x12e8, 0x3b, 0x1210, 0x1218, 0x1208, 0x3b, 0x1290, 0x1210, 0x1230, 0x3b, 0x12a8, 0x1228,
+0x1218, 0x3b, 0x1320, 0x1240, 0x1218, 0x3b, 0x1280, 0x12f0, 0x1228, 0x3b, 0x1280, 0x1220, 0x1220, 0x3b, 0x1320, 0x1210, 0x1228, 0x3b, 0x12a8, 0x1270,
+0x1270, 0x3b, 0x1218, 0x1308, 0x1260, 0x3b, 0x12a0, 0x1280, 0x12d8, 0x3b, 0x130d, 0x1295, 0x1263, 0x1275, 0x3b, 0x1220, 0x1295, 0x12e8, 0x3b, 0x1210,
+0x1218, 0x1208, 0x3b, 0x1290, 0x1210, 0x1230, 0x3b, 0x12a8, 0x1228, 0x1218, 0x3b, 0x1320, 0x1240, 0x1218, 0x3b, 0x1280, 0x12f0, 0x1228, 0x3b, 0x1280,
+0x1220, 0x1220, 0x3b, 0x57, 0x65, 0x79, 0x3b, 0x46, 0x61, 0x6e, 0x3b, 0x54, 0x61, 0x74, 0x3b, 0x4e, 0x61, 0x6e, 0x3b, 0x54,
+0x75, 0x79, 0x3b, 0x54, 0x73, 0x6f, 0x3b, 0x54, 0x61, 0x66, 0x3b, 0x57, 0x61, 0x72, 0x3b, 0x4b, 0x75, 0x6e, 0x3b, 0x42,
+0x61, 0x6e, 0x3b, 0x4b, 0x6f, 0x6d, 0x3b, 0x53, 0x61, 0x75, 0x3b, 0x46, 0x61, 0x69, 0x20, 0x57, 0x65, 0x79, 0x65, 0x6e,
+0x65, 0x3b, 0x46, 0x61, 0x69, 0x20, 0x46, 0x61, 0x6e, 0x69, 0x3b, 0x46, 0x61, 0x69, 0x20, 0x54, 0x61, 0x74, 0x61, 0x6b,
+0x61, 0x3b, 0x46, 0x61, 0x69, 0x20, 0x4e, 0x61, 0x6e, 0x67, 0x72, 0x61, 0x3b, 0x46, 0x61, 0x69, 0x20, 0x54, 0x75, 0x79,
+0x6f, 0x3b, 0x46, 0x61, 0x69, 0x20, 0x54, 0x73, 0x6f, 0x79, 0x69, 0x3b, 0x46, 0x61, 0x69, 0x20, 0x54, 0x61, 0x66, 0x61,
+0x6b, 0x61, 0x3b, 0x46, 0x61, 0x69, 0x20, 0x57, 0x61, 0x72, 0x61, 0x63, 0x68, 0x69, 0x3b, 0x46, 0x61, 0x69, 0x20, 0x4b,
+0x75, 0x6e, 0x6f, 0x62, 0x6f, 0x6b, 0x3b, 0x46, 0x61, 0x69, 0x20, 0x42, 0x61, 0x6e, 0x73, 0x6f, 0x6b, 0x3b, 0x46, 0x61,
+0x69, 0x20, 0x4b, 0x6f, 0x6d, 0x3b, 0x46, 0x61, 0x69, 0x20, 0x53, 0x61, 0x75, 0x6b, 0x3b, 0x44, 0x79, 0x6f, 0x6e, 0x3b,
+0x42, 0x61, 0x61, 0x3b, 0x41, 0x74, 0x61, 0x74, 0x3b, 0x41, 0x6e, 0x61, 0x73, 0x3b, 0x41, 0x74, 0x79, 0x6f, 0x3b, 0x41,
+0x63, 0x68, 0x69, 0x3b, 0x41, 0x74, 0x61, 0x72, 0x3b, 0x41, 0x77, 0x75, 0x72, 0x3b, 0x53, 0x68, 0x61, 0x64, 0x3b, 0x53,
+0x68, 0x61, 0x6b, 0x3b, 0x4e, 0x61, 0x62, 0x61, 0x3b, 0x4e, 0x61, 0x74, 0x61, 0x3b, 0x50, 0x65, 0x6e, 0x20, 0x44, 0x79,
+0x6f, 0x6e, 0x3b, 0x50, 0x65, 0x6e, 0x20, 0x42, 0x61, 0x27, 0x61, 0x3b, 0x50, 0x65, 0x6e, 0x20, 0x41, 0x74, 0x61, 0x74,
+0x3b, 0x50, 0x65, 0x6e, 0x20, 0x41, 0x6e, 0x61, 0x73, 0x3b, 0x50, 0x65, 0x6e, 0x20, 0x41, 0x74, 0x79, 0x6f, 0x6e, 0x3b,
+0x50, 0x65, 0x6e, 0x20, 0x41, 0x63, 0x68, 0x69, 0x72, 0x69, 0x6d, 0x3b, 0x50, 0x65, 0x6e, 0x20, 0x41, 0x74, 0x61, 0x72,
+0x69, 0x62, 0x61, 0x3b, 0x50, 0x65, 0x6e, 0x20, 0x41, 0x77, 0x75, 0x72, 0x72, 0x3b, 0x50, 0x65, 0x6e, 0x20, 0x53, 0x68,
+0x61, 0x64, 0x6f, 0x6e, 0x3b, 0x50, 0x65, 0x6e, 0x20, 0x53, 0x68, 0x61, 0x6b, 0x75, 0x72, 0x3b, 0x50, 0x65, 0x6e, 0x20,
+0x4b, 0x75, 0x72, 0x20, 0x4e, 0x61, 0x62, 0x61, 0x3b, 0x50, 0x65, 0x6e, 0x20, 0x4b, 0x75, 0x72, 0x20, 0x4e, 0x61, 0x74,
+0x61, 0x74, 0x3b, 0x41, 0x331, 0x79, 0x72, 0x3b, 0x41, 0x331, 0x68, 0x77, 0x3b, 0x41, 0x331, 0x74, 0x61, 0x3b, 0x41, 0x331,
+0x6e, 0x61, 0x3b, 0x41, 0x331, 0x70, 0x66, 0x3b, 0x41, 0x331, 0x6b, 0x69, 0x3b, 0x41, 0x331, 0x74, 0x79, 0x3b, 0x41, 0x331,
+0x6e, 0x69, 0x3b, 0x41, 0x331, 0x6b, 0x75, 0x3b, 0x53, 0x77, 0x61, 0x3b, 0x53, 0x62, 0x79, 0x3b, 0x53, 0x62, 0x68, 0x3b,
+0x48, 0x79, 0x77, 0x61, 0x6e, 0x20, 0x41, 0x331, 0x79, 0x72, 0x6e, 0x69, 0x67, 0x3b, 0x48, 0x79, 0x77, 0x61, 0x6e, 0x20,
+0x41, 0x331, 0x68, 0x77, 0x61, 0x3b, 0x48, 0x79, 0x77, 0x61, 0x6e, 0x20, 0x41, 0x331, 0x74, 0x61, 0x74, 0x3b, 0x48, 0x79,
+0x77, 0x61, 0x6e, 0x20, 0x41, 0x331, 0x6e, 0x61, 0x61, 0x69, 0x3b, 0x48, 0x79, 0x77, 0x61, 0x6e, 0x20, 0x41, 0x331, 0x70,
+0x66, 0x77, 0x6f, 0x6e, 0x3b, 0x48, 0x79, 0x77, 0x61, 0x6e, 0x20, 0x41, 0x331, 0x6b, 0x69, 0x74, 0x61, 0x74, 0x3b, 0x48,
+0x79, 0x77, 0x61, 0x6e, 0x20, 0x41, 0x331, 0x74, 0x79, 0x69, 0x72, 0x69, 0x6e, 0x3b, 0x48, 0x79, 0x77, 0x61, 0x6e, 0x20,
+0x41, 0x331, 0x6e, 0x69, 0x6e, 0x61, 0x69, 0x3b, 0x48, 0x79, 0x77, 0x61, 0x6e, 0x20, 0x41, 0x331, 0x6b, 0x75, 0x6d, 0x76,
+0x69, 0x72, 0x69, 0x79, 0x69, 0x6e, 0x3b, 0x48, 0x79, 0x77, 0x61, 0x6e, 0x20, 0x53, 0x77, 0x61, 0x6b, 0x3b, 0x48, 0x79,
+0x77, 0x61, 0x6e, 0x20, 0x53, 0x77, 0x61, 0x6b, 0x20, 0x42, 0x27, 0x61, 0x331, 0x79, 0x72, 0x6e, 0x69, 0x67, 0x3b, 0x48,
+0x79, 0x77, 0x61, 0x6e, 0x20, 0x53, 0x77, 0x61, 0x6b, 0x20, 0x42, 0x27, 0x61, 0x331, 0x68, 0x77, 0x61, 0x3b, 0x5a, 0x65,
+0x6e, 0x3b, 0x46, 0x65, 0x76, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x41, 0x76, 0x72, 0x3b, 0x4d, 0x61, 0x69, 0x3b, 0x4a, 0x75,
+0x67, 0x3b, 0x4c, 0x75, 0x69, 0x3b, 0x41, 0x76, 0x6f, 0x3b, 0x53, 0x65, 0x74, 0x3b, 0x4f, 0x74, 0x75, 0x3b, 0x4e, 0x6f,
+0x76, 0x3b, 0x44, 0x69, 0x63, 0x3b, 0x5a, 0x65, 0x6e, 0xe2, 0x72, 0x3b, 0x46, 0x65, 0x76, 0x72, 0xe2, 0x72, 0x3b, 0x4d,
+0x61, 0x72, 0xe7, 0x3b, 0x41, 0x76, 0x72, 0xee, 0x6c, 0x3b, 0x4d, 0x61, 0x69, 0x3b, 0x4a, 0x75, 0x67, 0x6e, 0x3b, 0x4c,
+0x75, 0x69, 0x3b, 0x41, 0x76, 0x6f, 0x73, 0x74, 0x3b, 0x53, 0x65, 0x74, 0x65, 0x6d, 0x62, 0x61, 0x72, 0x3b, 0x4f, 0x74,
+0x75, 0x62, 0x61, 0x72, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x61, 0x72, 0x3b, 0x44, 0x69, 0x63, 0x65, 0x6d, 0x62,
+0x61, 0x72, 0x3b, 0x50, 0x68, 0x61, 0x3b, 0x4c, 0x75, 0x68, 0x3b, 0x1e70, 0x68, 0x61, 0x3b, 0x4c, 0x61, 0x6d, 0x3b, 0x53,
+0x68, 0x75, 0x3b, 0x4c, 0x77, 0x69, 0x3b, 0x4c, 0x77, 0x61, 0x3b, 0x1e70, 0x68, 0x61, 0x3b, 0x4b, 0x68, 0x75, 0x3b, 0x54,
+0x73, 0x68, 0x3b, 0x1e3c, 0x61, 0x72, 0x3b, 0x4e, 0x79, 0x65, 0x3b, 0x50, 0x68, 0x61, 0x6e, 0x64, 0x6f, 0x3b, 0x4c, 0x75,
+0x68, 0x75, 0x68, 0x69, 0x3b, 0x1e70, 0x68, 0x61, 0x66, 0x61, 0x6d, 0x75, 0x68, 0x77, 0x65, 0x3b, 0x4c, 0x61, 0x6d, 0x62,
+0x61, 0x6d, 0x61, 0x69, 0x3b, 0x53, 0x68, 0x75, 0x6e, 0x64, 0x75, 0x6e, 0x74, 0x68, 0x75, 0x6c, 0x65, 0x3b, 0x46, 0x75,
+0x6c, 0x77, 0x69, 0x3b, 0x46, 0x75, 0x6c, 0x77, 0x61, 0x6e, 0x61, 0x3b, 0x1e70, 0x68, 0x61, 0x6e, 0x67, 0x75, 0x6c, 0x65,
+0x3b, 0x4b, 0x68, 0x75, 0x62, 0x76, 0x75, 0x6d, 0x65, 0x64, 0x7a, 0x69, 0x3b, 0x54, 0x73, 0x68, 0x69, 0x6d, 0x65, 0x64,
+0x7a, 0x69, 0x3b, 0x1e3c, 0x61, 0x72, 0x61, 0x3b, 0x4e, 0x79, 0x65, 0x6e, 0x64, 0x61, 0x76, 0x68, 0x75, 0x73, 0x69, 0x6b,
+0x75, 0x3b, 0x44, 0x7a, 0x76, 0x3b, 0x44, 0x7a, 0x64, 0x3b, 0x54, 0x65, 0x64, 0x3b, 0x41, 0x66, 0x254, 0x3b, 0x44, 0x61,
+0x6d, 0x3b, 0x4d, 0x61, 0x73, 0x3b, 0x53, 0x69, 0x61, 0x3b, 0x44, 0x65, 0x61, 0x3b, 0x41, 0x6e, 0x79, 0x3b, 0x4b, 0x65,
+0x6c, 0x3b, 0x41, 0x64, 0x65, 0x3b, 0x44, 0x7a, 0x6d, 0x3b, 0x44, 0x7a, 0x6f, 0x76, 0x65, 0x3b, 0x44, 0x7a, 0x6f, 0x64,
+0x7a, 0x65, 0x3b, 0x54, 0x65, 0x64, 0x6f, 0x78, 0x65, 0x3b, 0x41, 0x66, 0x254, 0x66, 0x69, 0x25b, 0x3b, 0x44, 0x61, 0x6d,
+0x61, 0x3b, 0x4d, 0x61, 0x73, 0x61, 0x3b, 0x53, 0x69, 0x61, 0x6d, 0x6c, 0x254, 0x6d, 0x3b, 0x44, 0x65, 0x61, 0x73, 0x69,
+0x61, 0x6d, 0x69, 0x6d, 0x65, 0x3b, 0x41, 0x6e, 0x79, 0x254, 0x6e, 0x79, 0x254, 0x3b, 0x4b, 0x65, 0x6c, 0x65, 0x3b, 0x41,
+0x64, 0x65, 0x25b, 0x6d, 0x65, 0x6b, 0x70, 0x254, 0x78, 0x65, 0x3b, 0x44, 0x7a, 0x6f, 0x6d, 0x65, 0x3b, 0x49, 0x61, 0x6e,
+0x2e, 0x3b, 0x50, 0x65, 0x70, 0x2e, 0x3b, 0x4d, 0x61, 0x6c, 0x2e, 0x3b, 0x2bb, 0x41, 0x70, 0x2e, 0x3b, 0x4d, 0x65, 0x69,
+0x3b, 0x49, 0x75, 0x6e, 0x2e, 0x3b, 0x49, 0x75, 0x6c, 0x2e, 0x3b, 0x2bb, 0x41, 0x75, 0x2e, 0x3b, 0x4b, 0x65, 0x70, 0x2e,
+0x3b, 0x2bb, 0x4f, 0x6b, 0x2e, 0x3b, 0x4e, 0x6f, 0x77, 0x2e, 0x3b, 0x4b, 0x65, 0x6b, 0x2e, 0x3b, 0x49, 0x61, 0x6e, 0x75,
+0x61, 0x6c, 0x69, 0x3b, 0x50, 0x65, 0x70, 0x65, 0x6c, 0x75, 0x61, 0x6c, 0x69, 0x3b, 0x4d, 0x61, 0x6c, 0x61, 0x6b, 0x69,
+0x3b, 0x2bb, 0x41, 0x70, 0x65, 0x6c, 0x69, 0x6c, 0x61, 0x3b, 0x4d, 0x65, 0x69, 0x3b, 0x49, 0x75, 0x6e, 0x65, 0x3b, 0x49,
+0x75, 0x6c, 0x61, 0x69, 0x3b, 0x2bb, 0x41, 0x75, 0x6b, 0x61, 0x6b, 0x65, 0x3b, 0x4b, 0x65, 0x70, 0x61, 0x6b, 0x65, 0x6d,
+0x61, 0x70, 0x61, 0x3b, 0x2bb, 0x4f, 0x6b, 0x61, 0x6b, 0x6f, 0x70, 0x61, 0x3b, 0x4e, 0x6f, 0x77, 0x65, 0x6d, 0x61, 0x70,
+0x61, 0x3b, 0x4b, 0x65, 0x6b, 0x65, 0x6d, 0x61, 0x70, 0x61, 0x3b, 0x4a, 0x75, 0x77, 0x3b, 0x53, 0x77, 0x69, 0x3b, 0x54,
+0x73, 0x61, 0x3b, 0x4e, 0x79, 0x61, 0x3b, 0x54, 0x73, 0x77, 0x3b, 0x41, 0x74, 0x61, 0x3b, 0x41, 0x6e, 0x61, 0x3b, 0x41,
+0x72, 0x69, 0x3b, 0x41, 0x6b, 0x75, 0x3b, 0x53, 0x77, 0x61, 0x3b, 0x4d, 0x61, 0x6e, 0x3b, 0x4d, 0x61, 0x73, 0x3b, 0x5a,
+0x77, 0x61, 0x74, 0x20, 0x4a, 0x75, 0x77, 0x75, 0x6e, 0x67, 0x3b, 0x5a, 0x77, 0x61, 0x74, 0x20, 0x53, 0x77, 0x69, 0x79,
+0x61, 0x6e, 0x67, 0x3b, 0x5a, 0x77, 0x61, 0x74, 0x20, 0x54, 0x73, 0x61, 0x74, 0x3b, 0x5a, 0x77, 0x61, 0x74, 0x20, 0x4e,
+0x79, 0x61, 0x69, 0x3b, 0x5a, 0x77, 0x61, 0x74, 0x20, 0x54, 0x73, 0x77, 0x6f, 0x6e, 0x3b, 0x5a, 0x77, 0x61, 0x74, 0x20,
+0x41, 0x74, 0x61, 0x61, 0x68, 0x3b, 0x5a, 0x77, 0x61, 0x74, 0x20, 0x41, 0x6e, 0x61, 0x74, 0x61, 0x74, 0x3b, 0x5a, 0x77,
+0x61, 0x74, 0x20, 0x41, 0x72, 0x69, 0x6e, 0x61, 0x69, 0x3b, 0x5a, 0x77, 0x61, 0x74, 0x20, 0x41, 0x6b, 0x75, 0x62, 0x75,
+0x6e, 0x79, 0x75, 0x6e, 0x67, 0x3b, 0x5a, 0x77, 0x61, 0x74, 0x20, 0x53, 0x77, 0x61, 0x67, 0x3b, 0x5a, 0x77, 0x61, 0x74,
+0x20, 0x4d, 0x61, 0x6e, 0x67, 0x6a, 0x75, 0x77, 0x61, 0x6e, 0x67, 0x3b, 0x5a, 0x77, 0x61, 0x74, 0x20, 0x53, 0x77, 0x61,
+0x67, 0x2d, 0x4d, 0x61, 0x2d, 0x53, 0x75, 0x79, 0x61, 0x6e, 0x67, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b,
+0x4d, 0x61, 0x6c, 0x3b, 0x45, 0x70, 0x75, 0x3b, 0x4d, 0x65, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x3b,
+0x4f, 0x67, 0x61, 0x3b, 0x53, 0x65, 0x70, 0x3b, 0x4f, 0x6b, 0x75, 0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x69, 0x73, 0x3b,
+0x4a, 0x61, 0x6e, 0x75, 0x77, 0x61, 0x6c, 0x65, 0x3b, 0x46, 0x65, 0x62, 0x75, 0x6c, 0x75, 0x77, 0x61, 0x6c, 0x65, 0x3b,
+0x4d, 0x61, 0x6c, 0x69, 0x63, 0x68, 0x69, 0x3b, 0x45, 0x70, 0x75, 0x6c, 0x6f, 0x3b, 0x4d, 0x65, 0x69, 0x3b, 0x4a, 0x75,
+0x6e, 0x69, 0x3b, 0x4a, 0x75, 0x6c, 0x61, 0x69, 0x3b, 0x4f, 0x67, 0x61, 0x73, 0x69, 0x74, 0x69, 0x3b, 0x53, 0x65, 0x70,
+0x75, 0x74, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x4f, 0x6b, 0x75, 0x74, 0x6f, 0x62, 0x61, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d,
+0x62, 0x61, 0x3b, 0x44, 0x69, 0x73, 0x65, 0x6d, 0x62, 0x61, 0x3b
+};
+
+static const ushort standalone_months_data[] = {
+0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x41, 0x70, 0x72, 0x3b, 0x4d, 0x61, 0x79, 0x3b,
+0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x41, 0x75, 0x67, 0x3b, 0x53, 0x65, 0x70, 0x3b, 0x4f, 0x63, 0x74, 0x3b,
+0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x65, 0x63, 0x3b, 0x4a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x79, 0x3b, 0x46, 0x65, 0x62, 0x72,
+0x75, 0x61, 0x72, 0x79, 0x3b, 0x4d, 0x61, 0x72, 0x63, 0x68, 0x3b, 0x41, 0x70, 0x72, 0x69, 0x6c, 0x3b, 0x4d, 0x61, 0x79,
+0x3b, 0x4a, 0x75, 0x6e, 0x65, 0x3b, 0x4a, 0x75, 0x6c, 0x79, 0x3b, 0x41, 0x75, 0x67, 0x75, 0x73, 0x74, 0x3b, 0x53, 0x65,
+0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4f, 0x63, 0x74, 0x6f, 0x62, 0x65, 0x72, 0x3b, 0x4e, 0x6f, 0x76, 0x65,
+0x6d, 0x62, 0x65, 0x72, 0x3b, 0x44, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4a, 0x3b, 0x46, 0x3b, 0x4d, 0x3b,
+0x41, 0x3b, 0x4d, 0x3b, 0x4a, 0x3b, 0x4a, 0x3b, 0x41, 0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x3b, 0x3b,
+0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x51, 0x3b, 0x4e, 0x3b, 0x43, 0x3b, 0x41, 0x3b, 0x43, 0x3b,
+0x51, 0x3b, 0x51, 0x3b, 0x4c, 0x3b, 0x57, 0x3b, 0x44, 0x3b, 0x58, 0x3b, 0x4b, 0x3b, 0x31, 0x3b, 0x32, 0x3b, 0x33, 0x3b,
+0x34, 0x3b, 0x35, 0x3b, 0x36, 0x3b, 0x37, 0x3b, 0x38, 0x3b, 0x39, 0x3b, 0x31, 0x30, 0x3b, 0x31, 0x31, 0x3b, 0x31, 0x32,
+0x3b, 0x4a, 0x3b, 0x53, 0x3b, 0x4d, 0x3b, 0x50, 0x3b, 0x4d, 0x3b, 0x51, 0x3b, 0x4b, 0x3b, 0x47, 0x3b, 0x53, 0x3b, 0x54,
+0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x1303, 0x3b, 0x134c, 0x3b, 0x121b, 0x3b, 0x12a4, 0x3b, 0x121c, 0x3b, 0x1301, 0x3b, 0x1301, 0x3b, 0x12a6,
+0x3b, 0x1234, 0x3b, 0x12a6, 0x3b, 0x1296, 0x3b, 0x12f2, 0x3b, 0x64a, 0x3b, 0x641, 0x3b, 0x645, 0x3b, 0x623, 0x3b, 0x648, 0x3b, 0x646,
+0x3b, 0x644, 0x3b, 0x63a, 0x3b, 0x633, 0x3b, 0x643, 0x3b, 0x628, 0x3b, 0x62f, 0x3b, 0x99c, 0x9be, 0x3b, 0x9ab, 0x9c7, 0x3b, 0x9ae,
+0x9be, 0x3b, 0x98f, 0x3b, 0x9ae, 0x9c7, 0x3b, 0x99c, 0x9c1, 0x9a8, 0x3b, 0x99c, 0x9c1, 0x3b, 0x986, 0x3b, 0x9b8, 0x9c7, 0x3b, 0x985,
+0x3b, 0x9a8, 0x3b, 0x9a1, 0x9bf, 0x3b, 0x44f, 0x3b, 0x444, 0x3b, 0x43c, 0x3b, 0x430, 0x3b, 0x43c, 0x3b, 0x44e, 0x3b, 0x44e, 0x3b,
+0x430, 0x3b, 0x441, 0x3b, 0x43e, 0x3b, 0x43d, 0x3b, 0x434, 0x3b, 0x1007, 0x3b, 0x1016, 0x3b, 0x1019, 0x3b, 0x1027, 0x3b, 0x1019, 0x3b,
+0x1007, 0x3b, 0x1007, 0x3b, 0x1029, 0x3b, 0x1005, 0x3b, 0x1021, 0x3b, 0x1014, 0x3b, 0x1012, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x442, 0x440,
+0x430, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x442, 0x440, 0x430, 0x432, 0x435, 0x43d, 0x44c,
+0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x441, 0x3b, 0x43b, 0x3b, 0x441, 0x3b, 0x43a, 0x3b, 0x43c, 0x3b, 0x447, 0x3b,
+0x43b, 0x3b, 0x436, 0x3b, 0x432, 0x3b, 0x43a, 0x3b, 0x43b, 0x3b, 0x441, 0x3b, 0x67, 0x3b, 0x66, 0x3b, 0x6d, 0x3b, 0x61, 0x3b,
+0x6d, 0x3b, 0x6a, 0x3b, 0x6a, 0x3b, 0x61, 0x3b, 0x73, 0x3b, 0x6f, 0x3b, 0x6e, 0x3b, 0x64, 0x3b, 0x4e00, 0x6708, 0x3b, 0x4e8c,
+0x6708, 0x3b, 0x4e09, 0x6708, 0x3b, 0x56db, 0x6708, 0x3b, 0x4e94, 0x6708, 0x3b, 0x516d, 0x6708, 0x3b, 0x4e03, 0x6708, 0x3b, 0x516b, 0x6708, 0x3b,
+0x4e5d, 0x6708, 0x3b, 0x5341, 0x6708, 0x3b, 0x5341, 0x4e00, 0x6708, 0x3b, 0x5341, 0x4e8c, 0x6708, 0x3b, 0x31, 0x6708, 0x3b, 0x32, 0x6708, 0x3b,
+0x33, 0x6708, 0x3b, 0x34, 0x6708, 0x3b, 0x35, 0x6708, 0x3b, 0x36, 0x6708, 0x3b, 0x37, 0x6708, 0x3b, 0x38, 0x6708, 0x3b, 0x39, 0x6708,
+0x3b, 0x31, 0x30, 0x6708, 0x3b, 0x31, 0x31, 0x6708, 0x3b, 0x31, 0x32, 0x6708, 0x3b, 0x73, 0x69, 0x6a, 0x65, 0x10d, 0x61, 0x6e,
+0x6a, 0x3b, 0x76, 0x65, 0x6c, 0x6a, 0x61, 0x10d, 0x61, 0x3b, 0x6f, 0x17e, 0x75, 0x6a, 0x61, 0x6b, 0x3b, 0x74, 0x72, 0x61,
+0x76, 0x61, 0x6e, 0x6a, 0x3b, 0x73, 0x76, 0x69, 0x62, 0x61, 0x6e, 0x6a, 0x3b, 0x6c, 0x69, 0x70, 0x61, 0x6e, 0x6a, 0x3b,
+0x73, 0x72, 0x70, 0x61, 0x6e, 0x6a, 0x3b, 0x6b, 0x6f, 0x6c, 0x6f, 0x76, 0x6f, 0x7a, 0x3b, 0x72, 0x75, 0x6a, 0x61, 0x6e,
+0x3b, 0x6c, 0x69, 0x73, 0x74, 0x6f, 0x70, 0x61, 0x64, 0x3b, 0x73, 0x74, 0x75, 0x64, 0x65, 0x6e, 0x69, 0x3b, 0x70, 0x72,
+0x6f, 0x73, 0x69, 0x6e, 0x61, 0x63, 0x3b, 0x73, 0x3b, 0x76, 0x3b, 0x6f, 0x3b, 0x74, 0x3b, 0x73, 0x3b, 0x6c, 0x3b, 0x73,
+0x3b, 0x6b, 0x3b, 0x72, 0x3b, 0x6c, 0x3b, 0x73, 0x3b, 0x70, 0x3b, 0x31, 0x2e, 0x3b, 0x32, 0x2e, 0x3b, 0x33, 0x2e, 0x3b,
+0x34, 0x2e, 0x3b, 0x35, 0x2e, 0x3b, 0x36, 0x2e, 0x3b, 0x37, 0x2e, 0x3b, 0x38, 0x2e, 0x3b, 0x39, 0x2e, 0x3b, 0x31, 0x30,
+0x2e, 0x3b, 0x31, 0x31, 0x2e, 0x3b, 0x31, 0x32, 0x2e, 0x3b, 0x6c, 0x65, 0x64, 0x65, 0x6e, 0x3b, 0xfa, 0x6e, 0x6f, 0x72,
+0x3b, 0x62, 0x159, 0x65, 0x7a, 0x65, 0x6e, 0x3b, 0x64, 0x75, 0x62, 0x65, 0x6e, 0x3b, 0x6b, 0x76, 0x11b, 0x74, 0x65, 0x6e,
+0x3b, 0x10d, 0x65, 0x72, 0x76, 0x65, 0x6e, 0x3b, 0x10d, 0x65, 0x72, 0x76, 0x65, 0x6e, 0x65, 0x63, 0x3b, 0x73, 0x72, 0x70,
+0x65, 0x6e, 0x3b, 0x7a, 0xe1, 0x159, 0xed, 0x3b, 0x159, 0xed, 0x6a, 0x65, 0x6e, 0x3b, 0x6c, 0x69, 0x73, 0x74, 0x6f, 0x70,
+0x61, 0x64, 0x3b, 0x70, 0x72, 0x6f, 0x73, 0x69, 0x6e, 0x65, 0x63, 0x3b, 0x6c, 0x3b, 0xfa, 0x3b, 0x62, 0x3b, 0x64, 0x3b,
+0x6b, 0x3b, 0x10d, 0x3b, 0x10d, 0x3b, 0x73, 0x3b, 0x7a, 0x3b, 0x159, 0x3b, 0x6c, 0x3b, 0x70, 0x3b, 0x54, 0x3b, 0x48, 0x3b,
+0x4d, 0x3b, 0x48, 0x3b, 0x54, 0x3b, 0x4b, 0x3b, 0x48, 0x3b, 0x45, 0x3b, 0x53, 0x3b, 0x4c, 0x3b, 0x4d, 0x3b, 0x4a, 0x3b,
+0x58, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x58, 0x3b, 0x58, 0x3b, 0x41, 0x3b, 0x53, 0x3b, 0x4f, 0x3b,
+0x4e, 0x3b, 0x44, 0x3b, 0x10d8, 0x3b, 0x10d7, 0x3b, 0x10db, 0x3b, 0x10d0, 0x3b, 0x10db, 0x3b, 0x10d8, 0x3b, 0x10d8, 0x3b, 0x10d0, 0x3b,
+0x10e1, 0x3b, 0x10dd, 0x3b, 0x10dc, 0x3b, 0x10d3, 0x3b, 0x3b, 0x3b, 0x4d, 0xe4, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x4a, 0x75, 0x6c,
+0x3b, 0x41, 0x75, 0x67, 0x3b, 0x53, 0x65, 0x70, 0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x65, 0x7a,
+0x3b, 0x399, 0x3b1, 0x3bd, 0x3bf, 0x3c5, 0x3ac, 0x3c1, 0x3b9, 0x3bf, 0x3c2, 0x3b, 0x3a6, 0x3b5, 0x3b2, 0x3c1, 0x3bf, 0x3c5, 0x3ac, 0x3c1,
+0x3b9, 0x3bf, 0x3c2, 0x3b, 0x39c, 0x3ac, 0x3c1, 0x3c4, 0x3b9, 0x3bf, 0x3c2, 0x3b, 0x391, 0x3c0, 0x3c1, 0x3af, 0x3bb, 0x3b9, 0x3bf, 0x3c2,
+0x3b, 0x39c, 0x3ac, 0x3b9, 0x3bf, 0x3c2, 0x3b, 0x399, 0x3bf, 0x3cd, 0x3bd, 0x3b9, 0x3bf, 0x3c2, 0x3b, 0x399, 0x3bf, 0x3cd, 0x3bb, 0x3b9,
+0x3bf, 0x3c2, 0x3b, 0x391, 0x3cd, 0x3b3, 0x3bf, 0x3c5, 0x3c3, 0x3c4, 0x3bf, 0x3c2, 0x3b, 0x3a3, 0x3b5, 0x3c0, 0x3c4, 0x3ad, 0x3bc, 0x3b2,
+0x3c1, 0x3b9, 0x3bf, 0x3c2, 0x3b, 0x39f, 0x3ba, 0x3c4, 0x3ce, 0x3b2, 0x3c1, 0x3b9, 0x3bf, 0x3c2, 0x3b, 0x39d, 0x3bf, 0x3ad, 0x3bc, 0x3b2,
+0x3c1, 0x3b9, 0x3bf, 0x3c2, 0x3b, 0x394, 0x3b5, 0x3ba, 0x3ad, 0x3bc, 0x3b2, 0x3c1, 0x3b9, 0x3bf, 0x3c2, 0x3b, 0x399, 0x3b, 0x3a6, 0x3b,
+0x39c, 0x3b, 0x391, 0x3b, 0x39c, 0x3b, 0x399, 0x3b, 0x399, 0x3b, 0x391, 0x3b, 0x3a3, 0x3b, 0x39f, 0x3b, 0x39d, 0x3b, 0x394, 0x3b,
+0x4a, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x59, 0x3b, 0x59, 0x3b, 0x41, 0x3b, 0x53, 0x3b, 0x4f, 0x3b,
+0x4e, 0x3b, 0x44, 0x3b, 0x3b, 0x3b, 0x5de, 0x5e8, 0x5e1, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x4a,
+0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0xc1, 0x3b, 0x4d, 0x3b, 0x4a, 0x3b, 0x4a, 0x3b, 0x41, 0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x4e,
+0x3b, 0x44, 0x3b, 0x6a, 0x3b, 0x66, 0x3b, 0x6d, 0x3b, 0x61, 0x3b, 0x6d, 0x3b, 0x6a, 0x3b, 0x6a, 0x3b, 0xe1, 0x3b, 0x73,
+0x3b, 0x6f, 0x3b, 0x6e, 0x3b, 0x64, 0x3b, 0x45, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x42, 0x3b, 0x4d, 0x3b, 0x49,
+0x3b, 0x4c, 0x3b, 0x4d, 0x3b, 0x44, 0x3b, 0x53, 0x3b, 0x4e, 0x3b, 0x47, 0x65, 0x6e, 0x6e, 0x61, 0x69, 0x6f, 0x3b, 0x46,
+0x65, 0x62, 0x62, 0x72, 0x61, 0x69, 0x6f, 0x3b, 0x4d, 0x61, 0x72, 0x7a, 0x6f, 0x3b, 0x41, 0x70, 0x72, 0x69, 0x6c, 0x65,
+0x3b, 0x4d, 0x61, 0x67, 0x67, 0x69, 0x6f, 0x3b, 0x47, 0x69, 0x75, 0x67, 0x6e, 0x6f, 0x3b, 0x4c, 0x75, 0x67, 0x6c, 0x69,
+0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x47, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x47, 0x3b, 0x4c,
+0x3b, 0x41, 0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x31, 0xc6d4, 0x3b, 0x32, 0xc6d4, 0x3b, 0x33, 0xc6d4, 0x3b,
+0x34, 0xc6d4, 0x3b, 0x35, 0xc6d4, 0x3b, 0x36, 0xc6d4, 0x3b, 0x37, 0xc6d4, 0x3b, 0x38, 0xc6d4, 0x3b, 0x39, 0xc6d4, 0x3b, 0x31, 0x30,
+0xc6d4, 0x3b, 0x31, 0x31, 0xc6d4, 0x3b, 0x31, 0x32, 0xc6d4, 0x3b, 0x53, 0x61, 0x75, 0x73, 0x69, 0x73, 0x3b, 0x56, 0x61, 0x73,
+0x61, 0x72, 0x69, 0x73, 0x3b, 0x4b, 0x6f, 0x76, 0x61, 0x73, 0x3b, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x64, 0x69, 0x73, 0x3b,
+0x47, 0x65, 0x67, 0x75, 0x17e, 0x117, 0x3b, 0x42, 0x69, 0x72, 0x17e, 0x65, 0x6c, 0x69, 0x73, 0x3b, 0x4c, 0x69, 0x65, 0x70,
+0x61, 0x3b, 0x52, 0x75, 0x67, 0x70, 0x6a, 0x16b, 0x74, 0x69, 0x73, 0x3b, 0x52, 0x75, 0x67, 0x73, 0x117, 0x6a, 0x69, 0x73,
+0x3b, 0x53, 0x70, 0x61, 0x6c, 0x69, 0x73, 0x3b, 0x4c, 0x61, 0x70, 0x6b, 0x72, 0x69, 0x74, 0x69, 0x73, 0x3b, 0x47, 0x72,
+0x75, 0x6f, 0x64, 0x69, 0x73, 0x3b, 0x53, 0x3b, 0x56, 0x3b, 0x4b, 0x3b, 0x42, 0x3b, 0x47, 0x3b, 0x42, 0x3b, 0x4c, 0x3b,
+0x52, 0x3b, 0x52, 0x3b, 0x53, 0x3b, 0x4c, 0x3b, 0x47, 0x3b, 0x458, 0x3b, 0x444, 0x3b, 0x43c, 0x3b, 0x430, 0x3b, 0x43c, 0x3b,
+0x458, 0x3b, 0x458, 0x3b, 0x430, 0x3b, 0x441, 0x3b, 0x43e, 0x3b, 0x43d, 0x3b, 0x434, 0x3b, 0xd1c, 0x3b, 0xd2b, 0xd46, 0x3b, 0xd2e,
+0x3b, 0xd0f, 0x3b, 0xd2e, 0xd47, 0x3b, 0xd1c, 0xd42, 0x3b, 0xd1c, 0xd42, 0x3b, 0xd06, 0x3b, 0xd38, 0xd46, 0x3b, 0xd12, 0x3b, 0xd28,
+0x3b, 0xd21, 0xd3f, 0x3b, 0x4a, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x120, 0x3b, 0x4c, 0x3b, 0x41, 0x3b,
+0x53, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x967, 0x3b, 0x968, 0x3b, 0x969, 0x3b, 0x96a, 0x3b, 0x96b, 0x3b, 0x96c, 0x3b,
+0x96d, 0x3b, 0x96e, 0x3b, 0x96f, 0x3b, 0x967, 0x966, 0x3b, 0x967, 0x967, 0x3b, 0x967, 0x968, 0x3b, 0x698, 0x627, 0x646, 0x648, 0x6cc,
+0x647, 0x3b, 0x641, 0x648, 0x631, 0x6cc, 0x647, 0x3b, 0x645, 0x627, 0x631, 0x633, 0x3b, 0x622, 0x648, 0x631, 0x6cc, 0x644, 0x3b, 0x645,
+0x647, 0x3b, 0x698, 0x648, 0x626, 0x646, 0x3b, 0x698, 0x648, 0x626, 0x6cc, 0x647, 0x3b, 0x627, 0x648, 0x62a, 0x3b, 0x633, 0x67e, 0x62a,
+0x627, 0x645, 0x628, 0x631, 0x3b, 0x627, 0x6a9, 0x62a, 0x628, 0x631, 0x3b, 0x646, 0x648, 0x627, 0x645, 0x628, 0x631, 0x3b, 0x62f, 0x633,
+0x627, 0x645, 0x628, 0x631, 0x3b, 0x698, 0x3b, 0x641, 0x3b, 0x645, 0x3b, 0x622, 0x3b, 0x645, 0x3b, 0x698, 0x3b, 0x698, 0x3b, 0x627,
+0x3b, 0x633, 0x3b, 0x627, 0x3b, 0x646, 0x3b, 0x62f, 0x3b, 0x62c, 0x3b, 0x641, 0x3b, 0x645, 0x3b, 0x627, 0x3b, 0x645, 0x3b, 0x62c,
+0x3b, 0x62c, 0x3b, 0x627, 0x3b, 0x633, 0x3b, 0x627, 0x3b, 0x646, 0x3b, 0x62f, 0x3b, 0x73, 0x74, 0x79, 0x63, 0x7a, 0x65, 0x144,
+0x3b, 0x6c, 0x75, 0x74, 0x79, 0x3b, 0x6d, 0x61, 0x72, 0x7a, 0x65, 0x63, 0x3b, 0x6b, 0x77, 0x69, 0x65, 0x63, 0x69, 0x65,
+0x144, 0x3b, 0x6d, 0x61, 0x6a, 0x3b, 0x63, 0x7a, 0x65, 0x72, 0x77, 0x69, 0x65, 0x63, 0x3b, 0x6c, 0x69, 0x70, 0x69, 0x65,
+0x63, 0x3b, 0x73, 0x69, 0x65, 0x72, 0x70, 0x69, 0x65, 0x144, 0x3b, 0x77, 0x72, 0x7a, 0x65, 0x73, 0x69, 0x65, 0x144, 0x3b,
+0x70, 0x61, 0x17a, 0x64, 0x7a, 0x69, 0x65, 0x72, 0x6e, 0x69, 0x6b, 0x3b, 0x6c, 0x69, 0x73, 0x74, 0x6f, 0x70, 0x61, 0x64,
+0x3b, 0x67, 0x72, 0x75, 0x64, 0x7a, 0x69, 0x65, 0x144, 0x3b, 0x73, 0x3b, 0x6c, 0x3b, 0x6d, 0x3b, 0x6b, 0x3b, 0x6d, 0x3b,
+0x63, 0x3b, 0x6c, 0x3b, 0x73, 0x3b, 0x77, 0x3b, 0x70, 0x3b, 0x6c, 0x3b, 0x67, 0x3b, 0xa1c, 0x3b, 0xa2b, 0x3b, 0xa2e, 0xa3e,
+0x3b, 0xa05, 0x3b, 0xa2e, 0x3b, 0xa1c, 0xa42, 0x3b, 0xa1c, 0xa41, 0x3b, 0xa05, 0x3b, 0xa38, 0x3b, 0xa05, 0x3b, 0xa28, 0x3b, 0xa26,
+0x3b, 0x49, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x49, 0x3b, 0x49, 0x3b, 0x41, 0x3b, 0x53, 0x3b, 0x4f,
+0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x44f, 0x43d, 0x432, 0x2e, 0x3b, 0x444, 0x435, 0x432, 0x440, 0x2e, 0x3b, 0x43c, 0x430, 0x440, 0x442,
+0x3b, 0x430, 0x43f, 0x440, 0x2e, 0x3b, 0x43c, 0x430, 0x439, 0x3b, 0x438, 0x44e, 0x43d, 0x44c, 0x3b, 0x438, 0x44e, 0x43b, 0x44c, 0x3b,
+0x430, 0x432, 0x433, 0x2e, 0x3b, 0x441, 0x435, 0x43d, 0x442, 0x2e, 0x3b, 0x43e, 0x43a, 0x442, 0x2e, 0x3b, 0x43d, 0x43e, 0x44f, 0x431,
+0x2e, 0x3b, 0x434, 0x435, 0x43a, 0x2e, 0x3b, 0x42f, 0x43d, 0x432, 0x430, 0x440, 0x44c, 0x3b, 0x424, 0x435, 0x432, 0x440, 0x430, 0x43b,
+0x44c, 0x3b, 0x41c, 0x430, 0x440, 0x442, 0x3b, 0x410, 0x43f, 0x440, 0x435, 0x43b, 0x44c, 0x3b, 0x41c, 0x430, 0x439, 0x3b, 0x418, 0x44e,
+0x43d, 0x44c, 0x3b, 0x418, 0x44e, 0x43b, 0x44c, 0x3b, 0x410, 0x432, 0x433, 0x443, 0x441, 0x442, 0x3b, 0x421, 0x435, 0x43d, 0x442, 0x44f,
+0x431, 0x440, 0x44c, 0x3b, 0x41e, 0x43a, 0x442, 0x44f, 0x431, 0x440, 0x44c, 0x3b, 0x41d, 0x43e, 0x44f, 0x431, 0x440, 0x44c, 0x3b, 0x414,
+0x435, 0x43a, 0x430, 0x431, 0x440, 0x44c, 0x3b, 0x42f, 0x3b, 0x424, 0x3b, 0x41c, 0x3b, 0x410, 0x3b, 0x41c, 0x3b, 0x418, 0x3b, 0x418,
+0x3b, 0x410, 0x3b, 0x421, 0x3b, 0x41e, 0x3b, 0x41d, 0x3b, 0x414, 0x3b, 0x6a, 0x3b, 0x66, 0x3b, 0x6d, 0x3b, 0x61, 0x3b, 0x6d,
+0x3b, 0x6a, 0x3b, 0x6a, 0x3b, 0x61, 0x3b, 0x73, 0x3b, 0x6f, 0x3b, 0x6e, 0x3b, 0x64, 0x3b, 0xda2, 0x3b, 0xdb4, 0xdd9, 0x3b,
+0xdb8, 0xdcf, 0x3b, 0xd85, 0x3b, 0xdb8, 0xdd0, 0x3b, 0xda2, 0xdd6, 0x3b, 0xda2, 0xdd6, 0x3b, 0xd85, 0x3b, 0xdc3, 0xdd0, 0x3b, 0xd94,
+0x3b, 0xdb1, 0xddc, 0x3b, 0xdaf, 0xdd9, 0x3b, 0x4b, 0x3b, 0x4c, 0x3b, 0x53, 0x3b, 0x41, 0x3b, 0x53, 0x3b, 0x4c, 0x3b, 0x54,
+0x3b, 0x53, 0x3b, 0x53, 0x3b, 0x54, 0x3b, 0x4b, 0x3b, 0x4c, 0x3b, 0x45, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d,
+0x3b, 0x4a, 0x3b, 0x4a, 0x3b, 0x41, 0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0xc1c, 0x3b, 0xc2b, 0xc3f, 0x3b,
+0xc2e, 0x3b, 0xc0e, 0x3b, 0xc2e, 0xc46, 0x3b, 0xc1c, 0xc41, 0x3b, 0xc1c, 0xc41, 0x3b, 0xc06, 0x3b, 0xc38, 0xc46, 0x3b, 0xc05, 0x3b,
+0xc28, 0x3b, 0xc21, 0xc3f, 0x3b, 0xe21, 0x2e, 0xe04, 0x2e, 0x3b, 0xe01, 0x2e, 0xe1e, 0x2e, 0x3b, 0xe21, 0xe35, 0x2e, 0xe04, 0x2e,
+0x3b, 0xe40, 0xe21, 0x2e, 0xe22, 0x2e, 0x3b, 0xe1e, 0x2e, 0xe04, 0x2e, 0x3b, 0xe21, 0xe34, 0x2e, 0xe22, 0x2e, 0x3b, 0xe01, 0x2e,
+0xe04, 0x2e, 0x3b, 0xe2a, 0x2e, 0xe04, 0x2e, 0x3b, 0xe01, 0x2e, 0xe22, 0x2e, 0x3b, 0xe15, 0x2e, 0xe04, 0x2e, 0x3b, 0xe1e, 0x2e,
+0xe22, 0x2e, 0x3b, 0xe18, 0x2e, 0xe04, 0x2e, 0x3b, 0x53, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x45, 0x3b, 0x4d, 0x3b, 0x53, 0x3b,
+0x53, 0x3b, 0x41, 0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x54, 0x3b, 0x4f, 0x3b, 0x15e, 0x3b, 0x4d, 0x3b, 0x4e, 0x3b,
+0x4d, 0x3b, 0x48, 0x3b, 0x54, 0x3b, 0x41, 0x3b, 0x45, 0x3b, 0x45, 0x3b, 0x4b, 0x3b, 0x41, 0x3b, 0x421, 0x456, 0x447, 0x3b,
+0x41b, 0x44e, 0x442, 0x3b, 0x411, 0x435, 0x440, 0x3b, 0x41a, 0x432, 0x456, 0x3b, 0x422, 0x440, 0x430, 0x3b, 0x427, 0x435, 0x440, 0x3b,
+0x41b, 0x438, 0x43f, 0x3b, 0x421, 0x435, 0x440, 0x3b, 0x412, 0x435, 0x440, 0x3b, 0x416, 0x43e, 0x432, 0x3b, 0x41b, 0x438, 0x441, 0x3b,
+0x413, 0x440, 0x443, 0x3b, 0x421, 0x456, 0x447, 0x435, 0x43d, 0x44c, 0x3b, 0x41b, 0x44e, 0x442, 0x438, 0x439, 0x3b, 0x411, 0x435, 0x440,
+0x435, 0x437, 0x435, 0x43d, 0x44c, 0x3b, 0x41a, 0x432, 0x456, 0x442, 0x435, 0x43d, 0x44c, 0x3b, 0x422, 0x440, 0x430, 0x432, 0x435, 0x43d,
+0x44c, 0x3b, 0x427, 0x435, 0x440, 0x432, 0x435, 0x43d, 0x44c, 0x3b, 0x41b, 0x438, 0x43f, 0x435, 0x43d, 0x44c, 0x3b, 0x421, 0x435, 0x440,
+0x43f, 0x435, 0x43d, 0x44c, 0x3b, 0x412, 0x435, 0x440, 0x435, 0x441, 0x435, 0x43d, 0x44c, 0x3b, 0x416, 0x43e, 0x432, 0x442, 0x435, 0x43d,
+0x44c, 0x3b, 0x41b, 0x438, 0x441, 0x442, 0x43e, 0x43f, 0x430, 0x434, 0x3b, 0x413, 0x440, 0x443, 0x434, 0x435, 0x43d, 0x44c, 0x3b, 0x421,
+0x3b, 0x41b, 0x3b, 0x411, 0x3b, 0x41a, 0x3b, 0x422, 0x3b, 0x427, 0x3b, 0x41b, 0x3b, 0x421, 0x3b, 0x412, 0x3b, 0x416, 0x3b, 0x41b,
+0x3b, 0x413, 0x3b, 0x3b, 0x43, 0x68, 0x77, 0x65, 0x3b, 0x4d, 0x61, 0x77, 0x3b, 0x45, 0x62, 0x72, 0x3b, 0x3b, 0x3b, 0x47,
+0x6f, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x47, 0x6f, 0x72, 0x66, 0x66, 0x65,
+0x6e, 0x6e, 0x61, 0x66, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x49, 0x3b, 0x43, 0x3b, 0x4d, 0x3b, 0x45, 0x3b, 0x4d, 0x3b,
+0x4d, 0x3b, 0x47, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x48, 0x3b, 0x54, 0x3b, 0x52, 0x3b, 0x75, 0x4a, 0x61, 0x6e, 0x75, 0x77,
+0x61, 0x72, 0x69, 0x3b, 0x75, 0x46, 0x65, 0x62, 0x72, 0x75, 0x77, 0x61, 0x72, 0x69, 0x3b, 0x75, 0x4d, 0x61, 0x73, 0x68,
+0x69, 0x3b, 0x75, 0x2d, 0x41, 0x70, 0x72, 0x65, 0x6c, 0x69, 0x3b, 0x75, 0x4d, 0x65, 0x79, 0x69, 0x3b, 0x75, 0x4a, 0x75,
+0x6e, 0x69, 0x3b, 0x75, 0x4a, 0x75, 0x6c, 0x61, 0x79, 0x69, 0x3b, 0x75, 0x41, 0x67, 0x61, 0x73, 0x74, 0x69, 0x3b, 0x75,
+0x53, 0x65, 0x70, 0x74, 0x68, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x75, 0x2d, 0x4f, 0x6b, 0x74, 0x68, 0x6f, 0x62, 0x61, 0x3b,
+0x75, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x75, 0x44, 0x69, 0x73, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x120d, 0x3b,
+0x12ab, 0x3b, 0x12ad, 0x3b, 0x134b, 0x3b, 0x12ad, 0x3b, 0x121d, 0x3b, 0x12b0, 0x3b, 0x121b, 0x3b, 0x12eb, 0x3b, 0x1218, 0x3b, 0x121d, 0x3b,
+0x1270, 0x3b, 0x1320, 0x3b, 0x12a8, 0x3b, 0x1218, 0x3b, 0x12a0, 0x3b, 0x130d, 0x3b, 0x1220, 0x3b, 0x1210, 0x3b, 0x1290, 0x3b, 0x12a8, 0x3b,
+0x1320, 0x3b, 0x1280, 0x3b, 0x1280, 0x3b, 0x5a, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x4a, 0x3b, 0x4c, 0x3b,
+0x41, 0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x44, 0x3b, 0x44, 0x3b, 0x54, 0x3b, 0x41, 0x3b, 0x44, 0x3b,
+0x4d, 0x3b, 0x53, 0x3b, 0x44, 0x3b, 0x41, 0x3b, 0x4b, 0x3b, 0x41, 0x3b, 0x44, 0x3b
+};
+
+static const ushort days_data[] = {
+0x53, 0x75, 0x6e, 0x3b, 0x4d, 0x6f, 0x6e, 0x3b, 0x54, 0x75, 0x65, 0x3b, 0x57, 0x65, 0x64, 0x3b, 0x54, 0x68, 0x75, 0x3b,
+0x46, 0x72, 0x69, 0x3b, 0x53, 0x61, 0x74, 0x3b, 0x53, 0x75, 0x6e, 0x64, 0x61, 0x79, 0x3b, 0x4d, 0x6f, 0x6e, 0x64, 0x61,
+0x79, 0x3b, 0x54, 0x75, 0x65, 0x73, 0x64, 0x61, 0x79, 0x3b, 0x57, 0x65, 0x64, 0x6e, 0x65, 0x73, 0x64, 0x61, 0x79, 0x3b,
+0x54, 0x68, 0x75, 0x72, 0x73, 0x64, 0x61, 0x79, 0x3b, 0x46, 0x72, 0x69, 0x64, 0x61, 0x79, 0x3b, 0x53, 0x61, 0x74, 0x75,
+0x72, 0x64, 0x61, 0x79, 0x3b, 0x53, 0x3b, 0x4d, 0x3b, 0x54, 0x3b, 0x57, 0x3b, 0x54, 0x3b, 0x46, 0x3b, 0x53, 0x3b, 0x37,
+0x3b, 0x31, 0x3b, 0x32, 0x3b, 0x33, 0x3b, 0x34, 0x3b, 0x35, 0x3b, 0x36, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
+0x44, 0x69, 0x6c, 0x3b, 0x57, 0x69, 0x78, 0x3b, 0x51, 0x69, 0x62, 0x3b, 0x52, 0x6f, 0x62, 0x3b, 0x4b, 0x61, 0x6d, 0x3b,
+0x4a, 0x69, 0x6d, 0x3b, 0x53, 0x61, 0x6e, 0x3b, 0x44, 0x69, 0x6c, 0x62, 0x61, 0x74, 0x61, 0x3b, 0x57, 0x69, 0x69, 0x78,
+0x61, 0x74, 0x61, 0x3b, 0x51, 0x69, 0x62, 0x78, 0x61, 0x74, 0x61, 0x3b, 0x52, 0x6f, 0x6f, 0x62, 0x69, 0x69, 0x3b, 0x4b,
+0x61, 0x6d, 0x69, 0x69, 0x73, 0x61, 0x3b, 0x4a, 0x69, 0x6d, 0x61, 0x61, 0x74, 0x61, 0x3b, 0x53, 0x61, 0x6e, 0x62, 0x61,
+0x74, 0x61, 0x3b, 0x41, 0x3b, 0x45, 0x3b, 0x54, 0x3b, 0x41, 0x3b, 0x4b, 0x3b, 0x47, 0x3b, 0x53, 0x3b, 0x41, 0x63, 0x61,
+0x3b, 0x45, 0x74, 0x6c, 0x3b, 0x54, 0x61, 0x6c, 0x3b, 0x41, 0x72, 0x62, 0x3b, 0x4b, 0x61, 0x6d, 0x3b, 0x47, 0x75, 0x6d,
+0x3b, 0x53, 0x61, 0x62, 0x3b, 0x41, 0x63, 0x61, 0x61, 0x64, 0x61, 0x3b, 0x45, 0x74, 0x6c, 0x65, 0x65, 0x6e, 0x69, 0x3b,
+0x54, 0x61, 0x6c, 0x61, 0x61, 0x74, 0x61, 0x3b, 0x41, 0x72, 0x62, 0x61, 0x71, 0x61, 0x3b, 0x4b, 0x61, 0x6d, 0x69, 0x69,
+0x73, 0x69, 0x3b, 0x47, 0x75, 0x6d, 0x71, 0x61, 0x74, 0x61, 0x3b, 0x53, 0x61, 0x62, 0x74, 0x69, 0x3b, 0x31, 0x3b, 0x32,
+0x3b, 0x33, 0x3b, 0x34, 0x3b, 0x35, 0x3b, 0x36, 0x3b, 0x37, 0x3b, 0x53, 0x6f, 0x3b, 0x4d, 0x61, 0x3b, 0x44, 0x69, 0x3b,
+0x57, 0x6f, 0x3b, 0x44, 0x6f, 0x3b, 0x56, 0x72, 0x3b, 0x53, 0x61, 0x3b, 0x53, 0x6f, 0x6e, 0x64, 0x61, 0x67, 0x3b, 0x4d,
+0x61, 0x61, 0x6e, 0x64, 0x61, 0x67, 0x3b, 0x44, 0x69, 0x6e, 0x73, 0x64, 0x61, 0x67, 0x3b, 0x57, 0x6f, 0x65, 0x6e, 0x73,
+0x64, 0x61, 0x67, 0x3b, 0x44, 0x6f, 0x6e, 0x64, 0x65, 0x72, 0x64, 0x61, 0x67, 0x3b, 0x56, 0x72, 0x79, 0x64, 0x61, 0x67,
+0x3b, 0x53, 0x61, 0x74, 0x65, 0x72, 0x64, 0x61, 0x67, 0x3b, 0x44, 0x3b, 0x48, 0x3b, 0x4d, 0x3b, 0x4d, 0x3b, 0x45, 0x3b,
+0x50, 0x3b, 0x53, 0x3b, 0x44, 0x69, 0x65, 0x3b, 0x48, 0xeb, 0x6e, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x4d, 0xeb, 0x72, 0x3b,
+0x45, 0x6e, 0x6a, 0x3b, 0x50, 0x72, 0x65, 0x3b, 0x53, 0x68, 0x74, 0x3b, 0x65, 0x20, 0x64, 0x69, 0x65, 0x6c, 0x3b, 0x65,
+0x20, 0x68, 0xeb, 0x6e, 0xeb, 0x3b, 0x65, 0x20, 0x6d, 0x61, 0x72, 0x74, 0xeb, 0x3b, 0x65, 0x20, 0x6d, 0xeb, 0x72, 0x6b,
+0x75, 0x72, 0xeb, 0x3b, 0x65, 0x20, 0x65, 0x6e, 0x6a, 0x74, 0x65, 0x3b, 0x65, 0x20, 0x70, 0x72, 0x65, 0x6d, 0x74, 0x65,
+0x3b, 0x65, 0x20, 0x73, 0x68, 0x74, 0x75, 0x6e, 0xeb, 0x3b, 0x12a5, 0x3b, 0x1230, 0x3b, 0x121b, 0x3b, 0x1228, 0x3b, 0x1210, 0x3b,
+0x12d3, 0x3b, 0x1245, 0x3b, 0x12a5, 0x1211, 0x12f5, 0x3b, 0x1230, 0x129e, 0x3b, 0x121b, 0x12ad, 0x1230, 0x3b, 0x1228, 0x1261, 0x12d5, 0x3b, 0x1210,
+0x1219, 0x1235, 0x3b, 0x12d3, 0x122d, 0x1265, 0x3b, 0x1245, 0x12f3, 0x121c, 0x3b, 0x12a5, 0x1211, 0x12f5, 0x3b, 0x1230, 0x129e, 0x3b, 0x121b, 0x12ad,
+0x1230, 0x129e, 0x3b, 0x1228, 0x1261, 0x12d5, 0x3b, 0x1210, 0x1219, 0x1235, 0x3b, 0x12d3, 0x122d, 0x1265, 0x3b, 0x1245, 0x12f3, 0x121c, 0x3b, 0x623,
+0x62d, 0x62f, 0x3b, 0x627, 0x62b, 0x646, 0x64a, 0x646, 0x3b, 0x62b, 0x644, 0x627, 0x62b, 0x627, 0x621, 0x3b, 0x623, 0x631, 0x628, 0x639,
+0x627, 0x621, 0x3b, 0x62e, 0x645, 0x64a, 0x633, 0x3b, 0x62c, 0x645, 0x639, 0x629, 0x3b, 0x633, 0x628, 0x62a, 0x3b, 0x62d, 0x3b, 0x646,
+0x3b, 0x62b, 0x3b, 0x631, 0x3b, 0x62e, 0x3b, 0x62c, 0x3b, 0x633, 0x3b, 0x627, 0x644, 0x623, 0x62d, 0x62f, 0x3b, 0x627, 0x644, 0x627,
+0x62b, 0x646, 0x64a, 0x646, 0x3b, 0x627, 0x644, 0x62b, 0x644, 0x627, 0x62b, 0x627, 0x621, 0x3b, 0x627, 0x644, 0x623, 0x631, 0x628, 0x639,
+0x627, 0x621, 0x3b, 0x627, 0x644, 0x62e, 0x645, 0x64a, 0x633, 0x3b, 0x627, 0x644, 0x62c, 0x645, 0x639, 0x629, 0x3b, 0x627, 0x644, 0x633,
+0x628, 0x62a, 0x3b, 0x53f, 0x56b, 0x580, 0x3b, 0x535, 0x580, 0x56f, 0x3b, 0x535, 0x580, 0x584, 0x3b, 0x549, 0x578, 0x580, 0x3b, 0x540,
+0x576, 0x563, 0x3b, 0x548, 0x582, 0x580, 0x3b, 0x547, 0x561, 0x562, 0x3b, 0x53f, 0x56b, 0x580, 0x561, 0x56f, 0x56b, 0x3b, 0x535, 0x580,
+0x56f, 0x578, 0x582, 0x577, 0x561, 0x562, 0x569, 0x56b, 0x3b, 0x535, 0x580, 0x565, 0x584, 0x577, 0x561, 0x562, 0x569, 0x56b, 0x3b, 0x549,
+0x578, 0x580, 0x565, 0x584, 0x577, 0x561, 0x562, 0x569, 0x56b, 0x3b, 0x540, 0x56b, 0x576, 0x563, 0x577, 0x561, 0x562, 0x569, 0x56b, 0x3b,
+0x548, 0x582, 0x580, 0x562, 0x561, 0x569, 0x3b, 0x547, 0x561, 0x562, 0x561, 0x569, 0x3b, 0x9f0, 0x9ac, 0x9bf, 0x3b, 0x9b8, 0x9cb, 0x9ae,
+0x3b, 0x9ae, 0x999, 0x9cd, 0x997, 0x9b2, 0x3b, 0x9ac, 0x9c1, 0x9a7, 0x3b, 0x9ac, 0x9c3, 0x9b9, 0x9b7, 0x9cd, 0x9aa, 0x9a4, 0x9bf, 0x3b,
+0x9b6, 0x9c1, 0x995, 0x9cd, 0x9f0, 0x3b, 0x9b6, 0x9a8, 0x9bf, 0x3b, 0x9a6, 0x9c7, 0x993, 0x9ac, 0x9be, 0x9f0, 0x3b, 0x9b8, 0x9cb, 0x9ae,
+0x9ac, 0x9be, 0x9f0, 0x3b, 0x9ae, 0x999, 0x9cd, 0x997, 0x9b2, 0x9ac, 0x9be, 0x9f0, 0x3b, 0x9ac, 0x9c1, 0x9a7, 0x9ac, 0x9be, 0x9f0, 0x3b,
+0x9ac, 0x9c3, 0x9b9, 0x9b7, 0x9cd, 0x9aa, 0x9a4, 0x9bf, 0x9ac, 0x9be, 0x9f0, 0x3b, 0x9b6, 0x9c1, 0x995, 0x9cd, 0x9f0, 0x9ac, 0x9be, 0x9f0,
+0x3b, 0x9b6, 0x9a8, 0x9bf, 0x9ac, 0x9be, 0x9f0, 0x3b, 0x42, 0x2e, 0x3b, 0x42, 0x2e, 0x45, 0x2e, 0x3b, 0xc7, 0x2e, 0x41, 0x2e,
+0x3b, 0xc7, 0x2e, 0x3b, 0x43, 0x2e, 0x41, 0x2e, 0x3b, 0x43, 0x3b, 0x15e, 0x2e, 0x3b, 0x62, 0x61, 0x7a, 0x61, 0x72, 0x3b,
+0x62, 0x61, 0x7a, 0x61, 0x72, 0x20, 0x65, 0x72, 0x74, 0x259, 0x73, 0x69, 0x3b, 0xe7, 0x259, 0x72, 0x15f, 0x259, 0x6e, 0x62,
+0x259, 0x20, 0x61, 0x78, 0x15f, 0x61, 0x6d, 0x131, 0x3b, 0xe7, 0x259, 0x72, 0x15f, 0x259, 0x6e, 0x62, 0x259, 0x3b, 0x63, 0xfc,
+0x6d, 0x259, 0x20, 0x61, 0x78, 0x15f, 0x61, 0x6d, 0x131, 0x3b, 0x63, 0xfc, 0x6d, 0x259, 0x3b, 0x15f, 0x259, 0x6e, 0x62, 0x259,
+0x3b, 0x69, 0x67, 0x3b, 0x61, 0x6c, 0x3b, 0x61, 0x73, 0x3b, 0x61, 0x7a, 0x3b, 0x6f, 0x67, 0x3b, 0x6f, 0x72, 0x3b, 0x6c,
+0x72, 0x3b, 0x69, 0x67, 0x61, 0x6e, 0x64, 0x65, 0x61, 0x3b, 0x61, 0x73, 0x74, 0x65, 0x6c, 0x65, 0x68, 0x65, 0x6e, 0x61,
+0x3b, 0x61, 0x73, 0x74, 0x65, 0x61, 0x72, 0x74, 0x65, 0x61, 0x3b, 0x61, 0x73, 0x74, 0x65, 0x61, 0x7a, 0x6b, 0x65, 0x6e,
+0x61, 0x3b, 0x6f, 0x73, 0x74, 0x65, 0x67, 0x75, 0x6e, 0x61, 0x3b, 0x6f, 0x73, 0x74, 0x69, 0x72, 0x61, 0x6c, 0x61, 0x3b,
+0x6c, 0x61, 0x72, 0x75, 0x6e, 0x62, 0x61, 0x74, 0x61, 0x3b, 0x9b0, 0x3b, 0x9b8, 0x9cb, 0x3b, 0x9ae, 0x3b, 0x9ac, 0x9c1, 0x3b,
+0x9ac, 0x9c3, 0x3b, 0x9b6, 0x9c1, 0x3b, 0x9b6, 0x3b, 0x9b0, 0x9ac, 0x9bf, 0x3b, 0x9b8, 0x9cb, 0x9ae, 0x3b, 0x9ae, 0x999, 0x9cd, 0x997,
+0x9b2, 0x3b, 0x9ac, 0x9c1, 0x9a7, 0x3b, 0x9ac, 0x9c3, 0x9b9, 0x9b8, 0x9cd, 0x9aa, 0x9a4, 0x9bf, 0x3b, 0x9b6, 0x9c1, 0x995, 0x9cd, 0x9b0,
+0x3b, 0x9b6, 0x9a8, 0x9bf, 0x3b, 0x9b0, 0x9ac, 0x9bf, 0x9ac, 0x9be, 0x9b0, 0x3b, 0x9b8, 0x9cb, 0x9ae, 0x9ac, 0x9be, 0x9b0, 0x3b, 0x9ae,
+0x999, 0x9cd, 0x997, 0x9b2, 0x9ac, 0x9be, 0x9b0, 0x3b, 0x9ac, 0x9c1, 0x9a7, 0x9ac, 0x9be, 0x9b0, 0x3b, 0x9ac, 0x9c3, 0x9b9, 0x9b7, 0x9cd,
+0x9aa, 0x9a4, 0x9bf, 0x9ac, 0x9be, 0x9b0, 0x3b, 0x9b6, 0x9c1, 0x995, 0x9cd, 0x9b0, 0x9ac, 0x9be, 0x9b0, 0x3b, 0x9b6, 0x9a8, 0x9bf, 0x9ac,
+0x9be, 0x9b0, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0x3b, 0xf58, 0xf72, 0xf62, 0xf0b, 0x3b, 0xf63, 0xfb7, 0xf42, 0xf0b, 0x3b, 0xf55, 0xf74, 0xf62,
+0xf0b, 0x3b, 0xf66, 0xf44, 0xf66, 0xf0b, 0x3b, 0xf66, 0xfa4, 0xf7a, 0xf53, 0xf0b, 0x3b, 0xf49, 0xf72, 0xf0b, 0x3b, 0xf42, 0xf5f, 0xf60,
+0xf0b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0x3b, 0xf42, 0xf5f, 0xf60, 0xf0b, 0xf58, 0xf72, 0xf42, 0xf0b, 0xf51, 0xf58, 0xf62, 0xf0b, 0x3b,
+0xf42, 0xf5f, 0xf60, 0xf0b, 0xf63, 0xfb7, 0xf42, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf42, 0xf5f, 0xf60, 0xf0b, 0xf55, 0xf74, 0xf62, 0xf0b, 0xf56,
+0xf74, 0xf0b, 0x3b, 0xf42, 0xf5f, 0xf60, 0xf0b, 0xf54, 0xf0b, 0xf66, 0xf44, 0xf66, 0xf0b, 0x3b, 0xf42, 0xf5f, 0xf60, 0xf0b, 0xf66, 0xfa4,
+0xf7a, 0xf53, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf42, 0xf5f, 0xf60, 0xf0b, 0xf49, 0xf72, 0xf0b, 0xf58, 0xf0b, 0x3b, 0x43d, 0x3b, 0x43f, 0x3b,
+0x432, 0x3b, 0x441, 0x3b, 0x447, 0x3b, 0x43f, 0x3b, 0x441, 0x3b, 0x43d, 0x434, 0x3b, 0x43f, 0x43d, 0x3b, 0x432, 0x442, 0x3b, 0x441,
+0x440, 0x3b, 0x447, 0x442, 0x3b, 0x43f, 0x442, 0x3b, 0x441, 0x431, 0x3b, 0x43d, 0x435, 0x434, 0x435, 0x43b, 0x44f, 0x3b, 0x43f, 0x43e,
+0x43d, 0x435, 0x434, 0x435, 0x43b, 0x43d, 0x438, 0x43a, 0x3b, 0x432, 0x442, 0x43e, 0x440, 0x43d, 0x438, 0x43a, 0x3b, 0x441, 0x440, 0x44f,
+0x434, 0x430, 0x3b, 0x447, 0x435, 0x442, 0x432, 0x44a, 0x440, 0x442, 0x44a, 0x43a, 0x3b, 0x43f, 0x435, 0x442, 0x44a, 0x43a, 0x3b, 0x441,
+0x44a, 0x431, 0x43e, 0x442, 0x430, 0x3b, 0x1010, 0x3b, 0x1010, 0x3b, 0x1021, 0x3b, 0x1017, 0x3b, 0x1000, 0x3b, 0x101e, 0x3b, 0x1005, 0x3b,
+0x1014, 0x103d, 0x1031, 0x3b, 0x101c, 0x102c, 0x3b, 0x1002, 0x102b, 0x3b, 0x101f, 0x1030, 0x1038, 0x3b, 0x1010, 0x1031, 0x1038, 0x3b, 0x1000, 0x103c,
+0x102c, 0x3b, 0x1014, 0x1031, 0x3b, 0x1010, 0x1014, 0x1004, 0x103a, 0x1039, 0x1002, 0x1014, 0x103d, 0x1031, 0x3b, 0x1010, 0x1014, 0x1004, 0x103a, 0x1039,
+0x101c, 0x102c, 0x3b, 0x1021, 0x1004, 0x103a, 0x1039, 0x1002, 0x102b, 0x3b, 0x1017, 0x102f, 0x1012, 0x1039, 0x1013, 0x101f, 0x1030, 0x1038, 0x3b, 0x1000,
+0x103c, 0x102c, 0x101e, 0x1015, 0x1010, 0x1031, 0x1038, 0x3b, 0x101e, 0x1031, 0x102c, 0x1000, 0x103c, 0x102c, 0x3b, 0x1005, 0x1014, 0x1031, 0x3b, 0x43d,
+0x3b, 0x43f, 0x3b, 0x430, 0x3b, 0x441, 0x3b, 0x447, 0x3b, 0x43f, 0x3b, 0x441, 0x3b, 0x43d, 0x434, 0x3b, 0x43f, 0x43d, 0x3b, 0x430,
+0x45e, 0x3b, 0x441, 0x440, 0x3b, 0x447, 0x446, 0x3b, 0x43f, 0x442, 0x3b, 0x441, 0x431, 0x3b, 0x43d, 0x44f, 0x434, 0x437, 0x435, 0x43b,
+0x44f, 0x3b, 0x43f, 0x430, 0x43d, 0x44f, 0x434, 0x437, 0x435, 0x43b, 0x430, 0x43a, 0x3b, 0x430, 0x45e, 0x442, 0x43e, 0x440, 0x430, 0x43a,
+0x3b, 0x441, 0x435, 0x440, 0x430, 0x434, 0x430, 0x3b, 0x447, 0x430, 0x446, 0x432, 0x435, 0x440, 0x3b, 0x43f, 0x44f, 0x442, 0x43d, 0x456,
+0x446, 0x430, 0x3b, 0x441, 0x443, 0x431, 0x43e, 0x442, 0x430, 0x3b, 0x17a2, 0x17b6, 0x3b, 0x1785, 0x3b, 0x17a2, 0x3b, 0x1796, 0x17bb, 0x3b,
+0x1796, 0x17d2, 0x179a, 0x3b, 0x179f, 0x17bb, 0x3b, 0x179f, 0x3b, 0x1790, 0x17d2, 0x1784, 0x17c3, 0x17a2, 0x17b6, 0x1791, 0x17b7, 0x178f, 0x17d2, 0x1799,
+0x3b, 0x200b, 0x1790, 0x17d2, 0x1784, 0x17c3, 0x1785, 0x17d0, 0x1793, 0x17d2, 0x1791, 0x3b, 0x1790, 0x17d2, 0x1784, 0x17c3, 0x17a2, 0x1784, 0x17d2, 0x1782,
+0x17b6, 0x179a, 0x3b, 0x1790, 0x17d2, 0x1784, 0x17c3, 0x1796, 0x17bb, 0x1792, 0x3b, 0x1790, 0x17d2, 0x1784, 0x17c3, 0x1796, 0x17d2, 0x179a, 0x17a0, 0x179f,
+0x17d2, 0x1794, 0x178f, 0x17b7, 0x17cd, 0x3b, 0x1790, 0x17d2, 0x1784, 0x17c3, 0x179f, 0x17bb, 0x1780, 0x17d2, 0x179a, 0x3b, 0x1790, 0x17d2, 0x1784, 0x17c3,
+0x179f, 0x17c5, 0x179a, 0x17cd, 0x3b, 0x64, 0x67, 0x3b, 0x64, 0x6c, 0x3b, 0x64, 0x74, 0x3b, 0x64, 0x63, 0x3b, 0x64, 0x6a, 0x3b,
+0x64, 0x76, 0x3b, 0x64, 0x73, 0x3b, 0x67, 0x3b, 0x6c, 0x3b, 0x74, 0x3b, 0x63, 0x3b, 0x6a, 0x3b, 0x76, 0x3b, 0x73, 0x3b,
+0x64, 0x67, 0x2e, 0x3b, 0x64, 0x6c, 0x2e, 0x3b, 0x64, 0x74, 0x2e, 0x3b, 0x64, 0x63, 0x2e, 0x3b, 0x64, 0x6a, 0x2e, 0x3b,
+0x64, 0x76, 0x2e, 0x3b, 0x64, 0x73, 0x2e, 0x3b, 0x64, 0x69, 0x75, 0x6d, 0x65, 0x6e, 0x67, 0x65, 0x3b, 0x64, 0x69, 0x6c,
+0x6c, 0x75, 0x6e, 0x73, 0x3b, 0x64, 0x69, 0x6d, 0x61, 0x72, 0x74, 0x73, 0x3b, 0x64, 0x69, 0x6d, 0x65, 0x63, 0x72, 0x65,
+0x73, 0x3b, 0x64, 0x69, 0x6a, 0x6f, 0x75, 0x73, 0x3b, 0x64, 0x69, 0x76, 0x65, 0x6e, 0x64, 0x72, 0x65, 0x73, 0x3b, 0x64,
+0x69, 0x73, 0x73, 0x61, 0x62, 0x74, 0x65, 0x3b, 0x65e5, 0x3b, 0x4e00, 0x3b, 0x4e8c, 0x3b, 0x4e09, 0x3b, 0x56db, 0x3b, 0x4e94, 0x3b,
+0x516d, 0x3b, 0x5468, 0x65e5, 0x3b, 0x5468, 0x4e00, 0x3b, 0x5468, 0x4e8c, 0x3b, 0x5468, 0x4e09, 0x3b, 0x5468, 0x56db, 0x3b, 0x5468, 0x4e94, 0x3b,
+0x5468, 0x516d, 0x3b, 0x661f, 0x671f, 0x65e5, 0x3b, 0x661f, 0x671f, 0x4e00, 0x3b, 0x661f, 0x671f, 0x4e8c, 0x3b, 0x661f, 0x671f, 0x4e09, 0x3b, 0x661f,
+0x671f, 0x56db, 0x3b, 0x661f, 0x671f, 0x4e94, 0x3b, 0x661f, 0x671f, 0x516d, 0x3b, 0x6e, 0x3b, 0x70, 0x3b, 0x75, 0x3b, 0x73, 0x3b, 0x10d,
+0x3b, 0x70, 0x3b, 0x73, 0x3b, 0x6e, 0x65, 0x64, 0x3b, 0x70, 0x6f, 0x6e, 0x3b, 0x75, 0x74, 0x6f, 0x3b, 0x73, 0x72, 0x69,
+0x3b, 0x10d, 0x65, 0x74, 0x3b, 0x70, 0x65, 0x74, 0x3b, 0x73, 0x75, 0x62, 0x3b, 0x6e, 0x65, 0x64, 0x6a, 0x65, 0x6c, 0x6a,
+0x61, 0x3b, 0x70, 0x6f, 0x6e, 0x65, 0x64, 0x6a, 0x65, 0x6c, 0x6a, 0x61, 0x6b, 0x3b, 0x75, 0x74, 0x6f, 0x72, 0x61, 0x6b,
+0x3b, 0x73, 0x72, 0x69, 0x6a, 0x65, 0x64, 0x61, 0x3b, 0x10d, 0x65, 0x74, 0x76, 0x72, 0x74, 0x61, 0x6b, 0x3b, 0x70, 0x65,
+0x74, 0x61, 0x6b, 0x3b, 0x73, 0x75, 0x62, 0x6f, 0x74, 0x61, 0x3b, 0x4e, 0x3b, 0x50, 0x3b, 0xda, 0x3b, 0x53, 0x3b, 0x10c,
+0x3b, 0x50, 0x3b, 0x53, 0x3b, 0x6e, 0x65, 0x3b, 0x70, 0x6f, 0x3b, 0xfa, 0x74, 0x3b, 0x73, 0x74, 0x3b, 0x10d, 0x74, 0x3b,
+0x70, 0xe1, 0x3b, 0x73, 0x6f, 0x3b, 0x6e, 0x65, 0x64, 0x11b, 0x6c, 0x65, 0x3b, 0x70, 0x6f, 0x6e, 0x64, 0x11b, 0x6c, 0xed,
+0x3b, 0xfa, 0x74, 0x65, 0x72, 0xfd, 0x3b, 0x73, 0x74, 0x159, 0x65, 0x64, 0x61, 0x3b, 0x10d, 0x74, 0x76, 0x72, 0x74, 0x65,
+0x6b, 0x3b, 0x70, 0xe1, 0x74, 0x65, 0x6b, 0x3b, 0x73, 0x6f, 0x62, 0x6f, 0x74, 0x61, 0x3b, 0x53, 0x3b, 0x4d, 0x3b, 0x54,
+0x3b, 0x4f, 0x3b, 0x54, 0x3b, 0x46, 0x3b, 0x4c, 0x3b, 0x73, 0xf8, 0x6e, 0x3b, 0x6d, 0x61, 0x6e, 0x3b, 0x74, 0x69, 0x72,
+0x3b, 0x6f, 0x6e, 0x73, 0x3b, 0x74, 0x6f, 0x72, 0x3b, 0x66, 0x72, 0x65, 0x3b, 0x6c, 0xf8, 0x72, 0x3b, 0x73, 0xf8, 0x6e,
+0x64, 0x61, 0x67, 0x3b, 0x6d, 0x61, 0x6e, 0x64, 0x61, 0x67, 0x3b, 0x74, 0x69, 0x72, 0x73, 0x64, 0x61, 0x67, 0x3b, 0x6f,
+0x6e, 0x73, 0x64, 0x61, 0x67, 0x3b, 0x74, 0x6f, 0x72, 0x73, 0x64, 0x61, 0x67, 0x3b, 0x66, 0x72, 0x65, 0x64, 0x61, 0x67,
+0x3b, 0x6c, 0xf8, 0x72, 0x64, 0x61, 0x67, 0x3b, 0x5a, 0x3b, 0x4d, 0x3b, 0x44, 0x3b, 0x57, 0x3b, 0x44, 0x3b, 0x56, 0x3b,
+0x5a, 0x3b, 0x7a, 0x6f, 0x3b, 0x6d, 0x61, 0x3b, 0x64, 0x69, 0x3b, 0x77, 0x6f, 0x3b, 0x64, 0x6f, 0x3b, 0x76, 0x72, 0x3b,
+0x7a, 0x61, 0x3b, 0x7a, 0x6f, 0x6e, 0x64, 0x61, 0x67, 0x3b, 0x6d, 0x61, 0x61, 0x6e, 0x64, 0x61, 0x67, 0x3b, 0x64, 0x69,
+0x6e, 0x73, 0x64, 0x61, 0x67, 0x3b, 0x77, 0x6f, 0x65, 0x6e, 0x73, 0x64, 0x61, 0x67, 0x3b, 0x64, 0x6f, 0x6e, 0x64, 0x65,
+0x72, 0x64, 0x61, 0x67, 0x3b, 0x76, 0x72, 0x69, 0x6a, 0x64, 0x61, 0x67, 0x3b, 0x7a, 0x61, 0x74, 0x65, 0x72, 0x64, 0x61,
+0x67, 0x3b, 0x50, 0x3b, 0x45, 0x3b, 0x54, 0x3b, 0x4b, 0x3b, 0x4e, 0x3b, 0x52, 0x3b, 0x4c, 0x3b, 0x70, 0xfc, 0x68, 0x61,
+0x70, 0xe4, 0x65, 0x76, 0x3b, 0x65, 0x73, 0x6d, 0x61, 0x73, 0x70, 0xe4, 0x65, 0x76, 0x3b, 0x74, 0x65, 0x69, 0x73, 0x69,
+0x70, 0xe4, 0x65, 0x76, 0x3b, 0x6b, 0x6f, 0x6c, 0x6d, 0x61, 0x70, 0xe4, 0x65, 0x76, 0x3b, 0x6e, 0x65, 0x6c, 0x6a, 0x61,
+0x70, 0xe4, 0x65, 0x76, 0x3b, 0x72, 0x65, 0x65, 0x64, 0x65, 0x3b, 0x6c, 0x61, 0x75, 0x70, 0xe4, 0x65, 0x76, 0x3b, 0x73,
+0x75, 0x6e, 0x3b, 0x6d, 0xe1, 0x6e, 0x3b, 0x74, 0xfd, 0x73, 0x3b, 0x6d, 0x69, 0x6b, 0x3b, 0x68, 0xf3, 0x73, 0x3b, 0x66,
+0x72, 0xed, 0x3b, 0x6c, 0x65, 0x79, 0x3b, 0x73, 0x75, 0x6e, 0x6e, 0x75, 0x64, 0x61, 0x67, 0x75, 0x72, 0x3b, 0x6d, 0xe1,
+0x6e, 0x61, 0x64, 0x61, 0x67, 0x75, 0x72, 0x3b, 0x74, 0xfd, 0x73, 0x64, 0x61, 0x67, 0x75, 0x72, 0x3b, 0x6d, 0x69, 0x6b,
+0x75, 0x64, 0x61, 0x67, 0x75, 0x72, 0x3b, 0x68, 0xf3, 0x73, 0x64, 0x61, 0x67, 0x75, 0x72, 0x3b, 0x66, 0x72, 0xed, 0x67,
+0x67, 0x6a, 0x61, 0x64, 0x61, 0x67, 0x75, 0x72, 0x3b, 0x6c, 0x65, 0x79, 0x67, 0x61, 0x72, 0x64, 0x61, 0x67, 0x75, 0x72,
+0x3b, 0x53, 0x3b, 0x4d, 0x3b, 0x54, 0x3b, 0x4b, 0x3b, 0x54, 0x3b, 0x50, 0x3b, 0x4c, 0x3b, 0x73, 0x75, 0x3b, 0x6d, 0x61,
+0x3b, 0x74, 0x69, 0x3b, 0x6b, 0x65, 0x3b, 0x74, 0x6f, 0x3b, 0x70, 0x65, 0x3b, 0x6c, 0x61, 0x3b, 0x73, 0x75, 0x6e, 0x6e,
+0x75, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x61, 0x3b, 0x6d, 0x61, 0x61, 0x6e, 0x61, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x61, 0x3b,
+0x74, 0x69, 0x69, 0x73, 0x74, 0x61, 0x69, 0x6e, 0x61, 0x3b, 0x6b, 0x65, 0x73, 0x6b, 0x69, 0x76, 0x69, 0x69, 0x6b, 0x6b,
+0x6f, 0x6e, 0x61, 0x3b, 0x74, 0x6f, 0x72, 0x73, 0x74, 0x61, 0x69, 0x6e, 0x61, 0x3b, 0x70, 0x65, 0x72, 0x6a, 0x61, 0x6e,
+0x74, 0x61, 0x69, 0x6e, 0x61, 0x3b, 0x6c, 0x61, 0x75, 0x61, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x61, 0x3b, 0x44, 0x3b, 0x4c,
+0x3b, 0x4d, 0x3b, 0x4d, 0x3b, 0x4a, 0x3b, 0x56, 0x3b, 0x53, 0x3b, 0x64, 0x69, 0x6d, 0x2e, 0x3b, 0x6c, 0x75, 0x6e, 0x2e,
+0x3b, 0x6d, 0x61, 0x72, 0x2e, 0x3b, 0x6d, 0x65, 0x72, 0x2e, 0x3b, 0x6a, 0x65, 0x75, 0x2e, 0x3b, 0x76, 0x65, 0x6e, 0x2e,
+0x3b, 0x73, 0x61, 0x6d, 0x2e, 0x3b, 0x64, 0x69, 0x6d, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x3b, 0x6c, 0x75, 0x6e, 0x64, 0x69,
+0x3b, 0x6d, 0x61, 0x72, 0x64, 0x69, 0x3b, 0x6d, 0x65, 0x72, 0x63, 0x72, 0x65, 0x64, 0x69, 0x3b, 0x6a, 0x65, 0x75, 0x64,
+0x69, 0x3b, 0x76, 0x65, 0x6e, 0x64, 0x72, 0x65, 0x64, 0x69, 0x3b, 0x73, 0x61, 0x6d, 0x65, 0x64, 0x69, 0x3b, 0x44, 0x3b,
+0x4c, 0x3b, 0x4d, 0x3b, 0x4d, 0x3b, 0x58, 0x3b, 0x56, 0x3b, 0x53, 0x3b, 0x44, 0x6f, 0x6d, 0x3b, 0x4c, 0x75, 0x6e, 0x3b,
+0x4d, 0x61, 0x72, 0x3b, 0x4d, 0xe9, 0x72, 0x3b, 0x58, 0x6f, 0x76, 0x3b, 0x56, 0x65, 0x6e, 0x3b, 0x53, 0xe1, 0x62, 0x3b,
+0x44, 0x6f, 0x6d, 0x69, 0x6e, 0x67, 0x6f, 0x3b, 0x4c, 0x75, 0x6e, 0x73, 0x3b, 0x4d, 0x61, 0x72, 0x74, 0x65, 0x73, 0x3b,
+0x4d, 0xe9, 0x72, 0x63, 0x6f, 0x72, 0x65, 0x73, 0x3b, 0x58, 0x6f, 0x76, 0x65, 0x73, 0x3b, 0x56, 0x65, 0x6e, 0x72, 0x65,
+0x73, 0x3b, 0x53, 0xe1, 0x62, 0x61, 0x64, 0x6f, 0x3b, 0x10d9, 0x3b, 0x10dd, 0x3b, 0x10e1, 0x3b, 0x10dd, 0x3b, 0x10ee, 0x3b, 0x10de,
+0x3b, 0x10e8, 0x3b, 0x10d9, 0x10d5, 0x10d8, 0x3b, 0x10dd, 0x10e0, 0x10e8, 0x3b, 0x10e1, 0x10d0, 0x10db, 0x3b, 0x10dd, 0x10d7, 0x10ee, 0x3b, 0x10ee,
+0x10e3, 0x10d7, 0x3b, 0x10de, 0x10d0, 0x10e0, 0x3b, 0x10e8, 0x10d0, 0x10d1, 0x3b, 0x10d9, 0x10d5, 0x10d8, 0x10e0, 0x10d0, 0x3b, 0x10dd, 0x10e0, 0x10e8,
+0x10d0, 0x10d1, 0x10d0, 0x10d7, 0x10d8, 0x3b, 0x10e1, 0x10d0, 0x10db, 0x10e8, 0x10d0, 0x10d1, 0x10d0, 0x10d7, 0x10d8, 0x3b, 0x10dd, 0x10d7, 0x10ee, 0x10e8,
+0x10d0, 0x10d1, 0x10d0, 0x10d7, 0x10d8, 0x3b, 0x10ee, 0x10e3, 0x10d7, 0x10e8, 0x10d0, 0x10d1, 0x10d0, 0x10d7, 0x10d8, 0x3b, 0x10de, 0x10d0, 0x10e0, 0x10d0,
+0x10e1, 0x10d9, 0x10d4, 0x10d5, 0x10d8, 0x3b, 0x10e8, 0x10d0, 0x10d1, 0x10d0, 0x10d7, 0x10d8, 0x3b, 0x53, 0x3b, 0x4d, 0x3b, 0x44, 0x3b, 0x4d,
+0x3b, 0x44, 0x3b, 0x46, 0x3b, 0x53, 0x3b, 0x53, 0x6f, 0x2e, 0x3b, 0x4d, 0x6f, 0x2e, 0x3b, 0x44, 0x69, 0x2e, 0x3b, 0x4d,
+0x69, 0x2e, 0x3b, 0x44, 0x6f, 0x2e, 0x3b, 0x46, 0x72, 0x2e, 0x3b, 0x53, 0x61, 0x2e, 0x3b, 0x53, 0x6f, 0x6e, 0x6e, 0x74,
+0x61, 0x67, 0x3b, 0x4d, 0x6f, 0x6e, 0x74, 0x61, 0x67, 0x3b, 0x44, 0x69, 0x65, 0x6e, 0x73, 0x74, 0x61, 0x67, 0x3b, 0x4d,
+0x69, 0x74, 0x74, 0x77, 0x6f, 0x63, 0x68, 0x3b, 0x44, 0x6f, 0x6e, 0x6e, 0x65, 0x72, 0x73, 0x74, 0x61, 0x67, 0x3b, 0x46,
+0x72, 0x65, 0x69, 0x74, 0x61, 0x67, 0x3b, 0x53, 0x61, 0x6d, 0x73, 0x74, 0x61, 0x67, 0x3b, 0x53, 0x6f, 0x6e, 0x3b, 0x4d,
+0x6f, 0x6e, 0x3b, 0x44, 0x69, 0x65, 0x3b, 0x4d, 0x69, 0x74, 0x3b, 0x44, 0x6f, 0x6e, 0x3b, 0x46, 0x72, 0x65, 0x3b, 0x53,
+0x61, 0x6d, 0x3b, 0x39a, 0x3b, 0x394, 0x3b, 0x3a4, 0x3b, 0x3a4, 0x3b, 0x3a0, 0x3b, 0x3a0, 0x3b, 0x3a3, 0x3b, 0x39a, 0x3c5, 0x3c1,
+0x3b, 0x394, 0x3b5, 0x3c5, 0x3b, 0x3a4, 0x3c1, 0x3b9, 0x3b, 0x3a4, 0x3b5, 0x3c4, 0x3b, 0x3a0, 0x3b5, 0x3bc, 0x3b, 0x3a0, 0x3b1, 0x3c1,
+0x3b, 0x3a3, 0x3b1, 0x3b2, 0x3b, 0x39a, 0x3c5, 0x3c1, 0x3b9, 0x3b1, 0x3ba, 0x3ae, 0x3b, 0x394, 0x3b5, 0x3c5, 0x3c4, 0x3ad, 0x3c1, 0x3b1,
+0x3b, 0x3a4, 0x3c1, 0x3af, 0x3c4, 0x3b7, 0x3b, 0x3a4, 0x3b5, 0x3c4, 0x3ac, 0x3c1, 0x3c4, 0x3b7, 0x3b, 0x3a0, 0x3ad, 0x3bc, 0x3c0, 0x3c4,
+0x3b7, 0x3b, 0x3a0, 0x3b1, 0x3c1, 0x3b1, 0x3c3, 0x3ba, 0x3b5, 0x3c5, 0x3ae, 0x3b, 0x3a3, 0x3ac, 0x3b2, 0x3b2, 0x3b1, 0x3c4, 0x3bf, 0x3b,
+0x73, 0x61, 0x62, 0x3b, 0x61, 0x74, 0x61, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x70, 0x69, 0x6e, 0x3b, 0x73, 0x69, 0x73, 0x3b,
+0x74, 0x61, 0x6c, 0x3b, 0x61, 0x72, 0x66, 0x3b, 0x73, 0x61, 0x62, 0x61, 0x61, 0x74, 0x3b, 0x61, 0x74, 0x61, 0x61, 0x73,
+0x69, 0x6e, 0x6e, 0x67, 0x6f, 0x72, 0x6e, 0x65, 0x71, 0x3b, 0x6d, 0x61, 0x72, 0x6c, 0x75, 0x6e, 0x6e, 0x67, 0x6f, 0x72,
+0x6e, 0x65, 0x71, 0x3b, 0x70, 0x69, 0x6e, 0x67, 0x61, 0x73, 0x75, 0x6e, 0x6e, 0x67, 0x6f, 0x72, 0x6e, 0x65, 0x71, 0x3b,
+0x73, 0x69, 0x73, 0x61, 0x6d, 0x61, 0x6e, 0x6e, 0x67, 0x6f, 0x72, 0x6e, 0x65, 0x71, 0x3b, 0x74, 0x61, 0x6c, 0x6c, 0x69,
+0x6d, 0x61, 0x6e, 0x6e, 0x67, 0x6f, 0x72, 0x6e, 0x65, 0x71, 0x3b, 0x61, 0x72, 0x66, 0x69, 0x6e, 0x69, 0x6e, 0x6e, 0x67,
+0x6f, 0x72, 0x6e, 0x65, 0x71, 0x3b, 0xab0, 0xab5, 0xabf, 0x3b, 0xab8, 0xacb, 0xaae, 0x3b, 0xaae, 0xa82, 0xa97, 0xab3, 0x3b, 0xaac,
+0xac1, 0xaa7, 0x3b, 0xa97, 0xac1, 0xab0, 0xac1, 0x3b, 0xab6, 0xac1, 0xa95, 0xacd, 0xab0, 0x3b, 0xab6, 0xaa8, 0xabf, 0x3b, 0xab0, 0xab5,
+0xabf, 0xab5, 0xabe, 0xab0, 0x3b, 0xab8, 0xacb, 0xaae, 0xab5, 0xabe, 0xab0, 0x3b, 0xaae, 0xa82, 0xa97, 0xab3, 0xab5, 0xabe, 0xab0, 0x3b,
+0xaac, 0xac1, 0xaa7, 0xab5, 0xabe, 0xab0, 0x3b, 0xa97, 0xac1, 0xab0, 0xac1, 0xab5, 0xabe, 0xab0, 0x3b, 0xab6, 0xac1, 0xa95, 0xacd, 0xab0,
+0xab5, 0xabe, 0xab0, 0x3b, 0xab6, 0xaa8, 0xabf, 0xab5, 0xabe, 0xab0, 0x3b, 0x4c, 0x3b, 0x4c, 0x3b, 0x54, 0x3b, 0x4c, 0x3b, 0x41,
+0x3b, 0x4a, 0x3b, 0x41, 0x3b, 0x4c, 0x61, 0x68, 0x3b, 0x4c, 0x69, 0x74, 0x3b, 0x54, 0x61, 0x6c, 0x3b, 0x4c, 0x61, 0x72,
+0x3b, 0x41, 0x6c, 0x68, 0x3b, 0x4a, 0x75, 0x6d, 0x3b, 0x41, 0x73, 0x61, 0x3b, 0x4c, 0x61, 0x68, 0x61, 0x64, 0x69, 0x3b,
+0x4c, 0x69, 0x74, 0x69, 0x6e, 0x69, 0x3b, 0x54, 0x61, 0x6c, 0x61, 0x74, 0x61, 0x3b, 0x4c, 0x61, 0x72, 0x61, 0x62, 0x61,
+0x3b, 0x41, 0x6c, 0x68, 0x61, 0x6d, 0x69, 0x73, 0x3b, 0x4a, 0x75, 0x6d, 0x6d, 0x61, 0x27, 0x61, 0x3b, 0x41, 0x73, 0x61,
+0x62, 0x61, 0x72, 0x3b, 0x5d0, 0x3b, 0x5d1, 0x3b, 0x5d2, 0x3b, 0x5d3, 0x3b, 0x5d4, 0x3b, 0x5d5, 0x3b, 0x5e9, 0x3b, 0x5d9, 0x5d5,
+0x5dd, 0x20, 0x5e8, 0x5d0, 0x5e9, 0x5d5, 0x5df, 0x3b, 0x5d9, 0x5d5, 0x5dd, 0x20, 0x5e9, 0x5e0, 0x5d9, 0x3b, 0x5d9, 0x5d5, 0x5dd, 0x20,
+0x5e9, 0x5dc, 0x5d9, 0x5e9, 0x5d9, 0x3b, 0x5d9, 0x5d5, 0x5dd, 0x20, 0x5e8, 0x5d1, 0x5d9, 0x5e2, 0x5d9, 0x3b, 0x5d9, 0x5d5, 0x5dd, 0x20,
+0x5d7, 0x5de, 0x5d9, 0x5e9, 0x5d9, 0x3b, 0x5d9, 0x5d5, 0x5dd, 0x20, 0x5e9, 0x5d9, 0x5e9, 0x5d9, 0x3b, 0x5e9, 0x5d1, 0x5ea, 0x3b, 0x930,
+0x3b, 0x32, 0x3b, 0x92e, 0x902, 0x3b, 0x34, 0x3b, 0x917, 0x941, 0x3b, 0x36, 0x3b, 0x37, 0x3b, 0x930, 0x935, 0x93f, 0x3b, 0x938,
+0x94b, 0x92e, 0x3b, 0x92e, 0x902, 0x917, 0x932, 0x3b, 0x92c, 0x941, 0x927, 0x3b, 0x917, 0x941, 0x930, 0x941, 0x3b, 0x936, 0x941, 0x915,
+0x94d, 0x930, 0x3b, 0x936, 0x928, 0x93f, 0x3b, 0x930, 0x935, 0x93f, 0x935, 0x93e, 0x930, 0x3b, 0x938, 0x94b, 0x92e, 0x935, 0x93e, 0x930,
+0x3b, 0x92e, 0x902, 0x917, 0x932, 0x935, 0x93e, 0x930, 0x3b, 0x92c, 0x941, 0x927, 0x935, 0x93e, 0x930, 0x3b, 0x917, 0x941, 0x930, 0x941,
+0x935, 0x93e, 0x930, 0x3b, 0x936, 0x941, 0x915, 0x94d, 0x930, 0x935, 0x93e, 0x930, 0x3b, 0x936, 0x928, 0x93f, 0x935, 0x93e, 0x930, 0x3b,
+0x56, 0x3b, 0x48, 0x3b, 0x4b, 0x3b, 0x53, 0x3b, 0x43, 0x3b, 0x50, 0x3b, 0x53, 0x3b, 0x56, 0x3b, 0x48, 0x3b, 0x4b, 0x3b,
+0x53, 0x7a, 0x65, 0x3b, 0x43, 0x73, 0x3b, 0x50, 0x3b, 0x53, 0x7a, 0x6f, 0x3b, 0x76, 0x61, 0x73, 0xe1, 0x72, 0x6e, 0x61,
+0x70, 0x3b, 0x68, 0xe9, 0x74, 0x66, 0x151, 0x3b, 0x6b, 0x65, 0x64, 0x64, 0x3b, 0x73, 0x7a, 0x65, 0x72, 0x64, 0x61, 0x3b,
+0x63, 0x73, 0xfc, 0x74, 0xf6, 0x72, 0x74, 0xf6, 0x6b, 0x3b, 0x70, 0xe9, 0x6e, 0x74, 0x65, 0x6b, 0x3b, 0x73, 0x7a, 0x6f,
+0x6d, 0x62, 0x61, 0x74, 0x3b, 0x73, 0x3b, 0x6d, 0x3b, 0xfe, 0x3b, 0x6d, 0x3b, 0x66, 0x3b, 0x66, 0x3b, 0x6c, 0x3b, 0x73,
+0x75, 0x6e, 0x3b, 0x6d, 0xe1, 0x6e, 0x3b, 0xfe, 0x72, 0x69, 0x3b, 0x6d, 0x69, 0xf0, 0x3b, 0x66, 0x69, 0x6d, 0x3b, 0x66,
+0xf6, 0x73, 0x3b, 0x6c, 0x61, 0x75, 0x3b, 0x73, 0x75, 0x6e, 0x6e, 0x75, 0x64, 0x61, 0x67, 0x75, 0x72, 0x3b, 0x6d, 0xe1,
+0x6e, 0x75, 0x64, 0x61, 0x67, 0x75, 0x72, 0x3b, 0xfe, 0x72, 0x69, 0xf0, 0x6a, 0x75, 0x64, 0x61, 0x67, 0x75, 0x72, 0x3b,
+0x6d, 0x69, 0xf0, 0x76, 0x69, 0x6b, 0x75, 0x64, 0x61, 0x67, 0x75, 0x72, 0x3b, 0x66, 0x69, 0x6d, 0x6d, 0x74, 0x75, 0x64,
+0x61, 0x67, 0x75, 0x72, 0x3b, 0x66, 0xf6, 0x73, 0x74, 0x75, 0x64, 0x61, 0x67, 0x75, 0x72, 0x3b, 0x6c, 0x61, 0x75, 0x67,
+0x61, 0x72, 0x64, 0x61, 0x67, 0x75, 0x72, 0x3b, 0x4d, 0x69, 0x6e, 0x3b, 0x53, 0x65, 0x6e, 0x3b, 0x53, 0x65, 0x6c, 0x3b,
+0x52, 0x61, 0x62, 0x3b, 0x4b, 0x61, 0x6d, 0x3b, 0x4a, 0x75, 0x6d, 0x3b, 0x53, 0x61, 0x62, 0x3b, 0x4d, 0x69, 0x6e, 0x67,
+0x67, 0x75, 0x3b, 0x53, 0x65, 0x6e, 0x69, 0x6e, 0x3b, 0x53, 0x65, 0x6c, 0x61, 0x73, 0x61, 0x3b, 0x52, 0x61, 0x62, 0x75,
+0x3b, 0x4b, 0x61, 0x6d, 0x69, 0x73, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x74, 0x3b, 0x53, 0x61, 0x62, 0x74, 0x75, 0x3b, 0x44,
+0x3b, 0x4c, 0x3b, 0x4d, 0x3b, 0x43, 0x3b, 0x44, 0x3b, 0x41, 0x3b, 0x53, 0x3b, 0x44, 0x6f, 0x6d, 0x68, 0x3b, 0x4c, 0x75,
+0x61, 0x6e, 0x3b, 0x4d, 0xe1, 0x69, 0x72, 0x74, 0x3b, 0x43, 0xe9, 0x61, 0x64, 0x3b, 0x44, 0xe9, 0x61, 0x72, 0x3b, 0x41,
+0x6f, 0x69, 0x6e, 0x65, 0x3b, 0x53, 0x61, 0x74, 0x68, 0x3b, 0x44, 0xe9, 0x20, 0x44, 0x6f, 0x6d, 0x68, 0x6e, 0x61, 0x69,
+0x67, 0x68, 0x3b, 0x44, 0xe9, 0x20, 0x4c, 0x75, 0x61, 0x69, 0x6e, 0x3b, 0x44, 0xe9, 0x20, 0x4d, 0xe1, 0x69, 0x72, 0x74,
+0x3b, 0x44, 0xe9, 0x20, 0x43, 0xe9, 0x61, 0x64, 0x61, 0x6f, 0x69, 0x6e, 0x3b, 0x44, 0xe9, 0x61, 0x72, 0x64, 0x61, 0x6f,
+0x69, 0x6e, 0x3b, 0x44, 0xe9, 0x20, 0x68, 0x41, 0x6f, 0x69, 0x6e, 0x65, 0x3b, 0x44, 0xe9, 0x20, 0x53, 0x61, 0x74, 0x68,
+0x61, 0x69, 0x72, 0x6e, 0x3b, 0x44, 0x6f, 0x6d, 0x65, 0x6e, 0x69, 0x63, 0x61, 0x3b, 0x4c, 0x75, 0x6e, 0x65, 0x64, 0xec,
+0x3b, 0x4d, 0x61, 0x72, 0x74, 0x65, 0x64, 0xec, 0x3b, 0x4d, 0x65, 0x72, 0x63, 0x6f, 0x6c, 0x65, 0x64, 0xec, 0x3b, 0x47,
+0x69, 0x6f, 0x76, 0x65, 0x64, 0xec, 0x3b, 0x56, 0x65, 0x6e, 0x65, 0x72, 0x64, 0xec, 0x3b, 0x53, 0x61, 0x62, 0x61, 0x74,
+0x6f, 0x3b, 0x44, 0x3b, 0x4c, 0x3b, 0x4d, 0x3b, 0x4d, 0x3b, 0x47, 0x3b, 0x56, 0x3b, 0x53, 0x3b, 0x64, 0x6f, 0x6d, 0x3b,
+0x6c, 0x75, 0x6e, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x6d, 0x65, 0x72, 0x3b, 0x67, 0x69, 0x6f, 0x3b, 0x76, 0x65, 0x6e, 0x3b,
+0x73, 0x61, 0x62, 0x3b, 0x64, 0x6f, 0x6d, 0x65, 0x6e, 0x69, 0x63, 0x61, 0x3b, 0x6c, 0x75, 0x6e, 0x65, 0x64, 0xec, 0x3b,
+0x6d, 0x61, 0x72, 0x74, 0x65, 0x64, 0xec, 0x3b, 0x6d, 0x65, 0x72, 0x63, 0x6f, 0x6c, 0x65, 0x64, 0xec, 0x3b, 0x67, 0x69,
+0x6f, 0x76, 0x65, 0x64, 0xec, 0x3b, 0x76, 0x65, 0x6e, 0x65, 0x72, 0x64, 0xec, 0x3b, 0x73, 0x61, 0x62, 0x61, 0x74, 0x6f,
+0x3b, 0x65e5, 0x3b, 0x6708, 0x3b, 0x706b, 0x3b, 0x6c34, 0x3b, 0x6728, 0x3b, 0x91d1, 0x3b, 0x571f, 0x3b, 0x65e5, 0x66dc, 0x65e5, 0x3b, 0x6708,
+0x66dc, 0x65e5, 0x3b, 0x706b, 0x66dc, 0x65e5, 0x3b, 0x6c34, 0x66dc, 0x65e5, 0x3b, 0x6728, 0x66dc, 0x65e5, 0x3b, 0x91d1, 0x66dc, 0x65e5, 0x3b, 0x571f,
+0x66dc, 0x65e5, 0x3b, 0xcb0, 0x2e, 0x3b, 0xcb8, 0xccb, 0x2e, 0x3b, 0xcae, 0xc82, 0x2e, 0x3b, 0xcac, 0xcc1, 0x2e, 0x3b, 0xc97, 0xcc1,
+0x2e, 0x3b, 0xcb6, 0xcc1, 0x2e, 0x3b, 0xcb6, 0xca8, 0xcbf, 0x2e, 0x3b, 0xcb0, 0xcb5, 0xcbf, 0xcb5, 0xcbe, 0xcb0, 0x3b, 0xcb8, 0xccb,
+0xcae, 0xcb5, 0xcbe, 0xcb0, 0x3b, 0xcae, 0xc82, 0xc97, 0xcb3, 0xcb5, 0xcbe, 0xcb0, 0x3b, 0xcac, 0xcc1, 0xca7, 0xcb5, 0xcbe, 0xcb0, 0x3b,
+0xc97, 0xcc1, 0xcb0, 0xcc1, 0xcb5, 0xcbe, 0xcb0, 0x3b, 0xcb6, 0xcc1, 0xc95, 0xccd, 0xcb0, 0xcb5, 0xcbe, 0xcb0, 0x3b, 0xcb6, 0xca8, 0xcbf,
+0xcb5, 0xcbe, 0xcb0, 0x3b, 0x436, 0x441, 0x2e, 0x3b, 0x434, 0x441, 0x2e, 0x3b, 0x441, 0x441, 0x2e, 0x3b, 0x441, 0x440, 0x2e, 0x3b,
+0x431, 0x441, 0x2e, 0x3b, 0x436, 0x43c, 0x2e, 0x3b, 0x441, 0x4bb, 0x2e, 0x3b, 0x436, 0x435, 0x43a, 0x441, 0x435, 0x43d, 0x456, 0x3b,
+0x434, 0x443, 0x439, 0x441, 0x435, 0x43d, 0x431, 0x456, 0x3b, 0x441, 0x435, 0x439, 0x441, 0x435, 0x43d, 0x431, 0x456, 0x3b, 0x441, 0x4d9,
+0x440, 0x435, 0x43d, 0x431, 0x456, 0x3b, 0x431, 0x435, 0x439, 0x441, 0x435, 0x43d, 0x431, 0x456, 0x3b, 0x436, 0x4b1, 0x43c, 0x430, 0x3b,
+0x441, 0x435, 0x43d, 0x431, 0x456, 0x3b, 0x63, 0x79, 0x75, 0x2e, 0x3b, 0x6d, 0x62, 0x65, 0x2e, 0x3b, 0x6b, 0x61, 0x62, 0x2e,
+0x3b, 0x67, 0x74, 0x75, 0x2e, 0x3b, 0x6b, 0x61, 0x6e, 0x2e, 0x3b, 0x67, 0x6e, 0x75, 0x2e, 0x3b, 0x67, 0x6e, 0x64, 0x2e,
+0x3b, 0x4b, 0x75, 0x20, 0x63, 0x79, 0x75, 0x6d, 0x77, 0x65, 0x72, 0x75, 0x3b, 0x4b, 0x75, 0x77, 0x61, 0x20, 0x6d, 0x62,
+0x65, 0x72, 0x65, 0x3b, 0x4b, 0x75, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x62, 0x69, 0x72, 0x69, 0x3b, 0x4b, 0x75, 0x77, 0x61,
+0x20, 0x67, 0x61, 0x74, 0x61, 0x74, 0x75, 0x3b, 0x4b, 0x75, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x6e, 0x65, 0x3b, 0x4b, 0x75,
+0x77, 0x61, 0x20, 0x67, 0x61, 0x74, 0x61, 0x6e, 0x75, 0x3b, 0x4b, 0x75, 0x77, 0x61, 0x20, 0x67, 0x61, 0x74, 0x61, 0x6e,
+0x64, 0x61, 0x74, 0x75, 0x3b, 0xc77c, 0x3b, 0xc6d4, 0x3b, 0xd654, 0x3b, 0xc218, 0x3b, 0xbaa9, 0x3b, 0xae08, 0x3b, 0xd1a0, 0x3b, 0xc77c,
+0xc694, 0xc77c, 0x3b, 0xc6d4, 0xc694, 0xc77c, 0x3b, 0xd654, 0xc694, 0xc77c, 0x3b, 0xc218, 0xc694, 0xc77c, 0x3b, 0xbaa9, 0xc694, 0xc77c, 0x3b, 0xae08,
+0xc694, 0xc77c, 0x3b, 0xd1a0, 0xc694, 0xc77c, 0x3b, 0xead, 0xeb2, 0x2e, 0x3b, 0xe88, 0x2e, 0x3b, 0xead, 0x2e, 0x3b, 0xe9e, 0x2e, 0x3b,
+0xe9e, 0xeab, 0x2e, 0x3b, 0xeaa, 0xe81, 0x2e, 0x3b, 0xeaa, 0x2e, 0x3b, 0xea7, 0xeb1, 0xe99, 0xead, 0xeb2, 0xe97, 0xeb4, 0xe94, 0x3b,
+0xea7, 0xeb1, 0xe99, 0xe88, 0xeb1, 0xe99, 0x3b, 0xea7, 0xeb1, 0xe99, 0xead, 0xeb1, 0xe87, 0xe84, 0xeb2, 0xe99, 0x3b, 0xea7, 0xeb1, 0xe99,
+0xe9e, 0xeb8, 0xe94, 0x3b, 0xea7, 0xeb1, 0xe99, 0xe9e, 0xeb0, 0xeab, 0xeb1, 0xe94, 0x3b, 0xea7, 0xeb1, 0xe99, 0xeaa, 0xeb8, 0xe81, 0x3b,
+0xea7, 0xeb1, 0xe99, 0xec0, 0xeaa, 0xebb, 0xeb2, 0x3b, 0x3b, 0x50, 0x72, 0x3b, 0x6f, 0x74, 0x3b, 0x54, 0x72, 0x3b, 0x43, 0x65,
+0x3b, 0x70, 0x6b, 0x3b, 0x53, 0x65, 0x3b, 0x53, 0x3b, 0x50, 0x3b, 0x4f, 0x3b, 0x54, 0x3b, 0x43, 0x3b, 0x50, 0x3b, 0x53,
+0x3b, 0x53, 0x76, 0x3b, 0x50, 0x3b, 0x4f, 0x3b, 0x54, 0x3b, 0x43, 0x3b, 0x50, 0x6b, 0x3b, 0x53, 0x3b, 0x73, 0x76, 0x113,
+0x74, 0x64, 0x69, 0x65, 0x6e, 0x61, 0x3b, 0x70, 0x69, 0x72, 0x6d, 0x64, 0x69, 0x65, 0x6e, 0x61, 0x3b, 0x6f, 0x74, 0x72,
+0x64, 0x69, 0x65, 0x6e, 0x61, 0x3b, 0x74, 0x72, 0x65, 0x161, 0x64, 0x69, 0x65, 0x6e, 0x61, 0x3b, 0x63, 0x65, 0x74, 0x75,
+0x72, 0x74, 0x64, 0x69, 0x65, 0x6e, 0x61, 0x3b, 0x70, 0x69, 0x65, 0x6b, 0x74, 0x64, 0x69, 0x65, 0x6e, 0x61, 0x3b, 0x73,
+0x65, 0x73, 0x74, 0x64, 0x69, 0x65, 0x6e, 0x61, 0x3b, 0x65, 0x79, 0x65, 0x3b, 0x6d, 0x31, 0x3b, 0x6d, 0x32, 0x3b, 0x6d,
+0x33, 0x3b, 0x6d, 0x34, 0x3b, 0x6d, 0x35, 0x3b, 0x6d, 0x70, 0x73, 0x3b, 0x65, 0x79, 0x65, 0x6e, 0x67, 0x61, 0x3b, 0x6d,
+0x6f, 0x6b, 0x254, 0x6c, 0x254, 0x20, 0x79, 0x61, 0x20, 0x6c, 0x69, 0x62, 0x6f, 0x73, 0xf3, 0x3b, 0x6d, 0x6f, 0x6b, 0x254,
+0x6c, 0x254, 0x20, 0x79, 0x61, 0x20, 0x6d, 0xed, 0x62, 0x61, 0x6c, 0xe9, 0x3b, 0x6d, 0x6f, 0x6b, 0x254, 0x6c, 0x254, 0x20,
+0x79, 0x61, 0x20, 0x6d, 0xed, 0x73, 0xe1, 0x74, 0x6f, 0x3b, 0x6d, 0x6f, 0x6b, 0x254, 0x6c, 0x254, 0x20, 0x79, 0x61, 0x20,
+0x6d, 0xed, 0x6e, 0xe9, 0x69, 0x3b, 0x6d, 0x6f, 0x6b, 0x254, 0x6c, 0x254, 0x20, 0x79, 0x61, 0x20, 0x6d, 0xed, 0x74, 0xe1,
+0x6e, 0x6f, 0x3b, 0x6d, 0x70, 0x254, 0x301, 0x73, 0x254, 0x3b, 0x53, 0x3b, 0x50, 0x3b, 0x41, 0x3b, 0x54, 0x3b, 0x4b, 0x3b,
+0x50, 0x3b, 0x160, 0x3b, 0x53, 0x6b, 0x3b, 0x50, 0x72, 0x3b, 0x41, 0x6e, 0x3b, 0x54, 0x72, 0x3b, 0x4b, 0x74, 0x3b, 0x50,
+0x6e, 0x3b, 0x160, 0x74, 0x3b, 0x73, 0x65, 0x6b, 0x6d, 0x61, 0x64, 0x69, 0x65, 0x6e, 0x69, 0x73, 0x3b, 0x70, 0x69, 0x72,
+0x6d, 0x61, 0x64, 0x69, 0x65, 0x6e, 0x69, 0x73, 0x3b, 0x61, 0x6e, 0x74, 0x72, 0x61, 0x64, 0x69, 0x65, 0x6e, 0x69, 0x73,
+0x3b, 0x74, 0x72, 0x65, 0x10d, 0x69, 0x61, 0x64, 0x69, 0x65, 0x6e, 0x69, 0x73, 0x3b, 0x6b, 0x65, 0x74, 0x76, 0x69, 0x72,
+0x74, 0x61, 0x64, 0x69, 0x65, 0x6e, 0x69, 0x73, 0x3b, 0x70, 0x65, 0x6e, 0x6b, 0x74, 0x61, 0x64, 0x69, 0x65, 0x6e, 0x69,
+0x73, 0x3b, 0x161, 0x65, 0x161, 0x74, 0x61, 0x64, 0x69, 0x65, 0x6e, 0x69, 0x73, 0x3b, 0x43d, 0x435, 0x434, 0x2e, 0x3b, 0x43f,
+0x43e, 0x43d, 0x2e, 0x3b, 0x432, 0x442, 0x2e, 0x3b, 0x441, 0x440, 0x435, 0x2e, 0x3b, 0x447, 0x435, 0x442, 0x2e, 0x3b, 0x43f, 0x435,
+0x442, 0x2e, 0x3b, 0x441, 0x430, 0x431, 0x2e, 0x3b, 0x43d, 0x435, 0x434, 0x435, 0x43b, 0x430, 0x3b, 0x43f, 0x43e, 0x43d, 0x435, 0x434,
+0x435, 0x43b, 0x43d, 0x438, 0x43a, 0x3b, 0x432, 0x442, 0x43e, 0x440, 0x43d, 0x438, 0x43a, 0x3b, 0x441, 0x440, 0x435, 0x434, 0x430, 0x3b,
+0x447, 0x435, 0x442, 0x432, 0x440, 0x442, 0x43e, 0x43a, 0x3b, 0x43f, 0x435, 0x442, 0x43e, 0x43a, 0x3b, 0x441, 0x430, 0x431, 0x43e, 0x442,
+0x430, 0x3b, 0x41, 0x68, 0x64, 0x3b, 0x49, 0x73, 0x6e, 0x3b, 0x53, 0x65, 0x6c, 0x3b, 0x52, 0x61, 0x62, 0x3b, 0x4b, 0x68,
+0x61, 0x3b, 0x4a, 0x75, 0x6d, 0x3b, 0x53, 0x61, 0x62, 0x3b, 0x41, 0x68, 0x61, 0x64, 0x3b, 0x49, 0x73, 0x6e, 0x69, 0x6e,
+0x3b, 0x53, 0x65, 0x6c, 0x61, 0x73, 0x61, 0x3b, 0x52, 0x61, 0x62, 0x75, 0x3b, 0x4b, 0x68, 0x61, 0x6d, 0x69, 0x73, 0x3b,
+0x4a, 0x75, 0x6d, 0x61, 0x61, 0x74, 0x3b, 0x53, 0x61, 0x62, 0x74, 0x75, 0x3b, 0x3b, 0xd24, 0xd3f, 0xd19, 0xd4d, 0xd15, 0xd33,
+0xd3e, 0xd34, 0xd4d, 0xd1a, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0xd1e, 0x3b, 0xd24, 0x3b, 0xd1a, 0x3b, 0xd2c, 0x3b, 0xd35, 0x3b,
+0xd35, 0x3b, 0xd36, 0x3b, 0xd1e, 0xd3e, 0x3b, 0xd24, 0xd3f, 0x3b, 0xd1a, 0xd4a, 0x3b, 0xd2c, 0xd41, 0x3b, 0xd35, 0xd4d, 0xd2f, 0xd3e,
+0x3b, 0xd35, 0xd46, 0x3b, 0xd36, 0x3b, 0xd1e, 0xd3e, 0xd2f, 0xd30, 0xd4d, 0x200d, 0x3b, 0xd24, 0xd3f, 0xd19, 0xd4d, 0xd15, 0xd33, 0xd4d,
+0x200d, 0x3b, 0xd1a, 0xd4a, 0xd35, 0xd4d, 0xd35, 0x3b, 0xd2c, 0xd41, 0xd27, 0xd28, 0xd4d, 0x200d, 0x3b, 0xd35, 0xd4d, 0xd2f, 0xd3e, 0xd34,
+0xd02, 0x3b, 0xd35, 0xd46, 0xd33, 0xd4d, 0xd33, 0xd3f, 0x3b, 0xd36, 0xd28, 0xd3f, 0x3b, 0x3b, 0x3b, 0xd1a, 0xd4a, 0x3b, 0x3b, 0x3b,
+0x3b, 0x3b, 0x126, 0x3b, 0x54, 0x3b, 0x54, 0x3b, 0x45, 0x3b, 0x126, 0x3b, 0x120, 0x3b, 0x53, 0x3b, 0x126, 0x61, 0x64, 0x3b,
+0x54, 0x6e, 0x65, 0x3b, 0x54, 0x6c, 0x69, 0x3b, 0x45, 0x72, 0x62, 0x3b, 0x126, 0x61, 0x6d, 0x3b, 0x120, 0x69, 0x6d, 0x3b,
+0x53, 0x69, 0x62, 0x3b, 0x49, 0x6c, 0x2d, 0x126, 0x61, 0x64, 0x64, 0x3b, 0x49, 0x74, 0x2d, 0x54, 0x6e, 0x65, 0x6a, 0x6e,
+0x3b, 0x49, 0x74, 0x2d, 0x54, 0x6c, 0x69, 0x65, 0x74, 0x61, 0x3b, 0x4c, 0x2d, 0x45, 0x72, 0x62, 0x67, 0x127, 0x61, 0x3b,
+0x49, 0x6c, 0x2d, 0x126, 0x61, 0x6d, 0x69, 0x73, 0x3b, 0x49, 0x6c, 0x2d, 0x120, 0x69, 0x6d, 0x67, 0x127, 0x61, 0x3b, 0x49,
+0x73, 0x2d, 0x53, 0x69, 0x62, 0x74, 0x3b, 0x930, 0x935, 0x93f, 0x3b, 0x938, 0x94b, 0x92e, 0x3b, 0x92e, 0x902, 0x917, 0x933, 0x3b,
+0x92c, 0x941, 0x927, 0x3b, 0x917, 0x941, 0x930, 0x941, 0x3b, 0x936, 0x941, 0x915, 0x94d, 0x930, 0x3b, 0x936, 0x928, 0x93f, 0x3b, 0x930,
+0x935, 0x93f, 0x935, 0x93e, 0x930, 0x3b, 0x938, 0x94b, 0x92e, 0x935, 0x93e, 0x930, 0x3b, 0x92e, 0x902, 0x917, 0x933, 0x935, 0x93e, 0x930,
+0x3b, 0x92c, 0x941, 0x927, 0x935, 0x93e, 0x930, 0x3b, 0x917, 0x941, 0x930, 0x941, 0x935, 0x93e, 0x930, 0x3b, 0x936, 0x941, 0x915, 0x94d,
+0x930, 0x935, 0x93e, 0x930, 0x3b, 0x936, 0x928, 0x93f, 0x935, 0x93e, 0x930, 0x3b, 0x41d, 0x44f, 0x3b, 0x414, 0x430, 0x3b, 0x41c, 0x44f,
+0x3b, 0x41b, 0x445, 0x3b, 0x41f, 0x4af, 0x3b, 0x411, 0x430, 0x3b, 0x411, 0x44f, 0x3b, 0x43d, 0x44f, 0x43c, 0x3b, 0x434, 0x430, 0x432,
+0x430, 0x430, 0x3b, 0x43c, 0x44f, 0x433, 0x43c, 0x430, 0x440, 0x3b, 0x43b, 0x445, 0x430, 0x433, 0x432, 0x430, 0x3b, 0x43f, 0x4af, 0x440,
+0x44d, 0x432, 0x3b, 0x431, 0x430, 0x430, 0x441, 0x430, 0x43d, 0x3b, 0x431, 0x44f, 0x43c, 0x431, 0x430, 0x3b, 0x967, 0x3b, 0x968, 0x3b,
+0x969, 0x3b, 0x96a, 0x3b, 0x96b, 0x3b, 0x96c, 0x3b, 0x96d, 0x3b, 0x906, 0x907, 0x924, 0x3b, 0x938, 0x94b, 0x92e, 0x3b, 0x92e, 0x919,
+0x94d, 0x917, 0x932, 0x3b, 0x92c, 0x941, 0x927, 0x3b, 0x92c, 0x93f, 0x939, 0x940, 0x3b, 0x936, 0x941, 0x915, 0x94d, 0x930, 0x3b, 0x936,
+0x928, 0x93f, 0x3b, 0x906, 0x907, 0x924, 0x92c, 0x93e, 0x930, 0x3b, 0x938, 0x94b, 0x92e, 0x92c, 0x93e, 0x930, 0x3b, 0x92e, 0x919, 0x94d,
+0x917, 0x932, 0x92c, 0x93e, 0x930, 0x3b, 0x92c, 0x941, 0x927, 0x92c, 0x93e, 0x930, 0x3b, 0x92c, 0x93f, 0x939, 0x940, 0x92c, 0x93e, 0x930,
+0x3b, 0x936, 0x941, 0x915, 0x94d, 0x930, 0x92c, 0x93e, 0x930, 0x3b, 0x936, 0x928, 0x93f, 0x92c, 0x93e, 0x930, 0x3b, 0x73, 0xf8, 0x6e,
+0x2e, 0x3b, 0x6d, 0x61, 0x6e, 0x2e, 0x3b, 0x74, 0x69, 0x72, 0x2e, 0x3b, 0x6f, 0x6e, 0x73, 0x2e, 0x3b, 0x74, 0x6f, 0x72,
+0x2e, 0x3b, 0x66, 0x72, 0x65, 0x2e, 0x3b, 0x6c, 0xf8, 0x72, 0x2e, 0x3b, 0xb30, 0xb2c, 0xb3f, 0x3b, 0xb38, 0xb4b, 0xb2e, 0x3b,
+0xb2e, 0xb19, 0xb4d, 0xb17, 0xb33, 0x3b, 0xb2c, 0xb41, 0xb27, 0x3b, 0xb17, 0xb41, 0xb30, 0xb41, 0x3b, 0xb36, 0xb41, 0xb15, 0xb4d, 0xb30,
+0x3b, 0xb36, 0xb28, 0xb3f, 0x3b, 0xb30, 0xb2c, 0xb3f, 0xb2c, 0xb3e, 0xb30, 0x3b, 0xb38, 0xb4b, 0xb2e, 0xb2c, 0xb3e, 0xb30, 0x3b, 0xb2e,
+0xb19, 0xb4d, 0xb17, 0xb33, 0xb2c, 0xb3e, 0xb30, 0x3b, 0xb2c, 0xb41, 0xb27, 0xb2c, 0xb3e, 0xb30, 0x3b, 0xb17, 0xb41, 0xb30, 0xb41, 0xb2c,
+0xb3e, 0xb30, 0x3b, 0xb36, 0xb41, 0xb15, 0xb4d, 0xb30, 0xb2c, 0xb3e, 0xb30, 0x3b, 0xb36, 0xb28, 0xb3f, 0xb2c, 0xb3e, 0xb30, 0x3b, 0x6cc,
+0x6a9, 0x634, 0x646, 0x628, 0x647, 0x3b, 0x62f, 0x648, 0x634, 0x646, 0x628, 0x647, 0x3b, 0x633, 0x647, 0x200c, 0x634, 0x646, 0x628, 0x647,
+0x3b, 0x686, 0x647, 0x627, 0x631, 0x634, 0x646, 0x628, 0x647, 0x3b, 0x67e, 0x646, 0x62c, 0x634, 0x646, 0x628, 0x647, 0x3b, 0x62c, 0x645,
+0x639, 0x647, 0x3b, 0x634, 0x646, 0x628, 0x647, 0x3b, 0x6cc, 0x3b, 0x62f, 0x3b, 0x633, 0x3b, 0x686, 0x3b, 0x67e, 0x3b, 0x62c, 0x3b,
+0x634, 0x3b, 0x4e, 0x3b, 0x50, 0x3b, 0x57, 0x3b, 0x15a, 0x3b, 0x43, 0x3b, 0x50, 0x3b, 0x53, 0x3b, 0x6e, 0x69, 0x65, 0x64,
+0x7a, 0x2e, 0x3b, 0x70, 0x6f, 0x6e, 0x2e, 0x3b, 0x77, 0x74, 0x2e, 0x3b, 0x15b, 0x72, 0x2e, 0x3b, 0x63, 0x7a, 0x77, 0x2e,
+0x3b, 0x70, 0x74, 0x2e, 0x3b, 0x73, 0x6f, 0x62, 0x2e, 0x3b, 0x6e, 0x69, 0x65, 0x64, 0x7a, 0x69, 0x65, 0x6c, 0x61, 0x3b,
+0x70, 0x6f, 0x6e, 0x69, 0x65, 0x64, 0x7a, 0x69, 0x61, 0x142, 0x65, 0x6b, 0x3b, 0x77, 0x74, 0x6f, 0x72, 0x65, 0x6b, 0x3b,
+0x15b, 0x72, 0x6f, 0x64, 0x61, 0x3b, 0x63, 0x7a, 0x77, 0x61, 0x72, 0x74, 0x65, 0x6b, 0x3b, 0x70, 0x69, 0x105, 0x74, 0x65,
+0x6b, 0x3b, 0x73, 0x6f, 0x62, 0x6f, 0x74, 0x61, 0x3b, 0x44, 0x3b, 0x53, 0x3b, 0x54, 0x3b, 0x51, 0x3b, 0x51, 0x3b, 0x53,
+0x3b, 0x53, 0x3b, 0x64, 0x6f, 0x6d, 0x3b, 0x73, 0x65, 0x67, 0x3b, 0x74, 0x65, 0x72, 0x3b, 0x71, 0x75, 0x61, 0x3b, 0x71,
+0x75, 0x69, 0x3b, 0x73, 0x65, 0x78, 0x3b, 0x73, 0xe1, 0x62, 0x3b, 0x64, 0x6f, 0x6d, 0x69, 0x6e, 0x67, 0x6f, 0x3b, 0x73,
+0x65, 0x67, 0x75, 0x6e, 0x64, 0x61, 0x2d, 0x66, 0x65, 0x69, 0x72, 0x61, 0x3b, 0x74, 0x65, 0x72, 0xe7, 0x61, 0x2d, 0x66,
+0x65, 0x69, 0x72, 0x61, 0x3b, 0x71, 0x75, 0x61, 0x72, 0x74, 0x61, 0x2d, 0x66, 0x65, 0x69, 0x72, 0x61, 0x3b, 0x71, 0x75,
+0x69, 0x6e, 0x74, 0x61, 0x2d, 0x66, 0x65, 0x69, 0x72, 0x61, 0x3b, 0x73, 0x65, 0x78, 0x74, 0x61, 0x2d, 0x66, 0x65, 0x69,
+0x72, 0x61, 0x3b, 0x73, 0xe1, 0x62, 0x61, 0x64, 0x6f, 0x3b, 0xa10, 0x3b, 0xa38, 0xa4b, 0x3b, 0xa2e, 0xa70, 0x3b, 0xa2c, 0xa41,
+0xa71, 0x3b, 0xa35, 0xa40, 0x3b, 0xa38, 0xa3c, 0xa41, 0xa71, 0x3b, 0xa38, 0xa3c, 0x3b, 0xa10, 0xa24, 0x2e, 0x3b, 0xa38, 0xa4b, 0xa2e,
+0x2e, 0x3b, 0xa2e, 0xa70, 0xa17, 0xa32, 0x2e, 0x3b, 0xa2c, 0xa41, 0xa27, 0x2e, 0x3b, 0xa35, 0xa40, 0xa30, 0x2e, 0x3b, 0xa38, 0xa3c,
+0xa41, 0xa15, 0xa30, 0x2e, 0x3b, 0xa38, 0xa3c, 0xa28, 0xa40, 0x2e, 0x3b, 0xa10, 0xa24, 0xa35, 0xa3e, 0xa30, 0x3b, 0xa38, 0xa4b, 0xa2e,
+0xa35, 0xa3e, 0xa30, 0x3b, 0xa2e, 0xa70, 0xa17, 0xa32, 0xa35, 0xa3e, 0xa30, 0x3b, 0xa2c, 0xa41, 0xa27, 0xa35, 0xa3e, 0xa30, 0x3b, 0xa35,
+0xa40, 0xa30, 0xa35, 0xa3e, 0xa30, 0x3b, 0xa38, 0xa3c, 0xa41, 0xa71, 0xa15, 0xa30, 0xa35, 0xa3e, 0xa30, 0x3b, 0xa38, 0xa3c, 0xa28, 0xa40,
+0xa1a, 0xa30, 0xa35, 0xa3e, 0xa30, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x73, 0xe2, 0x6d, 0x62, 0x103, 0x74, 0x103, 0x3b,
+0x44, 0x3b, 0x4c, 0x3b, 0x4d, 0x61, 0x3b, 0x4d, 0x69, 0x3b, 0x4a, 0x3b, 0x56, 0x3b, 0x53, 0x3b, 0x64, 0x75, 0x6d, 0x69,
+0x6e, 0x69, 0x63, 0x103, 0x3b, 0x6c, 0x75, 0x6e, 0x69, 0x3b, 0x6d, 0x61, 0x72, 0x21b, 0x69, 0x3b, 0x6d, 0x69, 0x65, 0x72,
+0x63, 0x75, 0x72, 0x69, 0x3b, 0x6a, 0x6f, 0x69, 0x3b, 0x76, 0x69, 0x6e, 0x65, 0x72, 0x69, 0x3b, 0x73, 0xe2, 0x6d, 0x62,
+0x103, 0x74, 0x103, 0x3b, 0x412, 0x43e, 0x441, 0x43a, 0x440, 0x435, 0x441, 0x435, 0x43d, 0x44c, 0x435, 0x3b, 0x41f, 0x43e, 0x43d, 0x435,
+0x434, 0x435, 0x43b, 0x44c, 0x43d, 0x438, 0x43a, 0x3b, 0x412, 0x442, 0x43e, 0x440, 0x43d, 0x438, 0x43a, 0x3b, 0x421, 0x440, 0x435, 0x434,
+0x430, 0x3b, 0x427, 0x435, 0x442, 0x432, 0x435, 0x440, 0x433, 0x3b, 0x41f, 0x44f, 0x442, 0x43d, 0x438, 0x446, 0x430, 0x3b, 0x421, 0x443,
+0x431, 0x431, 0x43e, 0x442, 0x430, 0x3b, 0x412, 0x3b, 0x41f, 0x3b, 0x412, 0x3b, 0x421, 0x3b, 0x427, 0x3b, 0x41f, 0x3b, 0x421, 0x3b,
+0x412, 0x441, 0x3b, 0x41f, 0x43d, 0x3b, 0x412, 0x442, 0x3b, 0x421, 0x440, 0x3b, 0x427, 0x442, 0x3b, 0x41f, 0x442, 0x3b, 0x421, 0x431,
+0x3b, 0x432, 0x43e, 0x441, 0x43a, 0x440, 0x435, 0x441, 0x435, 0x43d, 0x44c, 0x435, 0x3b, 0x43f, 0x43e, 0x43d, 0x435, 0x434, 0x435, 0x43b,
+0x44c, 0x43d, 0x438, 0x43a, 0x3b, 0x432, 0x442, 0x43e, 0x440, 0x43d, 0x438, 0x43a, 0x3b, 0x441, 0x440, 0x435, 0x434, 0x430, 0x3b, 0x447,
+0x435, 0x442, 0x432, 0x435, 0x440, 0x433, 0x3b, 0x43f, 0x44f, 0x442, 0x43d, 0x438, 0x446, 0x430, 0x3b, 0x441, 0x443, 0x431, 0x431, 0x43e,
+0x442, 0x430, 0x3b, 0x43d, 0x3b, 0x43f, 0x3b, 0x443, 0x3b, 0x441, 0x3b, 0x447, 0x3b, 0x43f, 0x3b, 0x441, 0x3b, 0x43d, 0x435, 0x434,
+0x3b, 0x43f, 0x43e, 0x43d, 0x3b, 0x443, 0x442, 0x43e, 0x3b, 0x441, 0x440, 0x435, 0x3b, 0x447, 0x435, 0x442, 0x3b, 0x43f, 0x435, 0x442,
+0x3b, 0x441, 0x443, 0x431, 0x3b, 0x43d, 0x435, 0x434, 0x435, 0x459, 0x430, 0x3b, 0x43f, 0x43e, 0x43d, 0x435, 0x434, 0x435, 0x459, 0x430,
+0x43a, 0x3b, 0x443, 0x442, 0x43e, 0x440, 0x430, 0x43a, 0x3b, 0x441, 0x440, 0x435, 0x434, 0x430, 0x3b, 0x447, 0x435, 0x442, 0x432, 0x440,
+0x442, 0x430, 0x43a, 0x3b, 0x43f, 0x435, 0x442, 0x430, 0x43a, 0x3b, 0x441, 0x443, 0x431, 0x43e, 0x442, 0x430, 0x3b, 0x43d, 0x435, 0x434,
+0x3b, 0x43f, 0x43e, 0x43d, 0x3b, 0x443, 0x442, 0x43e, 0x3b, 0x441, 0x440, 0x438, 0x3b, 0x447, 0x435, 0x442, 0x3b, 0x43f, 0x435, 0x442,
+0x3b, 0x441, 0x443, 0x431, 0x3b, 0x43d, 0x435, 0x434, 0x435, 0x459, 0x430, 0x3b, 0x43f, 0x43e, 0x43d, 0x435, 0x434, 0x435, 0x459, 0x430,
+0x43a, 0x3b, 0x443, 0x442, 0x43e, 0x440, 0x430, 0x43a, 0x3b, 0x441, 0x440, 0x438, 0x458, 0x435, 0x434, 0x430, 0x3b, 0x447, 0x435, 0x442,
+0x432, 0x440, 0x442, 0x430, 0x43a, 0x3b, 0x43f, 0x435, 0x442, 0x430, 0x43a, 0x3b, 0x441, 0x443, 0x431, 0x43e, 0x442, 0x430, 0x3b, 0x6e,
+0x65, 0x64, 0x3b, 0x70, 0x6f, 0x6e, 0x3b, 0x75, 0x74, 0x6f, 0x3b, 0x73, 0x72, 0x65, 0x3b, 0x10d, 0x65, 0x74, 0x3b, 0x70,
+0x65, 0x74, 0x3b, 0x73, 0x75, 0x62, 0x3b, 0x6e, 0x65, 0x64, 0x65, 0x6c, 0x6a, 0x61, 0x3b, 0x70, 0x6f, 0x6e, 0x65, 0x64,
+0x65, 0x6c, 0x6a, 0x61, 0x6b, 0x3b, 0x75, 0x74, 0x6f, 0x72, 0x61, 0x6b, 0x3b, 0x73, 0x72, 0x65, 0x64, 0x61, 0x3b, 0x10d,
+0x65, 0x74, 0x76, 0x72, 0x74, 0x61, 0x6b, 0x3b, 0x70, 0x65, 0x74, 0x61, 0x6b, 0x3b, 0x73, 0x75, 0x62, 0x6f, 0x74, 0x61,
+0x3b, 0x53, 0x6f, 0x6e, 0x3b, 0x4d, 0x6d, 0x61, 0x3b, 0x42, 0x65, 0x64, 0x3b, 0x52, 0x61, 0x72, 0x3b, 0x4e, 0x65, 0x3b,
+0x48, 0x6c, 0x61, 0x3b, 0x4d, 0x6f, 0x71, 0x3b, 0x53, 0x6f, 0x6e, 0x74, 0x61, 0x68, 0x61, 0x3b, 0x4d, 0x6d, 0x61, 0x6e,
+0x74, 0x61, 0x68, 0x61, 0x3b, 0x4c, 0x61, 0x62, 0x6f, 0x62, 0x65, 0x64, 0x69, 0x3b, 0x4c, 0x61, 0x62, 0x6f, 0x72, 0x61,
+0x72, 0x75, 0x3b, 0x4c, 0x61, 0x62, 0x6f, 0x6e, 0x65, 0x3b, 0x4c, 0x61, 0x62, 0x6f, 0x68, 0x6c, 0x61, 0x6e, 0x65, 0x3b,
+0x4d, 0x6f, 0x71, 0x65, 0x62, 0x65, 0x6c, 0x6f, 0x3b, 0x54, 0x73, 0x68, 0x3b, 0x4d, 0x6f, 0x73, 0x3b, 0x42, 0x65, 0x64,
+0x3b, 0x52, 0x61, 0x72, 0x3b, 0x4e, 0x65, 0x3b, 0x54, 0x6c, 0x61, 0x3b, 0x4d, 0x61, 0x74, 0x3b, 0x54, 0x73, 0x68, 0x69,
+0x70, 0x69, 0x3b, 0x4d, 0x6f, 0x73, 0x6f, 0x70, 0x75, 0x6c, 0x6f, 0x67, 0x6f, 0x3b, 0x4c, 0x61, 0x62, 0x6f, 0x62, 0x65,
+0x64, 0x69, 0x3b, 0x4c, 0x61, 0x62, 0x6f, 0x72, 0x61, 0x72, 0x6f, 0x3b, 0x4c, 0x61, 0x62, 0x6f, 0x6e, 0x65, 0x3b, 0x4c,
+0x61, 0x62, 0x6f, 0x74, 0x6c, 0x68, 0x61, 0x6e, 0x6f, 0x3b, 0x4d, 0x61, 0x74, 0x6c, 0x68, 0x61, 0x74, 0x73, 0x6f, 0x3b,
+0xd89, 0x3b, 0xdc3, 0x3b, 0xd85, 0x3b, 0xdb6, 0x3b, 0xdb6, 0xdca, 0x200d, 0xdbb, 0x3b, 0xdc3, 0xdd2, 0x3b, 0xdc3, 0xdd9, 0x3b, 0xd89,
+0xdbb, 0xdd2, 0x3b, 0xdc3, 0xdb3, 0xdd4, 0x3b, 0xd85, 0xd9f, 0x3b, 0xdb6, 0xdaf, 0xdcf, 0x3b, 0xdb6, 0xdca, 0x200d, 0xdbb, 0xdc4, 0x3b,
+0xdc3, 0xdd2, 0xd9a, 0xdd4, 0x3b, 0xdc3, 0xdd9, 0xdb1, 0x3b, 0xd89, 0xdbb, 0xdd2, 0xdaf, 0xdcf, 0x3b, 0xdc3, 0xdb3, 0xdd4, 0xdaf, 0xdcf,
+0x3b, 0xd85, 0xd9f, 0xdc4, 0xdbb, 0xdd4, 0xdc0, 0xdcf, 0xdaf, 0xdcf, 0x3b, 0xdb6, 0xdaf, 0xdcf, 0xdaf, 0xdcf, 0x3b, 0xdb6, 0xdca, 0x200d,
+0xdbb, 0xdc4, 0xdc3, 0xdca, 0xdb4, 0xdad, 0xdd2, 0xdb1, 0xdca, 0xdaf, 0xdcf, 0x3b, 0xdc3, 0xdd2, 0xd9a, 0xdd4, 0xdbb, 0xdcf, 0xdaf, 0xdcf,
+0x3b, 0xdc3, 0xdd9, 0xdb1, 0xdc3, 0xdd4, 0xdbb, 0xdcf, 0xdaf, 0xdcf, 0x3b, 0x53, 0x6f, 0x6e, 0x3b, 0x4d, 0x73, 0x6f, 0x3b, 0x42,
+0x69, 0x6c, 0x3b, 0x54, 0x73, 0x61, 0x3b, 0x4e, 0x65, 0x3b, 0x48, 0x6c, 0x61, 0x3b, 0x4d, 0x67, 0x63, 0x3b, 0x4c, 0x69,
+0x73, 0x6f, 0x6e, 0x74, 0x66, 0x6f, 0x3b, 0x75, 0x4d, 0x73, 0x6f, 0x6d, 0x62, 0x75, 0x6c, 0x75, 0x6b, 0x6f, 0x3b, 0x4c,
+0x65, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x3b, 0x4c, 0x65, 0x73, 0x69, 0x74, 0x73, 0x61, 0x74, 0x66, 0x75, 0x3b, 0x4c,
+0x65, 0x73, 0x69, 0x6e, 0x65, 0x3b, 0x4c, 0x65, 0x73, 0x69, 0x68, 0x6c, 0x61, 0x6e, 0x75, 0x3b, 0x75, 0x4d, 0x67, 0x63,
+0x69, 0x62, 0x65, 0x6c, 0x6f, 0x3b, 0x4e, 0x3b, 0x50, 0x3b, 0x55, 0x3b, 0x53, 0x3b, 0x160, 0x3b, 0x50, 0x3b, 0x53, 0x3b,
+0x4e, 0x65, 0x3b, 0x50, 0x6f, 0x3b, 0x55, 0x74, 0x3b, 0x53, 0x74, 0x3b, 0x160, 0x74, 0x3b, 0x50, 0x69, 0x3b, 0x53, 0x6f,
+0x3b, 0x4e, 0x65, 0x64, 0x65, 0x13e, 0x61, 0x3b, 0x50, 0x6f, 0x6e, 0x64, 0x65, 0x6c, 0x6f, 0x6b, 0x3b, 0x55, 0x74, 0x6f,
+0x72, 0x6f, 0x6b, 0x3b, 0x53, 0x74, 0x72, 0x65, 0x64, 0x61, 0x3b, 0x160, 0x74, 0x76, 0x72, 0x74, 0x6f, 0x6b, 0x3b, 0x50,
+0x69, 0x61, 0x74, 0x6f, 0x6b, 0x3b, 0x53, 0x6f, 0x62, 0x6f, 0x74, 0x61, 0x3b, 0x6e, 0x3b, 0x70, 0x3b, 0x74, 0x3b, 0x73,
+0x3b, 0x10d, 0x3b, 0x70, 0x3b, 0x73, 0x3b, 0x6e, 0x65, 0x64, 0x3b, 0x70, 0x6f, 0x6e, 0x3b, 0x74, 0x6f, 0x72, 0x3b, 0x73,
+0x72, 0x65, 0x3b, 0x10d, 0x65, 0x74, 0x3b, 0x70, 0x65, 0x74, 0x3b, 0x73, 0x6f, 0x62, 0x3b, 0x6e, 0x65, 0x64, 0x65, 0x6c,
+0x6a, 0x61, 0x3b, 0x70, 0x6f, 0x6e, 0x65, 0x64, 0x65, 0x6c, 0x6a, 0x65, 0x6b, 0x3b, 0x74, 0x6f, 0x72, 0x65, 0x6b, 0x3b,
+0x73, 0x72, 0x65, 0x64, 0x61, 0x3b, 0x10d, 0x65, 0x74, 0x72, 0x74, 0x65, 0x6b, 0x3b, 0x70, 0x65, 0x74, 0x65, 0x6b, 0x3b,
+0x73, 0x6f, 0x62, 0x6f, 0x74, 0x61, 0x3b, 0x41, 0x3b, 0x49, 0x3b, 0x53, 0x3b, 0x41, 0x3b, 0x4b, 0x3b, 0x4a, 0x3b, 0x53,
+0x3b, 0x41, 0x78, 0x61, 0x3b, 0x49, 0x73, 0x6e, 0x3b, 0x53, 0x61, 0x6c, 0x3b, 0x41, 0x72, 0x62, 0x3b, 0x4b, 0x68, 0x61,
+0x3b, 0x4a, 0x69, 0x6d, 0x3b, 0x53, 0x61, 0x62, 0x3b, 0x41, 0x78, 0x61, 0x64, 0x3b, 0x49, 0x73, 0x6e, 0x69, 0x69, 0x6e,
+0x3b, 0x53, 0x61, 0x6c, 0x61, 0x61, 0x73, 0x6f, 0x3b, 0x41, 0x72, 0x62, 0x61, 0x63, 0x6f, 0x3b, 0x4b, 0x68, 0x61, 0x6d,
+0x69, 0x69, 0x73, 0x3b, 0x4a, 0x69, 0x6d, 0x63, 0x6f, 0x3b, 0x53, 0x61, 0x62, 0x74, 0x69, 0x3b, 0x64, 0x6f, 0x6d, 0x3b,
+0x6c, 0x75, 0x6e, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x6d, 0x69, 0xe9, 0x3b, 0x6a, 0x75, 0x65, 0x3b, 0x76, 0x69, 0x65, 0x3b,
+0x73, 0xe1, 0x62, 0x3b, 0x64, 0x6f, 0x6d, 0x69, 0x6e, 0x67, 0x6f, 0x3b, 0x6c, 0x75, 0x6e, 0x65, 0x73, 0x3b, 0x6d, 0x61,
+0x72, 0x74, 0x65, 0x73, 0x3b, 0x6d, 0x69, 0xe9, 0x72, 0x63, 0x6f, 0x6c, 0x65, 0x73, 0x3b, 0x6a, 0x75, 0x65, 0x76, 0x65,
+0x73, 0x3b, 0x76, 0x69, 0x65, 0x72, 0x6e, 0x65, 0x73, 0x3b, 0x73, 0xe1, 0x62, 0x61, 0x64, 0x6f, 0x3b, 0x4a, 0x70, 0x69,
+0x3b, 0x4a, 0x74, 0x74, 0x3b, 0x4a, 0x6e, 0x6e, 0x3b, 0x4a, 0x74, 0x6e, 0x3b, 0x41, 0x6c, 0x68, 0x3b, 0x49, 0x6a, 0x75,
+0x3b, 0x4a, 0x6d, 0x6f, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x70, 0x69, 0x6c, 0x69, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x74, 0x61,
+0x74, 0x75, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x6e, 0x6e, 0x65, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x74, 0x61, 0x6e, 0x6f, 0x3b,
+0x41, 0x6c, 0x68, 0x61, 0x6d, 0x69, 0x73, 0x69, 0x3b, 0x49, 0x6a, 0x75, 0x6d, 0x61, 0x61, 0x3b, 0x4a, 0x75, 0x6d, 0x61,
+0x6d, 0x6f, 0x73, 0x69, 0x3b, 0x73, 0xf6, 0x6e, 0x3b, 0x6d, 0xe5, 0x6e, 0x3b, 0x74, 0x69, 0x73, 0x3b, 0x6f, 0x6e, 0x73,
+0x3b, 0x74, 0x6f, 0x72, 0x73, 0x3b, 0x66, 0x72, 0x65, 0x3b, 0x6c, 0xf6, 0x72, 0x3b, 0x73, 0xf6, 0x6e, 0x64, 0x61, 0x67,
+0x3b, 0x6d, 0xe5, 0x6e, 0x64, 0x61, 0x67, 0x3b, 0x74, 0x69, 0x73, 0x64, 0x61, 0x67, 0x3b, 0x6f, 0x6e, 0x73, 0x64, 0x61,
+0x67, 0x3b, 0x74, 0x6f, 0x72, 0x73, 0x64, 0x61, 0x67, 0x3b, 0x66, 0x72, 0x65, 0x64, 0x61, 0x67, 0x3b, 0x6c, 0xf6, 0x72,
+0x64, 0x61, 0x67, 0x3b, 0x42f, 0x448, 0x431, 0x3b, 0x414, 0x448, 0x431, 0x3b, 0x421, 0x448, 0x431, 0x3b, 0x427, 0x448, 0x431, 0x3b,
+0x41f, 0x448, 0x431, 0x3b, 0x4b6, 0x43c, 0x44a, 0x3b, 0x428, 0x43d, 0x431, 0x3b, 0x42f, 0x43a, 0x448, 0x430, 0x43d, 0x431, 0x435, 0x3b,
+0x414, 0x443, 0x448, 0x430, 0x43d, 0x431, 0x435, 0x3b, 0x421, 0x435, 0x448, 0x430, 0x43d, 0x431, 0x435, 0x3b, 0x427, 0x43e, 0x440, 0x448,
+0x430, 0x43d, 0x431, 0x435, 0x3b, 0x41f, 0x430, 0x43d, 0x4b7, 0x448, 0x430, 0x43d, 0x431, 0x435, 0x3b, 0x4b6, 0x443, 0x43c, 0x44a, 0x430,
+0x3b, 0x428, 0x430, 0x43d, 0x431, 0x435, 0x3b, 0xb9e, 0xbbe, 0x3b, 0xba4, 0xbbf, 0x3b, 0xb9a, 0xbc6, 0x3b, 0xbaa, 0xbc1, 0x3b, 0xbb5,
+0xbbf, 0x3b, 0xbb5, 0xbc6, 0x3b, 0xb9a, 0x3b, 0xb9e, 0xbbe, 0xbaf, 0xbbf, 0xbb1, 0xbc1, 0x3b, 0xba4, 0xbbf, 0xb99, 0xbcd, 0xb95, 0xbb3,
+0xbcd, 0x3b, 0xb9a, 0xbc6, 0xbb5, 0xbcd, 0xbb5, 0xbbe, 0xbaf, 0xbcd, 0x3b, 0xbaa, 0xbc1, 0xba4, 0xba9, 0xbcd, 0x3b, 0xbb5, 0xbbf, 0xbaf,
+0xbbe, 0xbb4, 0xba9, 0xbcd, 0x3b, 0xbb5, 0xbc6, 0xbb3, 0xbcd, 0xbb3, 0xbbf, 0x3b, 0xb9a, 0xba9, 0xbbf, 0x3b, 0xc06, 0x3b, 0x32, 0x3b,
+0xc38, 0xc4a, 0x3b, 0xc2d, 0xc41, 0x3b, 0xc17, 0xc41, 0x3b, 0xc36, 0xc41, 0x3b, 0xc36, 0x3b, 0xc06, 0xc26, 0xc3f, 0x3b, 0xc38, 0xc4b,
+0xc2e, 0x3b, 0xc2e, 0xc02, 0xc17, 0xc33, 0x3b, 0xc2c, 0xc41, 0xc27, 0x3b, 0xc17, 0xc41, 0xc30, 0xc41, 0x3b, 0xc36, 0xc41, 0xc15, 0xc4d,
+0xc30, 0x3b, 0xc36, 0xc28, 0xc3f, 0x3b, 0xc06, 0xc26, 0xc3f, 0xc35, 0xc3e, 0xc30, 0xc02, 0x3b, 0xc38, 0xc4b, 0xc2e, 0xc35, 0xc3e, 0xc30,
+0xc02, 0x3b, 0xc2e, 0xc02, 0xc17, 0xc33, 0xc35, 0xc3e, 0xc30, 0xc02, 0x3b, 0xc2c, 0xc41, 0xc27, 0xc35, 0xc3e, 0xc30, 0xc02, 0x3b, 0xc17,
+0xc41, 0xc30, 0xc41, 0xc35, 0xc3e, 0xc30, 0xc02, 0x3b, 0xc36, 0xc41, 0xc15, 0xc4d, 0xc30, 0xc35, 0xc3e, 0xc30, 0xc02, 0x3b, 0xc36, 0xc28,
+0xc3f, 0xc35, 0xc3e, 0xc30, 0xc02, 0x3b, 0xe2d, 0x3b, 0xe08, 0x3b, 0xe2d, 0x3b, 0xe1e, 0x3b, 0xe1e, 0x3b, 0xe28, 0x3b, 0xe2a, 0x3b,
+0xe2d, 0xe32, 0x2e, 0x3b, 0xe08, 0x2e, 0x3b, 0xe2d, 0x2e, 0x3b, 0xe1e, 0x2e, 0x3b, 0xe1e, 0xe24, 0x2e, 0x3b, 0xe28, 0x2e, 0x3b,
+0xe2a, 0x2e, 0x3b, 0xe27, 0xe31, 0xe19, 0xe2d, 0xe32, 0xe17, 0xe34, 0xe15, 0xe22, 0xe4c, 0x3b, 0xe27, 0xe31, 0xe19, 0xe08, 0xe31, 0xe19,
+0xe17, 0xe23, 0xe4c, 0x3b, 0xe27, 0xe31, 0xe19, 0xe2d, 0xe31, 0xe07, 0xe04, 0xe32, 0xe23, 0x3b, 0xe27, 0xe31, 0xe19, 0xe1e, 0xe38, 0xe18,
+0x3b, 0xe27, 0xe31, 0xe19, 0xe1e, 0xe24, 0xe2b, 0xe31, 0xe2a, 0xe1a, 0xe14, 0xe35, 0x3b, 0xe27, 0xe31, 0xe19, 0xe28, 0xe38, 0xe01, 0xe23,
+0xe4c, 0x3b, 0xe27, 0xe31, 0xe19, 0xe40, 0xe2a, 0xe32, 0xe23, 0xe4c, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0xe1e, 0xe24, 0x3b, 0x3b, 0x3b,
+0x1230, 0x3b, 0x1230, 0x3b, 0x1220, 0x3b, 0x1228, 0x3b, 0x1283, 0x3b, 0x12d3, 0x3b, 0x1240, 0x3b, 0x1230, 0x1295, 0x1260, 0x3b, 0x1230, 0x1291,
+0x12ed, 0x3b, 0x1230, 0x1209, 0x1235, 0x3b, 0x1228, 0x1261, 0x12d5, 0x3b, 0x1213, 0x1219, 0x1235, 0x3b, 0x12d3, 0x122d, 0x1262, 0x3b, 0x1240, 0x12f3,
+0x121d, 0x3b, 0x1230, 0x1295, 0x1260, 0x1275, 0x3b, 0x1230, 0x1291, 0x12ed, 0x3b, 0x1230, 0x1209, 0x1235, 0x3b, 0x1228, 0x1261, 0x12d5, 0x3b, 0x1213,
+0x1219, 0x1235, 0x3b, 0x12d3, 0x122d, 0x1262, 0x3b, 0x1240, 0x12f3, 0x121d, 0x3b, 0x1230, 0x1295, 0x1260, 0x3b, 0x1230, 0x1291, 0x12ed, 0x3b, 0x1220,
+0x1209, 0x1235, 0x3b, 0x1228, 0x1261, 0x12d5, 0x3b, 0x1283, 0x1219, 0x1235, 0x3b, 0x12d3, 0x122d, 0x1262, 0x3b, 0x1240, 0x12f3, 0x121d, 0x3b, 0x1230,
+0x1295, 0x1260, 0x1275, 0x3b, 0x1230, 0x1291, 0x12ed, 0x3b, 0x1220, 0x1209, 0x1235, 0x3b, 0x1228, 0x1261, 0x12d5, 0x3b, 0x1283, 0x1219, 0x1235, 0x3b,
+0x12d3, 0x122d, 0x1262, 0x3b, 0x1240, 0x12f3, 0x121d, 0x3b, 0x53, 0x3b, 0x4d, 0x3b, 0x54, 0x3b, 0x50, 0x3b, 0x54, 0x3b, 0x46, 0x3b,
+0x54, 0x3b, 0x53, 0x101, 0x70, 0x3b, 0x4d, 0x14d, 0x6e, 0x3b, 0x54, 0x75, 0x73, 0x3b, 0x50, 0x75, 0x6c, 0x3b, 0x54, 0x75,
+0x2bb, 0x61, 0x3b, 0x46, 0x61, 0x6c, 0x3b, 0x54, 0x6f, 0x6b, 0x3b, 0x53, 0x101, 0x70, 0x61, 0x74, 0x65, 0x3b, 0x4d, 0x14d,
+0x6e, 0x69, 0x74, 0x65, 0x3b, 0x54, 0x75, 0x73, 0x69, 0x74, 0x65, 0x3b, 0x50, 0x75, 0x6c, 0x65, 0x6c, 0x75, 0x6c, 0x75,
+0x3b, 0x54, 0x75, 0x2bb, 0x61, 0x70, 0x75, 0x6c, 0x65, 0x6c, 0x75, 0x6c, 0x75, 0x3b, 0x46, 0x61, 0x6c, 0x61, 0x69, 0x74,
+0x65, 0x3b, 0x54, 0x6f, 0x6b, 0x6f, 0x6e, 0x61, 0x6b, 0x69, 0x3b, 0x53, 0x6f, 0x6e, 0x3b, 0x4d, 0x75, 0x73, 0x3b, 0x42,
+0x69, 0x72, 0x3b, 0x48, 0x61, 0x72, 0x3b, 0x4e, 0x65, 0x3b, 0x54, 0x6c, 0x68, 0x3b, 0x4d, 0x75, 0x67, 0x3b, 0x53, 0x6f,
+0x6e, 0x74, 0x6f, 0x3b, 0x4d, 0x75, 0x73, 0x75, 0x6d, 0x62, 0x68, 0x75, 0x6e, 0x75, 0x6b, 0x75, 0x3b, 0x52, 0x61, 0x76,
+0x75, 0x6d, 0x62, 0x69, 0x72, 0x68, 0x69, 0x3b, 0x52, 0x61, 0x76, 0x75, 0x6e, 0x68, 0x61, 0x72, 0x68, 0x75, 0x3b, 0x52,
+0x61, 0x76, 0x75, 0x6d, 0x75, 0x6e, 0x65, 0x3b, 0x52, 0x61, 0x76, 0x75, 0x6e, 0x74, 0x6c, 0x68, 0x61, 0x6e, 0x75, 0x3b,
+0x4d, 0x75, 0x67, 0x71, 0x69, 0x76, 0x65, 0x6c, 0x61, 0x3b, 0x50, 0x3b, 0x50, 0x3b, 0x53, 0x3b, 0xc7, 0x3b, 0x50, 0x3b,
+0x43, 0x3b, 0x43, 0x3b, 0x50, 0x61, 0x7a, 0x3b, 0x50, 0x7a, 0x74, 0x3b, 0x53, 0x61, 0x6c, 0x3b, 0xc7, 0x61, 0x72, 0x3b,
+0x50, 0x65, 0x72, 0x3b, 0x43, 0x75, 0x6d, 0x3b, 0x43, 0x6d, 0x74, 0x3b, 0x50, 0x61, 0x7a, 0x61, 0x72, 0x3b, 0x50, 0x61,
+0x7a, 0x61, 0x72, 0x74, 0x65, 0x73, 0x69, 0x3b, 0x53, 0x61, 0x6c, 0x131, 0x3b, 0xc7, 0x61, 0x72, 0x15f, 0x61, 0x6d, 0x62,
+0x61, 0x3b, 0x50, 0x65, 0x72, 0x15f, 0x65, 0x6d, 0x62, 0x65, 0x3b, 0x43, 0x75, 0x6d, 0x61, 0x3b, 0x43, 0x75, 0x6d, 0x61,
+0x72, 0x74, 0x65, 0x73, 0x69, 0x3b, 0x41d, 0x3b, 0x41f, 0x3b, 0x412, 0x3b, 0x421, 0x3b, 0x427, 0x3b, 0x41f, 0x3b, 0x421, 0x3b,
+0x41d, 0x434, 0x3b, 0x41f, 0x43d, 0x3b, 0x412, 0x442, 0x3b, 0x421, 0x440, 0x3b, 0x427, 0x442, 0x3b, 0x41f, 0x442, 0x3b, 0x421, 0x431,
+0x3b, 0x41d, 0x435, 0x434, 0x456, 0x43b, 0x44f, 0x3b, 0x41f, 0x43e, 0x43d, 0x435, 0x434, 0x456, 0x43b, 0x43e, 0x43a, 0x3b, 0x412, 0x456,
+0x432, 0x442, 0x43e, 0x440, 0x43e, 0x43a, 0x3b, 0x421, 0x435, 0x440, 0x435, 0x434, 0x430, 0x3b, 0x427, 0x435, 0x442, 0x432, 0x435, 0x440,
+0x3b, 0x41f, 0x2bc, 0x44f, 0x442, 0x43d, 0x438, 0x446, 0x44f, 0x3b, 0x421, 0x443, 0x431, 0x43e, 0x442, 0x430, 0x3b, 0x627, 0x62a, 0x648,
+0x627, 0x631, 0x3b, 0x67e, 0x64a, 0x631, 0x3b, 0x645, 0x646, 0x6af, 0x644, 0x3b, 0x628, 0x62f, 0x647, 0x3b, 0x62c, 0x645, 0x639, 0x631,
+0x627, 0x62a, 0x3b, 0x62c, 0x645, 0x639, 0x6c1, 0x3b, 0x6c1, 0x641, 0x62a, 0x6c1, 0x3b, 0x627, 0x3b, 0x67e, 0x3b, 0x645, 0x3b, 0x628,
+0x3b, 0x62c, 0x3b, 0x62c, 0x3b, 0x6c1, 0x3b, 0x42f, 0x3b, 0x414, 0x3b, 0x421, 0x3b, 0x427, 0x3b, 0x41f, 0x3b, 0x416, 0x3b, 0x428,
+0x3b, 0x42f, 0x43a, 0x448, 0x3b, 0x414, 0x443, 0x448, 0x3b, 0x421, 0x435, 0x448, 0x3b, 0x427, 0x43e, 0x440, 0x3b, 0x41f, 0x430, 0x439,
+0x3b, 0x416, 0x443, 0x43c, 0x3b, 0x428, 0x430, 0x43d, 0x3b, 0x44f, 0x43a, 0x448, 0x430, 0x43d, 0x431, 0x430, 0x3b, 0x434, 0x443, 0x448,
+0x430, 0x43d, 0x431, 0x430, 0x3b, 0x441, 0x435, 0x448, 0x430, 0x43d, 0x431, 0x430, 0x3b, 0x447, 0x43e, 0x440, 0x448, 0x430, 0x43d, 0x431,
+0x430, 0x3b, 0x43f, 0x430, 0x439, 0x448, 0x430, 0x43d, 0x431, 0x430, 0x3b, 0x436, 0x443, 0x43c, 0x430, 0x3b, 0x448, 0x430, 0x43d, 0x431,
+0x430, 0x3b, 0x43, 0x4e, 0x3b, 0x54, 0x68, 0x20, 0x32, 0x3b, 0x54, 0x68, 0x20, 0x33, 0x3b, 0x54, 0x68, 0x20, 0x34, 0x3b,
+0x54, 0x68, 0x20, 0x35, 0x3b, 0x54, 0x68, 0x20, 0x36, 0x3b, 0x54, 0x68, 0x20, 0x37, 0x3b, 0x43, 0x68, 0x1ee7, 0x20, 0x6e,
+0x68, 0x1ead, 0x74, 0x3b, 0x54, 0x68, 0x1ee9, 0x20, 0x68, 0x61, 0x69, 0x3b, 0x54, 0x68, 0x1ee9, 0x20, 0x62, 0x61, 0x3b, 0x54,
+0x68, 0x1ee9, 0x20, 0x74, 0x1b0, 0x3b, 0x54, 0x68, 0x1ee9, 0x20, 0x6e, 0x103, 0x6d, 0x3b, 0x54, 0x68, 0x1ee9, 0x20, 0x73, 0xe1,
+0x75, 0x3b, 0x54, 0x68, 0x1ee9, 0x20, 0x62, 0x1ea3, 0x79, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x47, 0x77, 0x65, 0x3b, 0x3b,
+0x53, 0x3b, 0x4c, 0x3b, 0x4d, 0x3b, 0x4d, 0x3b, 0x49, 0x3b, 0x47, 0x3b, 0x53, 0x3b, 0x53, 0x75, 0x6c, 0x3b, 0x4c, 0x6c,
+0x75, 0x6e, 0x3b, 0x4d, 0x61, 0x77, 0x3b, 0x4d, 0x65, 0x72, 0x3b, 0x49, 0x61, 0x75, 0x3b, 0x47, 0x77, 0x65, 0x6e, 0x3b,
+0x53, 0x61, 0x64, 0x3b, 0x44, 0x79, 0x64, 0x64, 0x20, 0x53, 0x75, 0x6c, 0x3b, 0x44, 0x79, 0x64, 0x64, 0x20, 0x4c, 0x6c,
+0x75, 0x6e, 0x3b, 0x44, 0x79, 0x64, 0x64, 0x20, 0x4d, 0x61, 0x77, 0x72, 0x74, 0x68, 0x3b, 0x44, 0x79, 0x64, 0x64, 0x20,
+0x4d, 0x65, 0x72, 0x63, 0x68, 0x65, 0x72, 0x3b, 0x44, 0x79, 0x64, 0x64, 0x20, 0x49, 0x61, 0x75, 0x3b, 0x44, 0x79, 0x64,
+0x64, 0x20, 0x47, 0x77, 0x65, 0x6e, 0x65, 0x72, 0x3b, 0x44, 0x79, 0x64, 0x64, 0x20, 0x53, 0x61, 0x64, 0x77, 0x72, 0x6e,
+0x3b, 0x43, 0x61, 0x77, 0x3b, 0x4d, 0x76, 0x75, 0x3b, 0x42, 0x69, 0x6e, 0x3b, 0x54, 0x68, 0x61, 0x3b, 0x53, 0x69, 0x6e,
+0x3b, 0x48, 0x6c, 0x61, 0x3b, 0x4d, 0x67, 0x71, 0x3b, 0x43, 0x61, 0x77, 0x65, 0x3b, 0x4d, 0x76, 0x75, 0x6c, 0x6f, 0x3b,
+0x4c, 0x77, 0x65, 0x73, 0x69, 0x62, 0x69, 0x6e, 0x69, 0x3b, 0x4c, 0x77, 0x65, 0x73, 0x69, 0x74, 0x68, 0x61, 0x74, 0x68,
+0x75, 0x3b, 0x4c, 0x77, 0x65, 0x73, 0x69, 0x6e, 0x65, 0x3b, 0x4c, 0x77, 0x65, 0x73, 0x69, 0x68, 0x6c, 0x61, 0x6e, 0x75,
+0x3b, 0x4d, 0x67, 0x71, 0x69, 0x62, 0x65, 0x6c, 0x6f, 0x3b, 0xc0, 0xec, 0x6b, 0xfa, 0x3b, 0x41, 0x6a, 0xe9, 0x3b, 0xcc,
+0x73, 0x1eb9, 0x301, 0x67, 0x75, 0x6e, 0x3b, 0x1ecc, 0x6a, 0x1ecd, 0x301, 0x72, 0xfa, 0x3b, 0xc0, 0x1e63, 0x1eb9, 0x300, 0x1e63, 0x1eb9,
+0x300, 0x64, 0xe1, 0x69, 0x79, 0xe9, 0x3b, 0x1eb8, 0x74, 0xec, 0x3b, 0xc0, 0x62, 0xe1, 0x6d, 0x1eb9, 0x301, 0x74, 0x61, 0x3b,
+0x1ecc, 0x6a, 0x1ecd, 0x301, 0x20, 0xc0, 0xec, 0x6b, 0xfa, 0x3b, 0x1ecc, 0x6a, 0x1ecd, 0x301, 0x20, 0x41, 0x6a, 0xe9, 0x3b, 0x1ecc,
+0x6a, 0x1ecd, 0x301, 0x20, 0xcc, 0x73, 0x1eb9, 0x301, 0x67, 0x75, 0x6e, 0x3b, 0x1ecc, 0x6a, 0x1ecd, 0x301, 0x72, 0xfa, 0x3b, 0x1ecc,
+0x6a, 0x1ecd, 0x301, 0x20, 0xc0, 0x1e63, 0x1eb9, 0x300, 0x1e63, 0x1eb9, 0x300, 0x64, 0xe1, 0x69, 0x79, 0xe9, 0x3b, 0x1ecc, 0x6a, 0x1ecd,
+0x301, 0x20, 0x1eb8, 0x74, 0xec, 0x3b, 0x1ecc, 0x6a, 0x1ecd, 0x301, 0x20, 0xc0, 0x62, 0xe1, 0x6d, 0x1eb9, 0x301, 0x74, 0x61, 0x3b,
+0x53, 0x3b, 0x4d, 0x3b, 0x42, 0x3b, 0x54, 0x3b, 0x53, 0x3b, 0x48, 0x3b, 0x4d, 0x3b, 0x53, 0x6f, 0x6e, 0x3b, 0x4d, 0x73,
+0x6f, 0x3b, 0x42, 0x69, 0x6c, 0x3b, 0x54, 0x68, 0x61, 0x3b, 0x53, 0x69, 0x6e, 0x3b, 0x48, 0x6c, 0x61, 0x3b, 0x4d, 0x67,
+0x71, 0x3b, 0x53, 0x6f, 0x6e, 0x74, 0x6f, 0x3b, 0x4d, 0x73, 0x6f, 0x6d, 0x62, 0x75, 0x6c, 0x75, 0x6b, 0x6f, 0x3b, 0x4c,
+0x77, 0x65, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x3b, 0x4c, 0x77, 0x65, 0x73, 0x69, 0x74, 0x68, 0x61, 0x74, 0x68, 0x75,
+0x3b, 0x75, 0x4c, 0x77, 0x65, 0x73, 0x69, 0x6e, 0x65, 0x3b, 0x4c, 0x77, 0x65, 0x73, 0x69, 0x68, 0x6c, 0x61, 0x6e, 0x75,
+0x3b, 0x4d, 0x67, 0x71, 0x69, 0x62, 0x65, 0x6c, 0x6f, 0x3b, 0x3b, 0x6d, 0xe5, 0x2e, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x6c,
+0x61, 0x2e, 0x3b, 0x73, 0xf8, 0x2e, 0x3b, 0x6d, 0xe5, 0x3b, 0x74, 0x79, 0x3b, 0x6f, 0x6e, 0x3b, 0x74, 0x6f, 0x3b, 0x66,
+0x72, 0x3b, 0x6c, 0x61, 0x3b, 0x73, 0xf8, 0x6e, 0x64, 0x61, 0x67, 0x3b, 0x6d, 0xe5, 0x6e, 0x64, 0x61, 0x67, 0x3b, 0x74,
+0x79, 0x73, 0x64, 0x61, 0x67, 0x3b, 0x6f, 0x6e, 0x73, 0x64, 0x61, 0x67, 0x3b, 0x74, 0x6f, 0x72, 0x73, 0x64, 0x61, 0x67,
+0x3b, 0x66, 0x72, 0x65, 0x64, 0x61, 0x67, 0x3b, 0x6c, 0x61, 0x75, 0x72, 0x64, 0x61, 0x67, 0x3b, 0x4e, 0x65, 0x64, 0x3b,
+0x50, 0x6f, 0x6e, 0x3b, 0x55, 0x74, 0x6f, 0x3b, 0x53, 0x72, 0x69, 0x3b, 0x10c, 0x65, 0x74, 0x3b, 0x50, 0x65, 0x74, 0x3b,
+0x53, 0x75, 0x62, 0x3b, 0x4e, 0x65, 0x64, 0x6a, 0x65, 0x6c, 0x6a, 0x61, 0x3b, 0x50, 0x6f, 0x6e, 0x65, 0x64, 0x6a, 0x65,
+0x6c, 0x6a, 0x61, 0x6b, 0x3b, 0x55, 0x74, 0x6f, 0x72, 0x61, 0x6b, 0x3b, 0x53, 0x72, 0x69, 0x6a, 0x65, 0x64, 0x61, 0x3b,
+0x10c, 0x65, 0x74, 0x76, 0x72, 0x74, 0x61, 0x6b, 0x3b, 0x50, 0x65, 0x74, 0x61, 0x6b, 0x3b, 0x53, 0x75, 0x62, 0x6f, 0x74,
+0x61, 0x3b, 0x4a, 0x65, 0x64, 0x3b, 0x4a, 0x65, 0x6c, 0x3b, 0x4a, 0x65, 0x6d, 0x3b, 0x4a, 0x65, 0x72, 0x63, 0x3b, 0x4a,
+0x65, 0x72, 0x64, 0x3b, 0x4a, 0x65, 0x68, 0x3b, 0x4a, 0x65, 0x73, 0x3b, 0x4a, 0x65, 0x64, 0x6f, 0x6f, 0x6e, 0x65, 0x65,
+0x3b, 0x4a, 0x65, 0x6c, 0x68, 0x65, 0x69, 0x6e, 0x3b, 0x4a, 0x65, 0x6d, 0x61, 0x79, 0x72, 0x74, 0x3b, 0x4a, 0x65, 0x72,
+0x63, 0x65, 0x61, 0x6e, 0x3b, 0x4a, 0x65, 0x72, 0x64, 0x65, 0x69, 0x6e, 0x3b, 0x4a, 0x65, 0x68, 0x65, 0x69, 0x6e, 0x65,
+0x79, 0x3b, 0x4a, 0x65, 0x73, 0x61, 0x72, 0x6e, 0x3b, 0x53, 0x75, 0x6c, 0x3b, 0x4c, 0x75, 0x6e, 0x3b, 0x4d, 0x74, 0x68,
+0x3b, 0x4d, 0x68, 0x72, 0x3b, 0x59, 0x6f, 0x77, 0x3b, 0x47, 0x77, 0x65, 0x3b, 0x53, 0x61, 0x64, 0x3b, 0x44, 0x65, 0x20,
+0x53, 0x75, 0x6c, 0x3b, 0x44, 0x65, 0x20, 0x4c, 0x75, 0x6e, 0x3b, 0x44, 0x65, 0x20, 0x4d, 0x65, 0x72, 0x74, 0x68, 0x3b,
+0x44, 0x65, 0x20, 0x4d, 0x65, 0x72, 0x68, 0x65, 0x72, 0x3b, 0x44, 0x65, 0x20, 0x59, 0x6f, 0x77, 0x3b, 0x44, 0x65, 0x20,
+0x47, 0x77, 0x65, 0x6e, 0x65, 0x72, 0x3b, 0x44, 0x65, 0x20, 0x53, 0x61, 0x64, 0x6f, 0x72, 0x6e, 0x3b, 0x4b, 0x3b, 0x44,
+0x3b, 0x42, 0x3b, 0x57, 0x3b, 0x59, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x4b, 0x77, 0x65, 0x3b, 0x44, 0x77, 0x6f, 0x3b, 0x42,
+0x65, 0x6e, 0x3b, 0x57, 0x75, 0x6b, 0x3b, 0x59, 0x61, 0x77, 0x3b, 0x46, 0x69, 0x61, 0x3b, 0x4d, 0x65, 0x6d, 0x3b, 0x4b,
+0x77, 0x65, 0x73, 0x69, 0x64, 0x61, 0x3b, 0x44, 0x77, 0x6f, 0x77, 0x64, 0x61, 0x3b, 0x42, 0x65, 0x6e, 0x61, 0x64, 0x61,
+0x3b, 0x57, 0x75, 0x6b, 0x75, 0x64, 0x61, 0x3b, 0x59, 0x61, 0x77, 0x64, 0x61, 0x3b, 0x46, 0x69, 0x64, 0x61, 0x3b, 0x4d,
+0x65, 0x6d, 0x65, 0x6e, 0x65, 0x64, 0x61, 0x3b, 0x906, 0x926, 0x93f, 0x924, 0x94d, 0x92f, 0x935, 0x93e, 0x930, 0x3b, 0x938, 0x94b,
+0x92e, 0x935, 0x93e, 0x930, 0x3b, 0x92e, 0x902, 0x917, 0x933, 0x93e, 0x930, 0x3b, 0x92c, 0x941, 0x927, 0x935, 0x93e, 0x930, 0x3b, 0x917,
+0x941, 0x930, 0x941, 0x935, 0x93e, 0x930, 0x3b, 0x936, 0x941, 0x915, 0x94d, 0x930, 0x935, 0x93e, 0x930, 0x3b, 0x936, 0x928, 0x93f, 0x935,
+0x93e, 0x930, 0x3b, 0x48, 0x6f, 0x3b, 0x44, 0x7a, 0x75, 0x3b, 0x44, 0x7a, 0x66, 0x3b, 0x53, 0x68, 0x6f, 0x3b, 0x53, 0x6f,
+0x6f, 0x3b, 0x53, 0x6f, 0x68, 0x3b, 0x48, 0x6f, 0x3b, 0x48, 0x6f, 0x67, 0x62, 0x61, 0x61, 0x3b, 0x44, 0x7a, 0x75, 0x3b,
+0x44, 0x7a, 0x75, 0x66, 0x6f, 0x3b, 0x53, 0x68, 0x6f, 0x3b, 0x53, 0x6f, 0x6f, 0x3b, 0x53, 0x6f, 0x68, 0x61, 0x61, 0x3b,
+0x48, 0x6f, 0x3b, 0x1ee4, 0x6b, 0x61, 0x3b, 0x4d, 0x1ecd, 0x6e, 0x3b, 0x54, 0x69, 0x75, 0x3b, 0x57, 0x65, 0x6e, 0x3b, 0x54,
+0x1ecd, 0x1ecd, 0x3b, 0x46, 0x72, 0x61, 0x1ecb, 0x3b, 0x53, 0x61, 0x74, 0x3b, 0x4d, 0x62, 0x1ecd, 0x73, 0x1ecb, 0x20, 0x1ee4, 0x6b,
+0x61, 0x3b, 0x4d, 0x1ecd, 0x6e, 0x64, 0x65, 0x3b, 0x54, 0x69, 0x75, 0x7a, 0x64, 0x65, 0x65, 0x3b, 0x57, 0x65, 0x6e, 0x65,
+0x7a, 0x64, 0x65, 0x65, 0x3b, 0x54, 0x1ecd, 0x1ecd, 0x7a, 0x64, 0x65, 0x65, 0x3b, 0x46, 0x72, 0x61, 0x1ecb, 0x64, 0x65, 0x65,
+0x3b, 0x53, 0x61, 0x74, 0x1ecd, 0x64, 0x65, 0x65, 0x3b, 0x4a, 0x70, 0x6c, 0x3b, 0x4a, 0x74, 0x74, 0x3b, 0x4a, 0x6e, 0x6e,
+0x3b, 0x4a, 0x74, 0x6e, 0x3b, 0x41, 0x6c, 0x68, 0x3b, 0x49, 0x6a, 0x6d, 0x3b, 0x4a, 0x6d, 0x73, 0x3b, 0x4a, 0x75, 0x6d,
+0x61, 0x70, 0x69, 0x6c, 0x69, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x74, 0x61, 0x74, 0x75, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x6e,
+0x6e, 0x65, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x74, 0x61, 0x6e, 0x6f, 0x3b, 0x41, 0x6c, 0x61, 0x6d, 0x69, 0x73, 0x69, 0x3b,
+0x49, 0x6a, 0x75, 0x6d, 0x61, 0x61, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x6d, 0x6f, 0x73, 0x69, 0x3b, 0x1230, 0x3b, 0x1230, 0x3b,
+0x1230, 0x3b, 0x1208, 0x3b, 0x12a3, 0x3b, 0x12a3, 0x3b, 0x1230, 0x3b, 0x1230, 0x2f, 0x1245, 0x3b, 0x1230, 0x1291, 0x3b, 0x1230, 0x120a, 0x131d,
+0x3b, 0x1208, 0x1313, 0x3b, 0x12a3, 0x121d, 0x12f5, 0x3b, 0x12a3, 0x122d, 0x1265, 0x3b, 0x1230, 0x2f, 0x123d, 0x3b, 0x1230, 0x1295, 0x1260, 0x122d,
+0x20, 0x1245, 0x12f3, 0x12c5, 0x3b, 0x1230, 0x1291, 0x3b, 0x1230, 0x120a, 0x131d, 0x3b, 0x1208, 0x1313, 0x20, 0x12c8, 0x122a, 0x20, 0x1208, 0x1265,
+0x12cb, 0x3b, 0x12a3, 0x121d, 0x12f5, 0x3b, 0x12a3, 0x122d, 0x1265, 0x3b, 0x1230, 0x1295, 0x1260, 0x122d, 0x20, 0x123d, 0x1313, 0x12c5, 0x3b, 0x12a5,
+0x3b, 0x1230, 0x3b, 0x1220, 0x3b, 0x122b, 0x3b, 0x1210, 0x3b, 0x12d3, 0x3b, 0x1240, 0x3b, 0x12a5, 0x1281, 0x12f5, 0x3b, 0x1230, 0x1291, 0x12ed,
+0x3b, 0x1220, 0x1209, 0x1235, 0x3b, 0x122b, 0x1265, 0x12d5, 0x3b, 0x1210, 0x1219, 0x1235, 0x3b, 0x12d3, 0x122d, 0x1260, 0x3b, 0x1240, 0x12f3, 0x121a,
+0x3b, 0x12a5, 0x1281, 0x12f5, 0x3b, 0x1230, 0x1291, 0x12ed, 0x3b, 0x1220, 0x1209, 0x1235, 0x3b, 0x122b, 0x1265, 0x12d5, 0x3b, 0x1210, 0x1219, 0x1235,
+0x3b, 0x12d3, 0x122d, 0x1260, 0x3b, 0x1240, 0x12f3, 0x121a, 0x1275, 0x3b, 0x4c, 0x61, 0x68, 0x3b, 0x4b, 0x75, 0x62, 0x3b, 0x47, 0x62,
+0x61, 0x3b, 0x54, 0x61, 0x6e, 0x3b, 0x59, 0x65, 0x69, 0x3b, 0x4b, 0x6f, 0x79, 0x3b, 0x53, 0x61, 0x74, 0x3b, 0x4c, 0x61,
+0x68, 0x61, 0x64, 0x69, 0x3b, 0x4a, 0x65, 0x2d, 0x4b, 0x75, 0x62, 0x61, 0x63, 0x68, 0x61, 0x3b, 0x4a, 0x65, 0x2d, 0x47,
+0x62, 0x61, 0x69, 0x3b, 0x54, 0x61, 0x6e, 0x73, 0x61, 0x74, 0x69, 0x3b, 0x4a, 0x65, 0x2d, 0x59, 0x65, 0x69, 0x3b, 0x4a,
+0x65, 0x2d, 0x4b, 0x6f, 0x79, 0x65, 0x3b, 0x53, 0x61, 0x74, 0x69, 0x3b, 0x53, 0x3b, 0x53, 0x3b, 0x4d, 0x3b, 0x52, 0x3b,
+0x48, 0x3b, 0x41, 0x3b, 0x51, 0x3b, 0x53, 0x61, 0x6d, 0x3b, 0x53, 0x61, 0x6e, 0x3b, 0x4d, 0x61, 0x6b, 0x3b, 0x52, 0x6f,
+0x77, 0x3b, 0x48, 0x61, 0x6d, 0x3b, 0x41, 0x72, 0x62, 0x3b, 0x51, 0x69, 0x64, 0x3b, 0x53, 0x61, 0x6d, 0x62, 0x61, 0x74,
+0x61, 0x3b, 0x53, 0x61, 0x6e, 0x79, 0x6f, 0x3b, 0x4d, 0x61, 0x61, 0x6b, 0x69, 0x73, 0x61, 0x6e, 0x79, 0x6f, 0x3b, 0x52,
+0x6f, 0x6f, 0x77, 0x65, 0x3b, 0x48, 0x61, 0x6d, 0x75, 0x73, 0x65, 0x3b, 0x41, 0x72, 0x62, 0x65, 0x3b, 0x51, 0x69, 0x64,
+0x61, 0x61, 0x6d, 0x65, 0x3b, 0x59, 0x6f, 0x6b, 0x3b, 0x54, 0x75, 0x6e, 0x67, 0x3b, 0x54, 0x2e, 0x20, 0x54, 0x75, 0x6e,
+0x67, 0x3b, 0x54, 0x73, 0x61, 0x6e, 0x3b, 0x4e, 0x61, 0x73, 0x3b, 0x4e, 0x61, 0x74, 0x3b, 0x43, 0x68, 0x69, 0x72, 0x3b,
+0x57, 0x61, 0x69, 0x20, 0x59, 0x6f, 0x6b, 0x61, 0x20, 0x42, 0x61, 0x77, 0x61, 0x69, 0x3b, 0x57, 0x61, 0x69, 0x20, 0x54,
+0x75, 0x6e, 0x67, 0x61, 0x3b, 0x54, 0x6f, 0x6b, 0x69, 0x20, 0x47, 0x69, 0x74, 0x75, 0x6e, 0x67, 0x3b, 0x54, 0x73, 0x61,
+0x6d, 0x20, 0x4b, 0x61, 0x73, 0x75, 0x77, 0x61, 0x3b, 0x57, 0x61, 0x69, 0x20, 0x4e, 0x61, 0x20, 0x4e, 0x61, 0x73, 0x3b,
+0x57, 0x61, 0x69, 0x20, 0x4e, 0x61, 0x20, 0x54, 0x69, 0x79, 0x6f, 0x6e, 0x3b, 0x57, 0x61, 0x69, 0x20, 0x4e, 0x61, 0x20,
+0x43, 0x68, 0x69, 0x72, 0x69, 0x6d, 0x3b, 0x1230, 0x3b, 0x1230, 0x3b, 0x1273, 0x3b, 0x12a3, 0x3b, 0x12a8, 0x3b, 0x1305, 0x3b, 0x1230,
+0x3b, 0x1230, 0x2f, 0x12d3, 0x3b, 0x1230, 0x1296, 0x3b, 0x1273, 0x120b, 0x1238, 0x3b, 0x12a3, 0x1228, 0x122d, 0x3b, 0x12a8, 0x121a, 0x123d, 0x3b,
+0x1305, 0x121d, 0x12d3, 0x3b, 0x1230, 0x2f, 0x1295, 0x3b, 0x1230, 0x1295, 0x1260, 0x1275, 0x20, 0x12d3, 0x1263, 0x12ed, 0x3b, 0x1230, 0x1296, 0x3b,
+0x1273, 0x120b, 0x1238, 0x1296, 0x3b, 0x12a3, 0x1228, 0x122d, 0x1263, 0x12d3, 0x3b, 0x12a8, 0x121a, 0x123d, 0x3b, 0x1305, 0x121d, 0x12d3, 0x1275, 0x3b,
+0x1230, 0x1295, 0x1260, 0x1275, 0x20, 0x1295, 0x12a2, 0x123d, 0x3b, 0x4c, 0x61, 0x64, 0x3b, 0x4c, 0x69, 0x6e, 0x3b, 0x54, 0x61, 0x6c,
+0x3b, 0x4c, 0x61, 0x72, 0x3b, 0x4c, 0x61, 0x6d, 0x3b, 0x4a, 0x75, 0x6d, 0x3b, 0x41, 0x73, 0x61, 0x3b, 0x4c, 0x61, 0x64,
+0x69, 0x3b, 0x4c, 0x69, 0x6e, 0x74, 0x61, 0x6e, 0x69, 0x3b, 0x54, 0x61, 0x6c, 0x61, 0x74, 0x61, 0x3b, 0x4c, 0x61, 0x72,
+0x62, 0x61, 0x3b, 0x4c, 0x61, 0x6d, 0x69, 0x74, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x3b, 0x41, 0x73, 0x61, 0x62, 0x61, 0x72,
+0x3b, 0x64, 0x6f, 0x6d, 0x3b, 0x6c, 0x75, 0x6e, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x6d, 0x69, 0x65, 0x3b, 0x6a, 0x6f, 0x69,
+0x3b, 0x76, 0x69, 0x6e, 0x3b, 0x73, 0x61, 0x62, 0x3b, 0x64, 0x6f, 0x6d, 0x65, 0x6e, 0x69, 0x65, 0x3b, 0x6c, 0x75, 0x6e,
+0x69, 0x73, 0x3b, 0x6d, 0x61, 0x72, 0x74, 0x61, 0x72, 0x73, 0x3b, 0x6d, 0x69, 0x65, 0x72, 0x63, 0x75, 0x73, 0x3b, 0x6a,
+0x6f, 0x69, 0x62, 0x65, 0x3b, 0x76, 0x69, 0x6e, 0x61, 0x72, 0x73, 0x3b, 0x73, 0x61, 0x62, 0x69, 0x64, 0x65, 0x3b, 0x53,
+0x77, 0x6f, 0x3b, 0x4d, 0x75, 0x73, 0x3b, 0x56, 0x68, 0x69, 0x3b, 0x52, 0x61, 0x72, 0x3b, 0x1e4a, 0x61, 0x3b, 0x1e70, 0x61,
+0x6e, 0x3b, 0x4d, 0x75, 0x67, 0x3b, 0x53, 0x77, 0x6f, 0x6e, 0x64, 0x61, 0x68, 0x61, 0x3b, 0x4d, 0x75, 0x73, 0x75, 0x6d,
+0x62, 0x75, 0x6c, 0x75, 0x77, 0x6f, 0x3b, 0x1e3c, 0x61, 0x76, 0x68, 0x75, 0x76, 0x68, 0x69, 0x6c, 0x69, 0x3b, 0x1e3c, 0x61,
+0x76, 0x68, 0x75, 0x72, 0x61, 0x72, 0x75, 0x3b, 0x1e3c, 0x61, 0x76, 0x68, 0x75, 0x1e4b, 0x61, 0x3b, 0x1e3c, 0x61, 0x76, 0x68,
+0x75, 0x1e71, 0x61, 0x6e, 0x75, 0x3b, 0x4d, 0x75, 0x67, 0x69, 0x76, 0x68, 0x65, 0x6c, 0x61, 0x3b, 0x4b, 0x3b, 0x44, 0x3b,
+0x42, 0x3b, 0x4b, 0x3b, 0x59, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x4b, 0x254, 0x73, 0x20, 0x4b, 0x77, 0x65, 0x3b, 0x44, 0x7a,
+0x6f, 0x3b, 0x42, 0x72, 0x61, 0x3b, 0x4b, 0x75, 0x256, 0x3b, 0x59, 0x61, 0x77, 0x3b, 0x46, 0x69, 0x256, 0x3b, 0x4d, 0x65,
+0x6d, 0x3b, 0x4b, 0x254, 0x73, 0x69, 0x256, 0x61, 0x3b, 0x44, 0x7a, 0x6f, 0x256, 0x61, 0x3b, 0x42, 0x72, 0x61, 0x256, 0x61,
+0x3b, 0x4b, 0x75, 0x256, 0x61, 0x3b, 0x59, 0x61, 0x77, 0x6f, 0x256, 0x61, 0x3b, 0x46, 0x69, 0x256, 0x61, 0x3b, 0x4d, 0x65,
+0x6d, 0x6c, 0x65, 0x256, 0x61, 0x3b, 0x4c, 0x50, 0x3b, 0x50, 0x31, 0x3b, 0x50, 0x32, 0x3b, 0x50, 0x33, 0x3b, 0x50, 0x34,
+0x3b, 0x50, 0x35, 0x3b, 0x50, 0x36, 0x3b, 0x4c, 0x101, 0x70, 0x75, 0x6c, 0x65, 0x3b, 0x50, 0x6f, 0x2bb, 0x61, 0x6b, 0x61,
+0x68, 0x69, 0x3b, 0x50, 0x6f, 0x2bb, 0x61, 0x6c, 0x75, 0x61, 0x3b, 0x50, 0x6f, 0x2bb, 0x61, 0x6b, 0x6f, 0x6c, 0x75, 0x3b,
+0x50, 0x6f, 0x2bb, 0x61, 0x68, 0x101, 0x3b, 0x50, 0x6f, 0x2bb, 0x61, 0x6c, 0x69, 0x6d, 0x61, 0x3b, 0x50, 0x6f, 0x2bb, 0x61,
+0x6f, 0x6e, 0x6f, 0x3b, 0x4c, 0x61, 0x64, 0x3b, 0x54, 0x61, 0x6e, 0x3b, 0x54, 0x61, 0x6c, 0x3b, 0x4c, 0x61, 0x72, 0x3b,
+0x4c, 0x61, 0x6d, 0x3b, 0x4a, 0x75, 0x6d, 0x3b, 0x41, 0x73, 0x61, 0x3b, 0x4c, 0x61, 0x64, 0x69, 0x3b, 0x54, 0x61, 0x6e,
+0x69, 0x69, 0x3b, 0x54, 0x61, 0x6c, 0x61, 0x74, 0x61, 0x3b, 0x4c, 0x61, 0x72, 0x62, 0x61, 0x3b, 0x4c, 0x61, 0x6d, 0x69,
+0x74, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x3b, 0x41, 0x73, 0x61, 0x62, 0x61, 0x74, 0x3b, 0x4d, 0x75, 0x6c, 0x3b, 0x4c, 0x65,
+0x6d, 0x3b, 0x57, 0x69, 0x72, 0x3b, 0x54, 0x61, 0x74, 0x3b, 0x4e, 0x61, 0x69, 0x3b, 0x53, 0x61, 0x6e, 0x3b, 0x57, 0x65,
+0x72, 0x3b, 0x4c, 0x61, 0x6d, 0x75, 0x6c, 0x75, 0x6e, 0x67, 0x75, 0x3b, 0x4c, 0x6f, 0x6c, 0x65, 0x6d, 0x62, 0x61, 0x3b,
+0x4c, 0x61, 0x63, 0x68, 0x69, 0x77, 0x69, 0x72, 0x69, 0x3b, 0x4c, 0x61, 0x63, 0x68, 0x69, 0x74, 0x61, 0x74, 0x75, 0x3b,
+0x4c, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x61, 0x79, 0x69, 0x3b, 0x4c, 0x61, 0x63, 0x68, 0x69, 0x73, 0x61, 0x6e, 0x75, 0x3b,
+0x4c, 0x6f, 0x77, 0x65, 0x72, 0x75, 0x6b, 0x61, 0x3b
+};
+
+static const ushort am_data[] = {
+0x41, 0x4d, 0x76, 0x6d, 0x2e, 0x50, 0x44, 0x635, 0x531, 0x57c, 0x2024, 0x9aa, 0x9c2, 0x9f0, 0x9cd, 0x9ac, 0x9be, 0x9aa, 0x9c2, 0x9b0,
+0x9cd, 0x9ac, 0x9be, 0x9b9, 0x9cd, 0x9a3, 0x43f, 0x440, 0x2e, 0x20, 0x43e, 0x431, 0x2e, 0x434, 0x430, 0x20, 0x43f, 0x430, 0x43b, 0x443,
+0x434, 0x43d, 0x44f, 0x1796, 0x17d2, 0x179a, 0x17b9, 0x1780, 0x4e0a, 0x5348, 0x64, 0x6f, 0x70, 0x2e, 0x66, 0x2e, 0x6d, 0x2e, 0x61, 0x2e,
+0x6d, 0x2e, 0x61, 0x70, 0x2e, 0x76, 0x6f, 0x72, 0x6d, 0x2e, 0x3c0, 0x2e, 0x3bc, 0x2e, 0xaaa, 0xac2, 0xab0, 0xacd, 0xab5, 0xa0,
+0xaae, 0xaa7, 0xacd, 0xaaf, 0xabe, 0xab9, 0xacd, 0xaa8, 0x5dc, 0x5e4, 0x5e0, 0x5d4, 0x22, 0x5e6, 0x92a, 0x942, 0x930, 0x94d, 0x935, 0x93e,
+0x939, 0x94d, 0x928, 0x64, 0x65, 0x2e, 0x6d, 0x2e, 0x5348, 0x524d, 0xcaa, 0xcc2, 0xcb0, 0xccd, 0xcb5, 0xcbe, 0xcb9, 0xccd, 0xca8, 0xc624,
+0xc804, 0x70, 0x72, 0x69, 0x65, 0x161, 0x70, 0x69, 0x65, 0x74, 0x51, 0x4e, 0x92e, 0x2e, 0x92a, 0x942, 0x2e, 0x66, 0x6f, 0x72,
+0x6d, 0x69, 0x64, 0x64, 0x61, 0x67, 0x63a, 0x2e, 0x645, 0x2e, 0x642, 0x628, 0x644, 0x20, 0x627, 0x632, 0x20, 0x638, 0x647, 0x631,
+0x41, 0x6e, 0x74, 0x65, 0x73, 0x20, 0x64, 0x6f, 0x20, 0x6d, 0x65, 0x69, 0x6f, 0x2d, 0x64, 0x69, 0x61, 0xa38, 0xa35, 0xa47,
+0xa30, 0xa47, 0x43f, 0x440, 0x435, 0x43f, 0x43e, 0x434, 0x43d, 0x435, 0xdb4, 0xdd9, 0x2e, 0xdc0, 0x2e, 0x73, 0x6e, 0x66, 0x6d, 0xb95,
+0xbbe, 0xbb2, 0xbc8, 0xc2a, 0xc42, 0xc30, 0xc4d, 0xc35, 0xc3e, 0xc39, 0xc4d, 0xc28, 0xc02, 0xe01, 0xe48, 0xe2d, 0xe19, 0xe40, 0xe17, 0xe35,
+0xe48, 0xe22, 0xe07, 0x1295, 0x1309, 0x1206, 0x20, 0x1230, 0x12d3, 0x1270, 0x434, 0x43f, 0x53, 0x41, 0xe0, 0xe1, 0x72, 0x1ecd, 0x300
+};
+
+static const ushort pm_data[] = {
+0x50, 0x4d, 0x6e, 0x6d, 0x2e, 0x4d, 0x44, 0x645, 0x535, 0x580, 0x2024, 0x985, 0x9aa, 0x985, 0x9aa, 0x9b0, 0x9be, 0x9b9, 0x9cd, 0x9a3,
+0x441, 0x43b, 0x2e, 0x20, 0x43e, 0x431, 0x2e, 0x43f, 0x430, 0x441, 0x43b, 0x44f, 0x20, 0x43f, 0x430, 0x43b, 0x443, 0x434, 0x43d, 0x44f,
+0x179b, 0x17d2, 0x1784, 0x17b6, 0x1785, 0x4e0b, 0x5348, 0x6f, 0x64, 0x70, 0x2e, 0x65, 0x2e, 0x6d, 0x2e, 0x70, 0x2e, 0x6d, 0x2e, 0x69,
+0x70, 0x2e, 0x6e, 0x61, 0x63, 0x68, 0x6d, 0x2e, 0x3bc, 0x2e, 0x3bc, 0x2e, 0xa89, 0xaa4, 0xacd, 0xaa4, 0xab0, 0xa0, 0xaae, 0xaa7,
+0xacd, 0xaaf, 0xabe, 0xab9, 0xacd, 0xaa8, 0x5d0, 0x5d7, 0x5d4, 0x22, 0x5e6, 0x905, 0x92a, 0x930, 0x93e, 0x939, 0x94d, 0x928, 0x64, 0x75,
+0x2e, 0x70, 0x2e, 0x5348, 0x5f8c, 0xc85, 0xcaa, 0xcb0, 0xcbe, 0xcb9, 0xccd, 0xca8, 0xc624, 0xd6c4, 0x70, 0x6f, 0x70, 0x69, 0x65, 0x74,
+0x57, 0x4e, 0x92e, 0x2e, 0x928, 0x902, 0x2e, 0x65, 0x74, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x64, 0x64, 0x61, 0x67, 0x63a, 0x2e,
+0x648, 0x2e, 0x628, 0x639, 0x62f, 0x20, 0x627, 0x632, 0x20, 0x638, 0x647, 0x631, 0x44, 0x65, 0x70, 0x6f, 0x69, 0x73, 0x20, 0x64,
+0x6f, 0x20, 0x6d, 0x65, 0x69, 0x6f, 0x2d, 0x64, 0x69, 0x61, 0xa38, 0xa3c, 0xa3e, 0xa2e, 0x43f, 0x43e, 0x43f, 0x43e, 0x434, 0x43d,
+0x435, 0xdb4, 0x2e, 0xdc0, 0x2e, 0x67, 0x6e, 0x65, 0x6d, 0xbae, 0xbbe, 0xbb2, 0xbc8, 0xc05, 0xc2a, 0xc30, 0xc3e, 0xc39, 0xc4d, 0xc28,
+0xc02, 0xe2b, 0xe25, 0xe31, 0xe07, 0xe40, 0xe17, 0xe35, 0xe48, 0xe22, 0xe07, 0x12f5, 0x1215, 0x122d, 0x20, 0x1230, 0x12d3, 0x1275, 0x43f, 0x43f,
+0x43, 0x48, 0x1ecd, 0x300, 0x73, 0xe1, 0x6e
+};
+
+static const char language_name_list[] =
+"Default\0"
+"C\0"
+"Abkhazian\0"
+"Afan\0"
+"Afar\0"
+"Afrikaans\0"
+"Albanian\0"
+"Amharic\0"
+"Arabic\0"
+"Armenian\0"
+"Assamese\0"
+"Aymara\0"
+"Azerbaijani\0"
+"Bashkir\0"
+"Basque\0"
+"Bengali\0"
+"Bhutani\0"
+"Bihari\0"
+"Bislama\0"
+"Breton\0"
+"Bulgarian\0"
+"Burmese\0"
+"Byelorussian\0"
+"Cambodian\0"
+"Catalan\0"
+"Chinese\0"
+"Corsican\0"
+"Croatian\0"
+"Czech\0"
+"Danish\0"
+"Dutch\0"
+"English\0"
+"Esperanto\0"
+"Estonian\0"
+"Faroese\0"
+"Fiji\0"
+"Finnish\0"
+"French\0"
+"Frisian\0"
+"Gaelic\0"
+"Galician\0"
+"Georgian\0"
+"German\0"
+"Greek\0"
+"Greenlandic\0"
+"Guarani\0"
+"Gujarati\0"
+"Hausa\0"
+"Hebrew\0"
+"Hindi\0"
+"Hungarian\0"
+"Icelandic\0"
+"Indonesian\0"
+"Interlingua\0"
+"Interlingue\0"
+"Inuktitut\0"
+"Inupiak\0"
+"Irish\0"
+"Italian\0"
+"Japanese\0"
+"Javanese\0"
+"Kannada\0"
+"Kashmiri\0"
+"Kazakh\0"
+"Kinyarwanda\0"
+"Kirghiz\0"
+"Korean\0"
+"Kurdish\0"
+"Kurundi\0"
+"Laothian\0"
+"Latin\0"
+"Latvian\0"
+"Lingala\0"
+"Lithuanian\0"
+"Macedonian\0"
+"Malagasy\0"
+"Malay\0"
+"Malayalam\0"
+"Maltese\0"
+"Maori\0"
+"Marathi\0"
+"Moldavian\0"
+"Mongolian\0"
+"Nauru\0"
+"Nepali\0"
+"Norwegian\0"
+"Occitan\0"
+"Oriya\0"
+"Pashto\0"
+"Persian\0"
+"Polish\0"
+"Portuguese\0"
+"Punjabi\0"
+"Quechua\0"
+"RhaetoRomance\0"
+"Romanian\0"
+"Russian\0"
+"Samoan\0"
+"Sangho\0"
+"Sanskrit\0"
+"Serbian\0"
+"SerboCroatian\0"
+"Sesotho\0"
+"Setswana\0"
+"Shona\0"
+"Sindhi\0"
+"Singhalese\0"
+"Siswati\0"
+"Slovak\0"
+"Slovenian\0"
+"Somali\0"
+"Spanish\0"
+"Sundanese\0"
+"Swahili\0"
+"Swedish\0"
+"Tagalog\0"
+"Tajik\0"
+"Tamil\0"
+"Tatar\0"
+"Telugu\0"
+"Thai\0"
+"Tibetan\0"
+"Tigrinya\0"
+"Tonga\0"
+"Tsonga\0"
+"Turkish\0"
+"Turkmen\0"
+"Twi\0"
+"Uigur\0"
+"Ukrainian\0"
+"Urdu\0"
+"Uzbek\0"
+"Vietnamese\0"
+"Volapuk\0"
+"Welsh\0"
+"Wolof\0"
+"Xhosa\0"
+"Yiddish\0"
+"Yoruba\0"
+"Zhuang\0"
+"Zulu\0"
+"Nynorsk\0"
+"Bosnian\0"
+"Divehi\0"
+"Manx\0"
+"Cornish\0"
+"Akan\0"
+"Konkani\0"
+"Ga\0"
+"Igbo\0"
+"Kamba\0"
+"Syriac\0"
+"Blin\0"
+"Geez\0"
+"Koro\0"
+"Sidamo\0"
+"Atsam\0"
+"Tigre\0"
+"Jju\0"
+"Friulian\0"
+"Venda\0"
+"Ewe\0"
+"Walamo\0"
+"Hawaiian\0"
+"Tyap\0"
+"Chewa\0"
+;
+
+static const uint language_name_index[] = {
+ 0, // Unused
+ 8, // C
+ 10, // Abkhazian
+ 20, // Afan
+ 25, // Afar
+ 30, // Afrikaans
+ 40, // Albanian
+ 49, // Amharic
+ 57, // Arabic
+ 64, // Armenian
+ 73, // Assamese
+ 82, // Aymara
+ 89, // Azerbaijani
+ 101, // Bashkir
+ 109, // Basque
+ 116, // Bengali
+ 124, // Bhutani
+ 132, // Bihari
+ 139, // Bislama
+ 147, // Breton
+ 154, // Bulgarian
+ 164, // Burmese
+ 172, // Byelorussian
+ 185, // Cambodian
+ 195, // Catalan
+ 203, // Chinese
+ 211, // Corsican
+ 220, // Croatian
+ 229, // Czech
+ 235, // Danish
+ 242, // Dutch
+ 248, // English
+ 256, // Esperanto
+ 266, // Estonian
+ 275, // Faroese
+ 283, // Fiji
+ 288, // Finnish
+ 296, // French
+ 303, // Frisian
+ 311, // Gaelic
+ 318, // Galician
+ 327, // Georgian
+ 336, // German
+ 343, // Greek
+ 349, // Greenlandic
+ 361, // Guarani
+ 369, // Gujarati
+ 378, // Hausa
+ 384, // Hebrew
+ 391, // Hindi
+ 397, // Hungarian
+ 407, // Icelandic
+ 417, // Indonesian
+ 428, // Interlingua
+ 440, // Interlingue
+ 452, // Inuktitut
+ 462, // Inupiak
+ 470, // Irish
+ 476, // Italian
+ 484, // Japanese
+ 493, // Javanese
+ 502, // Kannada
+ 510, // Kashmiri
+ 519, // Kazakh
+ 526, // Kinyarwanda
+ 538, // Kirghiz
+ 546, // Korean
+ 553, // Kurdish
+ 561, // Kurundi
+ 569, // Laothian
+ 578, // Latin
+ 584, // Latvian
+ 592, // Lingala
+ 600, // Lithuanian
+ 611, // Macedonian
+ 622, // Malagasy
+ 631, // Malay
+ 637, // Malayalam
+ 647, // Maltese
+ 655, // Maori
+ 661, // Marathi
+ 669, // Moldavian
+ 679, // Mongolian
+ 689, // Nauru
+ 695, // Nepali
+ 702, // Norwegian
+ 712, // Occitan
+ 720, // Oriya
+ 726, // Pashto
+ 733, // Persian
+ 741, // Polish
+ 748, // Portuguese
+ 759, // Punjabi
+ 767, // Quechua
+ 775, // RhaetoRomance
+ 789, // Romanian
+ 798, // Russian
+ 806, // Samoan
+ 813, // Sangho
+ 820, // Sanskrit
+ 829, // Serbian
+ 837, // SerboCroatian
+ 851, // Sesotho
+ 859, // Setswana
+ 868, // Shona
+ 874, // Sindhi
+ 881, // Singhalese
+ 892, // Siswati
+ 900, // Slovak
+ 907, // Slovenian
+ 917, // Somali
+ 924, // Spanish
+ 932, // Sundanese
+ 942, // Swahili
+ 950, // Swedish
+ 958, // Tagalog
+ 966, // Tajik
+ 972, // Tamil
+ 978, // Tatar
+ 984, // Telugu
+ 991, // Thai
+ 996, // Tibetan
+ 1004, // Tigrinya
+ 1013, // Tonga
+ 1019, // Tsonga
+ 1026, // Turkish
+ 1034, // Turkmen
+ 1042, // Twi
+ 1046, // Uigur
+ 1052, // Ukrainian
+ 1062, // Urdu
+ 1067, // Uzbek
+ 1073, // Vietnamese
+ 1084, // Volapuk
+ 1092, // Welsh
+ 1098, // Wolof
+ 1104, // Xhosa
+ 1110, // Yiddish
+ 1118, // Yoruba
+ 1125, // Zhuang
+ 1132, // Zulu
+ 1137, // Nynorsk
+ 1145, // Bosnian
+ 1153, // Divehi
+ 1160, // Manx
+ 1165, // Cornish
+ 1173, // Akan
+ 1178, // Konkani
+ 1186, // Ga
+ 1189, // Igbo
+ 1194, // Kamba
+ 1200, // Syriac
+ 1207, // Blin
+ 1212, // Geez
+ 1217, // Koro
+ 1222, // Sidamo
+ 1229, // Atsam
+ 1235, // Tigre
+ 1241, // Jju
+ 1245, // Friulian
+ 1254, // Venda
+ 1260, // Ewe
+ 1264, // Walamo
+ 1271, // Hawaiian
+ 1280, // Tyap
+ 1285, // Chewa
+};
+
+static const char country_name_list[] =
+"Default\0"
+"Afghanistan\0"
+"Albania\0"
+"Algeria\0"
+"AmericanSamoa\0"
+"Andorra\0"
+"Angola\0"
+"Anguilla\0"
+"Antarctica\0"
+"AntiguaAndBarbuda\0"
+"Argentina\0"
+"Armenia\0"
+"Aruba\0"
+"Australia\0"
+"Austria\0"
+"Azerbaijan\0"
+"Bahamas\0"
+"Bahrain\0"
+"Bangladesh\0"
+"Barbados\0"
+"Belarus\0"
+"Belgium\0"
+"Belize\0"
+"Benin\0"
+"Bermuda\0"
+"Bhutan\0"
+"Bolivia\0"
+"BosniaAndHerzegowina\0"
+"Botswana\0"
+"BouvetIsland\0"
+"Brazil\0"
+"BritishIndianOceanTerritory\0"
+"BruneiDarussalam\0"
+"Bulgaria\0"
+"BurkinaFaso\0"
+"Burundi\0"
+"Cambodia\0"
+"Cameroon\0"
+"Canada\0"
+"CapeVerde\0"
+"CaymanIslands\0"
+"CentralAfricanRepublic\0"
+"Chad\0"
+"Chile\0"
+"China\0"
+"ChristmasIsland\0"
+"CocosIslands\0"
+"Colombia\0"
+"Comoros\0"
+"DemocraticRepublicOfCongo\0"
+"PeoplesRepublicOfCongo\0"
+"CookIslands\0"
+"CostaRica\0"
+"IvoryCoast\0"
+"Croatia\0"
+"Cuba\0"
+"Cyprus\0"
+"CzechRepublic\0"
+"Denmark\0"
+"Djibouti\0"
+"Dominica\0"
+"DominicanRepublic\0"
+"EastTimor\0"
+"Ecuador\0"
+"Egypt\0"
+"ElSalvador\0"
+"EquatorialGuinea\0"
+"Eritrea\0"
+"Estonia\0"
+"Ethiopia\0"
+"FalklandIslands\0"
+"FaroeIslands\0"
+"Fiji\0"
+"Finland\0"
+"France\0"
+"MetropolitanFrance\0"
+"FrenchGuiana\0"
+"FrenchPolynesia\0"
+"FrenchSouthernTerritories\0"
+"Gabon\0"
+"Gambia\0"
+"Georgia\0"
+"Germany\0"
+"Ghana\0"
+"Gibraltar\0"
+"Greece\0"
+"Greenland\0"
+"Grenada\0"
+"Guadeloupe\0"
+"Guam\0"
+"Guatemala\0"
+"Guinea\0"
+"GuineaBissau\0"
+"Guyana\0"
+"Haiti\0"
+"HeardAndMcDonaldIslands\0"
+"Honduras\0"
+"HongKong\0"
+"Hungary\0"
+"Iceland\0"
+"India\0"
+"Indonesia\0"
+"Iran\0"
+"Iraq\0"
+"Ireland\0"
+"Israel\0"
+"Italy\0"
+"Jamaica\0"
+"Japan\0"
+"Jordan\0"
+"Kazakhstan\0"
+"Kenya\0"
+"Kiribati\0"
+"DemocraticRepublicOfKorea\0"
+"RepublicOfKorea\0"
+"Kuwait\0"
+"Kyrgyzstan\0"
+"Lao\0"
+"Latvia\0"
+"Lebanon\0"
+"Lesotho\0"
+"Liberia\0"
+"LibyanArabJamahiriya\0"
+"Liechtenstein\0"
+"Lithuania\0"
+"Luxembourg\0"
+"Macau\0"
+"Macedonia\0"
+"Madagascar\0"
+"Malawi\0"
+"Malaysia\0"
+"Maldives\0"
+"Mali\0"
+"Malta\0"
+"MarshallIslands\0"
+"Martinique\0"
+"Mauritania\0"
+"Mauritius\0"
+"Mayotte\0"
+"Mexico\0"
+"Micronesia\0"
+"Moldova\0"
+"Monaco\0"
+"Mongolia\0"
+"Montserrat\0"
+"Morocco\0"
+"Mozambique\0"
+"Myanmar\0"
+"Namibia\0"
+"Nauru\0"
+"Nepal\0"
+"Netherlands\0"
+"NetherlandsAntilles\0"
+"NewCaledonia\0"
+"NewZealand\0"
+"Nicaragua\0"
+"Niger\0"
+"Nigeria\0"
+"Niue\0"
+"NorfolkIsland\0"
+"NorthernMarianaIslands\0"
+"Norway\0"
+"Oman\0"
+"Pakistan\0"
+"Palau\0"
+"PalestinianTerritory\0"
+"Panama\0"
+"PapuaNewGuinea\0"
+"Paraguay\0"
+"Peru\0"
+"Philippines\0"
+"Pitcairn\0"
+"Poland\0"
+"Portugal\0"
+"PuertoRico\0"
+"Qatar\0"
+"Reunion\0"
+"Romania\0"
+"RussianFederation\0"
+"Rwanda\0"
+"SaintKittsAndNevis\0"
+"StLucia\0"
+"StVincentAndTheGrenadines\0"
+"Samoa\0"
+"SanMarino\0"
+"SaoTomeAndPrincipe\0"
+"SaudiArabia\0"
+"Senegal\0"
+"Seychelles\0"
+"SierraLeone\0"
+"Singapore\0"
+"Slovakia\0"
+"Slovenia\0"
+"SolomonIslands\0"
+"Somalia\0"
+"SouthAfrica\0"
+"SouthGeorgiaAndTheSouthSandwichIslands\0"
+"Spain\0"
+"SriLanka\0"
+"StHelena\0"
+"StPierreAndMiquelon\0"
+"Sudan\0"
+"Suriname\0"
+"SvalbardAndJanMayenIslands\0"
+"Swaziland\0"
+"Sweden\0"
+"Switzerland\0"
+"SyrianArabRepublic\0"
+"Taiwan\0"
+"Tajikistan\0"
+"Tanzania\0"
+"Thailand\0"
+"Togo\0"
+"Tokelau\0"
+"Tonga\0"
+"TrinidadAndTobago\0"
+"Tunisia\0"
+"Turkey\0"
+"Turkmenistan\0"
+"TurksAndCaicosIslands\0"
+"Tuvalu\0"
+"Uganda\0"
+"Ukraine\0"
+"UnitedArabEmirates\0"
+"UnitedKingdom\0"
+"UnitedStates\0"
+"UnitedStatesMinorOutlyingIslands\0"
+"Uruguay\0"
+"Uzbekistan\0"
+"Vanuatu\0"
+"VaticanCityState\0"
+"Venezuela\0"
+"VietNam\0"
+"BritishVirginIslands\0"
+"USVirginIslands\0"
+"WallisAndFutunaIslands\0"
+"WesternSahara\0"
+"Yemen\0"
+"Yugoslavia\0"
+"Zambia\0"
+"Zimbabwe\0"
+"SerbiaAndMontenegro\0"
+;
+
+static const uint country_name_index[] = {
+ 0, // AnyCountry
+ 8, // Afghanistan
+ 20, // Albania
+ 28, // Algeria
+ 36, // AmericanSamoa
+ 50, // Andorra
+ 58, // Angola
+ 65, // Anguilla
+ 74, // Antarctica
+ 85, // AntiguaAndBarbuda
+ 103, // Argentina
+ 113, // Armenia
+ 121, // Aruba
+ 127, // Australia
+ 137, // Austria
+ 145, // Azerbaijan
+ 156, // Bahamas
+ 164, // Bahrain
+ 172, // Bangladesh
+ 183, // Barbados
+ 192, // Belarus
+ 200, // Belgium
+ 208, // Belize
+ 215, // Benin
+ 221, // Bermuda
+ 229, // Bhutan
+ 236, // Bolivia
+ 244, // BosniaAndHerzegowina
+ 265, // Botswana
+ 274, // BouvetIsland
+ 287, // Brazil
+ 294, // BritishIndianOceanTerritory
+ 322, // BruneiDarussalam
+ 339, // Bulgaria
+ 348, // BurkinaFaso
+ 360, // Burundi
+ 368, // Cambodia
+ 377, // Cameroon
+ 386, // Canada
+ 393, // CapeVerde
+ 403, // CaymanIslands
+ 417, // CentralAfricanRepublic
+ 440, // Chad
+ 445, // Chile
+ 451, // China
+ 457, // ChristmasIsland
+ 473, // CocosIslands
+ 486, // Colombia
+ 495, // Comoros
+ 503, // DemocraticRepublicOfCongo
+ 529, // PeoplesRepublicOfCongo
+ 552, // CookIslands
+ 564, // CostaRica
+ 574, // IvoryCoast
+ 585, // Croatia
+ 593, // Cuba
+ 598, // Cyprus
+ 605, // CzechRepublic
+ 619, // Denmark
+ 627, // Djibouti
+ 636, // Dominica
+ 645, // DominicanRepublic
+ 663, // EastTimor
+ 673, // Ecuador
+ 681, // Egypt
+ 687, // ElSalvador
+ 698, // EquatorialGuinea
+ 715, // Eritrea
+ 723, // Estonia
+ 731, // Ethiopia
+ 740, // FalklandIslands
+ 756, // FaroeIslands
+ 769, // Fiji
+ 774, // Finland
+ 782, // France
+ 789, // MetropolitanFrance
+ 808, // FrenchGuiana
+ 821, // FrenchPolynesia
+ 837, // FrenchSouthernTerritories
+ 863, // Gabon
+ 869, // Gambia
+ 876, // Georgia
+ 884, // Germany
+ 892, // Ghana
+ 898, // Gibraltar
+ 908, // Greece
+ 915, // Greenland
+ 925, // Grenada
+ 933, // Guadeloupe
+ 944, // Guam
+ 949, // Guatemala
+ 959, // Guinea
+ 966, // GuineaBissau
+ 979, // Guyana
+ 986, // Haiti
+ 992, // HeardAndMcDonaldIslands
+ 1016, // Honduras
+ 1025, // HongKong
+ 1034, // Hungary
+ 1042, // Iceland
+ 1050, // India
+ 1056, // Indonesia
+ 1066, // Iran
+ 1071, // Iraq
+ 1076, // Ireland
+ 1084, // Israel
+ 1091, // Italy
+ 1097, // Jamaica
+ 1105, // Japan
+ 1111, // Jordan
+ 1118, // Kazakhstan
+ 1129, // Kenya
+ 1135, // Kiribati
+ 1144, // DemocraticRepublicOfKorea
+ 1170, // RepublicOfKorea
+ 1186, // Kuwait
+ 1193, // Kyrgyzstan
+ 1204, // Lao
+ 1208, // Latvia
+ 1215, // Lebanon
+ 1223, // Lesotho
+ 1231, // Liberia
+ 1239, // LibyanArabJamahiriya
+ 1260, // Liechtenstein
+ 1274, // Lithuania
+ 1284, // Luxembourg
+ 1295, // Macau
+ 1301, // Macedonia
+ 1311, // Madagascar
+ 1322, // Malawi
+ 1329, // Malaysia
+ 1338, // Maldives
+ 1347, // Mali
+ 1352, // Malta
+ 1358, // MarshallIslands
+ 1374, // Martinique
+ 1385, // Mauritania
+ 1396, // Mauritius
+ 1406, // Mayotte
+ 1414, // Mexico
+ 1421, // Micronesia
+ 1432, // Moldova
+ 1440, // Monaco
+ 1447, // Mongolia
+ 1456, // Montserrat
+ 1467, // Morocco
+ 1475, // Mozambique
+ 1486, // Myanmar
+ 1494, // Namibia
+ 1502, // Nauru
+ 1508, // Nepal
+ 1514, // Netherlands
+ 1526, // NetherlandsAntilles
+ 1546, // NewCaledonia
+ 1559, // NewZealand
+ 1570, // Nicaragua
+ 1580, // Niger
+ 1586, // Nigeria
+ 1594, // Niue
+ 1599, // NorfolkIsland
+ 1613, // NorthernMarianaIslands
+ 1636, // Norway
+ 1643, // Oman
+ 1648, // Pakistan
+ 1657, // Palau
+ 1663, // PalestinianTerritory
+ 1684, // Panama
+ 1691, // PapuaNewGuinea
+ 1706, // Paraguay
+ 1715, // Peru
+ 1720, // Philippines
+ 1732, // Pitcairn
+ 1741, // Poland
+ 1748, // Portugal
+ 1757, // PuertoRico
+ 1768, // Qatar
+ 1774, // Reunion
+ 1782, // Romania
+ 1790, // RussianFederation
+ 1808, // Rwanda
+ 1815, // SaintKittsAndNevis
+ 1834, // StLucia
+ 1842, // StVincentAndTheGrenadines
+ 1868, // Samoa
+ 1874, // SanMarino
+ 1884, // SaoTomeAndPrincipe
+ 1903, // SaudiArabia
+ 1915, // Senegal
+ 1923, // Seychelles
+ 1934, // SierraLeone
+ 1946, // Singapore
+ 1956, // Slovakia
+ 1965, // Slovenia
+ 1974, // SolomonIslands
+ 1989, // Somalia
+ 1997, // SouthAfrica
+ 2009, // SouthGeorgiaAndTheSouthSandwichIslands
+ 2048, // Spain
+ 2054, // SriLanka
+ 2063, // StHelena
+ 2072, // StPierreAndMiquelon
+ 2092, // Sudan
+ 2098, // Suriname
+ 2107, // SvalbardAndJanMayenIslands
+ 2134, // Swaziland
+ 2144, // Sweden
+ 2151, // Switzerland
+ 2163, // SyrianArabRepublic
+ 2182, // Taiwan
+ 2189, // Tajikistan
+ 2200, // Tanzania
+ 2209, // Thailand
+ 2218, // Togo
+ 2223, // Tokelau
+ 2231, // Tonga
+ 2237, // TrinidadAndTobago
+ 2255, // Tunisia
+ 2263, // Turkey
+ 2270, // Turkmenistan
+ 2283, // TurksAndCaicosIslands
+ 2305, // Tuvalu
+ 2312, // Uganda
+ 2319, // Ukraine
+ 2327, // UnitedArabEmirates
+ 2346, // UnitedKingdom
+ 2360, // UnitedStates
+ 2373, // UnitedStatesMinorOutlyingIslands
+ 2406, // Uruguay
+ 2414, // Uzbekistan
+ 2425, // Vanuatu
+ 2433, // VaticanCityState
+ 2450, // Venezuela
+ 2460, // VietNam
+ 2468, // BritishVirginIslands
+ 2489, // USVirginIslands
+ 2505, // WallisAndFutunaIslands
+ 2528, // WesternSahara
+ 2542, // Yemen
+ 2548, // Yugoslavia
+ 2559, // Zambia
+ 2566, // Zimbabwe
+ 2575, // SerbiaAndMontenegro
+};
+
+static const unsigned char language_code_list[] =
+" \0" // Unused
+" \0" // C
+"ab\0" // Abkhazian
+"om\0" // Afan
+"aa\0" // Afar
+"af\0" // Afrikaans
+"sq\0" // Albanian
+"am\0" // Amharic
+"ar\0" // Arabic
+"hy\0" // Armenian
+"as\0" // Assamese
+"ay\0" // Aymara
+"az\0" // Azerbaijani
+"ba\0" // Bashkir
+"eu\0" // Basque
+"bn\0" // Bengali
+"dz\0" // Bhutani
+"bh\0" // Bihari
+"bi\0" // Bislama
+"br\0" // Breton
+"bg\0" // Bulgarian
+"my\0" // Burmese
+"be\0" // Byelorussian
+"km\0" // Cambodian
+"ca\0" // Catalan
+"zh\0" // Chinese
+"co\0" // Corsican
+"hr\0" // Croatian
+"cs\0" // Czech
+"da\0" // Danish
+"nl\0" // Dutch
+"en\0" // English
+"eo\0" // Esperanto
+"et\0" // Estonian
+"fo\0" // Faroese
+"fj\0" // Fiji
+"fi\0" // Finnish
+"fr\0" // French
+"fy\0" // Frisian
+"gd\0" // Gaelic
+"gl\0" // Galician
+"ka\0" // Georgian
+"de\0" // German
+"el\0" // Greek
+"kl\0" // Greenlandic
+"gn\0" // Guarani
+"gu\0" // Gujarati
+"ha\0" // Hausa
+"he\0" // Hebrew
+"hi\0" // Hindi
+"hu\0" // Hungarian
+"is\0" // Icelandic
+"id\0" // Indonesian
+"ia\0" // Interlingua
+"ie\0" // Interlingue
+"iu\0" // Inuktitut
+"ik\0" // Inupiak
+"ga\0" // Irish
+"it\0" // Italian
+"ja\0" // Japanese
+"jv\0" // Javanese
+"kn\0" // Kannada
+"ks\0" // Kashmiri
+"kk\0" // Kazakh
+"rw\0" // Kinyarwanda
+"ky\0" // Kirghiz
+"ko\0" // Korean
+"ku\0" // Kurdish
+"rn\0" // Kurundi
+"lo\0" // Laothian
+"la\0" // Latin
+"lv\0" // Latvian
+"ln\0" // Lingala
+"lt\0" // Lithuanian
+"mk\0" // Macedonian
+"mg\0" // Malagasy
+"ms\0" // Malay
+"ml\0" // Malayalam
+"mt\0" // Maltese
+"mi\0" // Maori
+"mr\0" // Marathi
+"mo\0" // Moldavian
+"mn\0" // Mongolian
+"na\0" // Nauru
+"ne\0" // Nepali
+"nb\0" // Norwegian
+"oc\0" // Occitan
+"or\0" // Oriya
+"ps\0" // Pashto
+"fa\0" // Persian
+"pl\0" // Polish
+"pt\0" // Portuguese
+"pa\0" // Punjabi
+"qu\0" // Quechua
+"rm\0" // RhaetoRomance
+"ro\0" // Romanian
+"ru\0" // Russian
+"sm\0" // Samoan
+"sg\0" // Sangho
+"sa\0" // Sanskrit
+"sr\0" // Serbian
+"sh\0" // SerboCroatian
+"st\0" // Sesotho
+"tn\0" // Setswana
+"sn\0" // Shona
+"sd\0" // Sindhi
+"si\0" // Singhalese
+"ss\0" // Siswati
+"sk\0" // Slovak
+"sl\0" // Slovenian
+"so\0" // Somali
+"es\0" // Spanish
+"su\0" // Sundanese
+"sw\0" // Swahili
+"sv\0" // Swedish
+"tl\0" // Tagalog
+"tg\0" // Tajik
+"ta\0" // Tamil
+"tt\0" // Tatar
+"te\0" // Telugu
+"th\0" // Thai
+"bo\0" // Tibetan
+"ti\0" // Tigrinya
+"to\0" // Tonga
+"ts\0" // Tsonga
+"tr\0" // Turkish
+"tk\0" // Turkmen
+"tw\0" // Twi
+"ug\0" // Uigur
+"uk\0" // Ukrainian
+"ur\0" // Urdu
+"uz\0" // Uzbek
+"vi\0" // Vietnamese
+"vo\0" // Volapuk
+"cy\0" // Welsh
+"wo\0" // Wolof
+"xh\0" // Xhosa
+"yi\0" // Yiddish
+"yo\0" // Yoruba
+"za\0" // Zhuang
+"zu\0" // Zulu
+"nn\0" // Nynorsk
+"bs\0" // Bosnian
+"dv\0" // Divehi
+"gv\0" // Manx
+"kw\0" // Cornish
+"ak\0" // Akan
+"kok" // Konkani
+"gaa" // Ga
+"ig\0" // Igbo
+"kam" // Kamba
+"syr" // Syriac
+"byn" // Blin
+"gez" // Geez
+"kfo" // Koro
+"sid" // Sidamo
+"cch" // Atsam
+"tig" // Tigre
+"kaj" // Jju
+"fur" // Friulian
+"ve\0" // Venda
+"ee\0" // Ewe
+"wa\0" // Walamo
+"haw" // Hawaiian
+"kcg" // Tyap
+"ny\0" // Chewa
+;
+
+static const unsigned char country_code_list[] =
+" " // AnyCountry
+"AF" // Afghanistan
+"AL" // Albania
+"DZ" // Algeria
+"AS" // AmericanSamoa
+"AD" // Andorra
+"AO" // Angola
+"AI" // Anguilla
+"AQ" // Antarctica
+"AG" // AntiguaAndBarbuda
+"AR" // Argentina
+"AM" // Armenia
+"AW" // Aruba
+"AU" // Australia
+"AT" // Austria
+"AZ" // Azerbaijan
+"BS" // Bahamas
+"BH" // Bahrain
+"BD" // Bangladesh
+"BB" // Barbados
+"BY" // Belarus
+"BE" // Belgium
+"BZ" // Belize
+"BJ" // Benin
+"BM" // Bermuda
+"BT" // Bhutan
+"BO" // Bolivia
+"BA" // BosniaAndHerzegowina
+"BW" // Botswana
+"BV" // BouvetIsland
+"BR" // Brazil
+"IO" // BritishIndianOceanTerritory
+"BN" // BruneiDarussalam
+"BG" // Bulgaria
+"BF" // BurkinaFaso
+"BI" // Burundi
+"KH" // Cambodia
+"CM" // Cameroon
+"CA" // Canada
+"CV" // CapeVerde
+"KY" // CaymanIslands
+"CF" // CentralAfricanRepublic
+"TD" // Chad
+"CL" // Chile
+"CN" // China
+"CX" // ChristmasIsland
+"CC" // CocosIslands
+"CO" // Colombia
+"KM" // Comoros
+"CD" // DemocraticRepublicOfCongo
+"CG" // PeoplesRepublicOfCongo
+"CK" // CookIslands
+"CR" // CostaRica
+"CI" // IvoryCoast
+"HR" // Croatia
+"CU" // Cuba
+"CY" // Cyprus
+"CZ" // CzechRepublic
+"DK" // Denmark
+"DJ" // Djibouti
+"DM" // Dominica
+"DO" // DominicanRepublic
+"TL" // EastTimor
+"EC" // Ecuador
+"EG" // Egypt
+"SV" // ElSalvador
+"GQ" // EquatorialGuinea
+"ER" // Eritrea
+"EE" // Estonia
+"ET" // Ethiopia
+"FK" // FalklandIslands
+"FO" // FaroeIslands
+"FJ" // Fiji
+"FI" // Finland
+"FR" // France
+"FX" // MetropolitanFrance
+"GF" // FrenchGuiana
+"PF" // FrenchPolynesia
+"TF" // FrenchSouthernTerritories
+"GA" // Gabon
+"GM" // Gambia
+"GE" // Georgia
+"DE" // Germany
+"GH" // Ghana
+"GI" // Gibraltar
+"GR" // Greece
+"GL" // Greenland
+"GD" // Grenada
+"GP" // Guadeloupe
+"GU" // Guam
+"GT" // Guatemala
+"GN" // Guinea
+"GW" // GuineaBissau
+"GY" // Guyana
+"HT" // Haiti
+"HM" // HeardAndMcDonaldIslands
+"HN" // Honduras
+"HK" // HongKong
+"HU" // Hungary
+"IS" // Iceland
+"IN" // India
+"ID" // Indonesia
+"IR" // Iran
+"IQ" // Iraq
+"IE" // Ireland
+"IL" // Israel
+"IT" // Italy
+"JM" // Jamaica
+"JP" // Japan
+"JO" // Jordan
+"KZ" // Kazakhstan
+"KE" // Kenya
+"KI" // Kiribati
+"KP" // DemocraticRepublicOfKorea
+"KR" // RepublicOfKorea
+"KW" // Kuwait
+"KG" // Kyrgyzstan
+"LA" // Lao
+"LV" // Latvia
+"LB" // Lebanon
+"LS" // Lesotho
+"LR" // Liberia
+"LY" // LibyanArabJamahiriya
+"LI" // Liechtenstein
+"LT" // Lithuania
+"LU" // Luxembourg
+"MO" // Macau
+"MK" // Macedonia
+"MG" // Madagascar
+"MW" // Malawi
+"MY" // Malaysia
+"MV" // Maldives
+"ML" // Mali
+"MT" // Malta
+"MH" // MarshallIslands
+"MQ" // Martinique
+"MR" // Mauritania
+"MU" // Mauritius
+"YT" // Mayotte
+"MX" // Mexico
+"FM" // Micronesia
+"MD" // Moldova
+"MC" // Monaco
+"MN" // Mongolia
+"MS" // Montserrat
+"MA" // Morocco
+"MZ" // Mozambique
+"MM" // Myanmar
+"NA" // Namibia
+"NR" // Nauru
+"NP" // Nepal
+"NL" // Netherlands
+"AN" // NetherlandsAntilles
+"NC" // NewCaledonia
+"NZ" // NewZealand
+"NI" // Nicaragua
+"NE" // Niger
+"NG" // Nigeria
+"NU" // Niue
+"NF" // NorfolkIsland
+"MP" // NorthernMarianaIslands
+"NO" // Norway
+"OM" // Oman
+"PK" // Pakistan
+"PW" // Palau
+"PS" // PalestinianTerritory
+"PA" // Panama
+"PG" // PapuaNewGuinea
+"PY" // Paraguay
+"PE" // Peru
+"PH" // Philippines
+"PN" // Pitcairn
+"PL" // Poland
+"PT" // Portugal
+"PR" // PuertoRico
+"QA" // Qatar
+"RE" // Reunion
+"RO" // Romania
+"RU" // RussianFederation
+"RW" // Rwanda
+"KN" // SaintKittsAndNevis
+"LC" // StLucia
+"VC" // StVincentAndTheGrenadines
+"WS" // Samoa
+"SM" // SanMarino
+"ST" // SaoTomeAndPrincipe
+"SA" // SaudiArabia
+"SN" // Senegal
+"SC" // Seychelles
+"SL" // SierraLeone
+"SG" // Singapore
+"SK" // Slovakia
+"SI" // Slovenia
+"SB" // SolomonIslands
+"SO" // Somalia
+"ZA" // SouthAfrica
+"GS" // SouthGeorgiaAndTheSouthSandwichIslands
+"ES" // Spain
+"LK" // SriLanka
+"SH" // StHelena
+"PM" // StPierreAndMiquelon
+"SD" // Sudan
+"SR" // Suriname
+"SJ" // SvalbardAndJanMayenIslands
+"SZ" // Swaziland
+"SE" // Sweden
+"CH" // Switzerland
+"SY" // SyrianArabRepublic
+"TW" // Taiwan
+"TJ" // Tajikistan
+"TZ" // Tanzania
+"TH" // Thailand
+"TG" // Togo
+"TK" // Tokelau
+"TO" // Tonga
+"TT" // TrinidadAndTobago
+"TN" // Tunisia
+"TR" // Turkey
+"TM" // Turkmenistan
+"TC" // TurksAndCaicosIslands
+"TV" // Tuvalu
+"UG" // Uganda
+"UA" // Ukraine
+"AE" // UnitedArabEmirates
+"GB" // UnitedKingdom
+"US" // UnitedStates
+"UM" // UnitedStatesMinorOutlyingIslands
+"UY" // Uruguay
+"UZ" // Uzbekistan
+"VU" // Vanuatu
+"VA" // VaticanCityState
+"VE" // Venezuela
+"VN" // VietNam
+"VG" // BritishVirginIslands
+"VI" // USVirginIslands
+"WF" // WallisAndFutunaIslands
+"EH" // WesternSahara
+"YE" // Yemen
+"YU" // Yugoslavia
+"ZM" // Zambia
+"ZW" // Zimbabwe
+"CS" // SerbiaAndMontenegro
+;
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/corelib/tools/qlocale_p.h b/src/corelib/tools/qlocale_p.h
new file mode 100644
index 0000000000..9d36a831cb
--- /dev/null
+++ b/src/corelib/tools/qlocale_p.h
@@ -0,0 +1,206 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QLOCALE_P_H
+#define QLOCALE_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 "QtCore/qstring.h"
+#include "QtCore/qvarlengtharray.h"
+
+#include "qlocale.h"
+
+QT_BEGIN_NAMESPACE
+
+struct Q_CORE_EXPORT QLocalePrivate
+{
+public:
+ QChar decimal() const { return QChar(m_decimal); }
+ QChar group() const { return QChar(m_group); }
+ QChar list() const { return QChar(m_list); }
+ QChar percent() const { return QChar(m_percent); }
+ QChar zero() const { return QChar(m_zero); }
+ QChar plus() const { return QChar(m_plus); }
+ QChar minus() const { return QChar(m_minus); }
+ QChar exponential() const { return QChar(m_exponential); }
+
+ quint32 languageId() const { return m_language_id; }
+ quint32 countryId() const { return m_country_id; }
+
+ QLocale::MeasurementSystem measurementSystem() const;
+
+ enum DoubleForm {
+ DFExponent = 0,
+ DFDecimal,
+ DFSignificantDigits,
+ _DFMax = DFSignificantDigits
+ };
+
+ enum Flags {
+ NoFlags = 0,
+ Alternate = 0x01,
+ ZeroPadded = 0x02,
+ LeftAdjusted = 0x04,
+ BlankBeforePositive = 0x08,
+ AlwaysShowSign = 0x10,
+ ThousandsGroup = 0x20,
+ CapitalEorX = 0x40,
+
+ ShowBase = 0x80,
+ UppercaseBase = 0x100,
+ ForcePoint = Alternate,
+ };
+
+ enum GroupSeparatorMode {
+ FailOnGroupSeparators,
+ ParseGroupSeparators
+ };
+
+ QString doubleToString(double d,
+ int precision = -1,
+ DoubleForm form = DFSignificantDigits,
+ int width = -1,
+ unsigned flags = NoFlags) const;
+ QString longLongToString(qint64 l, int precision = -1,
+ int base = 10,
+ int width = -1,
+ unsigned flags = NoFlags) const;
+ QString unsLongLongToString(quint64 l, int precision = -1,
+ int base = 10,
+ int width = -1,
+ unsigned flags = NoFlags) const;
+ double stringToDouble(const QString &num, bool *ok, GroupSeparatorMode group_sep_mode) const;
+ qint64 stringToLongLong(const QString &num, int base, bool *ok, GroupSeparatorMode group_sep_mode) const;
+ quint64 stringToUnsLongLong(const QString &num, int base, bool *ok, GroupSeparatorMode group_sep_mode) const;
+
+
+ static double bytearrayToDouble(const char *num, bool *ok, bool *overflow = 0);
+ static qint64 bytearrayToLongLong(const char *num, int base, bool *ok, bool *overflow = 0);
+ static quint64 bytearrayToUnsLongLong(const char *num, int base, bool *ok);
+
+ typedef QVarLengthArray<char, 256> CharBuff;
+ bool numberToCLocale(const QString &num,
+ GroupSeparatorMode group_sep_mode,
+ CharBuff *result) const;
+ inline char digitToCLocale(const QChar &c) const;
+
+ static void updateSystemPrivate();
+
+ enum NumberMode { IntegerMode, DoubleStandardMode, DoubleScientificMode };
+ bool validateChars(const QString &str, NumberMode numMode, QByteArray *buff, int decDigits = -1) const;
+
+ QString dateTimeToString(const QString &format, const QDate *date, const QTime *time,
+ const QLocale *q) const;
+
+ quint32 m_language_id, m_country_id;
+
+ quint16 m_decimal, m_group, m_list, m_percent,
+ m_zero, m_minus, m_plus, m_exponential;
+
+ quint32 m_short_date_format_idx, m_short_date_format_size;
+ quint32 m_long_date_format_idx, m_long_date_format_size;
+ quint32 m_short_time_format_idx, m_short_time_format_size;
+ quint32 m_long_time_format_idx, m_long_time_format_size;
+ quint32 m_standalone_short_month_names_idx, m_standalone_short_month_names_size;
+ quint32 m_standalone_long_month_names_idx, m_standalone_long_month_names_size;
+ quint32 m_standalone_narrow_month_names_idx, m_standalone_narrow_month_names_size;
+ quint32 m_short_month_names_idx, m_short_month_names_size;
+ quint32 m_long_month_names_idx, m_long_month_names_size;
+ quint32 m_narrow_month_names_idx, m_narrow_month_names_size;
+ quint32 m_standalone_short_day_names_idx, m_standalone_short_day_names_size;
+ quint32 m_standalone_long_day_names_idx, m_standalone_long_day_names_size;
+ quint32 m_standalone_narrow_day_names_idx, m_standalone_narrow_day_names_size;
+ quint32 m_short_day_names_idx, m_short_day_names_size;
+ quint32 m_long_day_names_idx, m_long_day_names_size;
+ quint32 m_narrow_day_names_idx, m_narrow_day_names_size;
+ quint32 m_am_idx, m_am_size;
+ quint32 m_pm_idx, m_pm_size;
+};
+
+inline char QLocalePrivate::digitToCLocale(const QChar &in) const
+{
+ const QChar _zero = zero();
+ const QChar _group = group();
+ const ushort zeroUnicode = _zero.unicode();
+ const ushort tenUnicode = zeroUnicode + 10;
+
+ if (in.unicode() >= zeroUnicode && in.unicode() < tenUnicode)
+ return '0' + in.unicode() - zeroUnicode;
+
+ if (in.unicode() >= '0' && in.unicode() <= '9')
+ return in.toLatin1();
+
+ if (in == plus())
+ return '+';
+
+ if (in == minus())
+ return '-';
+
+ if (in == decimal())
+ return '.';
+
+ if (in == group())
+ return ',';
+
+ if (in == exponential() || in == exponential().toUpper())
+ return 'e';
+
+ // In several languages group() is the char 0xA0, which looks like a space.
+ // People use a regular space instead of it and complain it doesn't work.
+ if (_group.unicode() == 0xA0 && in.unicode() == ' ')
+ return ',';
+
+ return 0;
+}
+
+QT_END_NAMESPACE
+
+#endif // QLOCALE_P_H
diff --git a/src/corelib/tools/qmap.cpp b/src/corelib/tools/qmap.cpp
new file mode 100644
index 0000000000..0699400796
--- /dev/null
+++ b/src/corelib/tools/qmap.cpp
@@ -0,0 +1,1588 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qmap.h"
+
+#include <stdlib.h>
+
+#ifdef QT_QMAP_DEBUG
+# include <qstring.h>
+# include <qvector.h>
+#endif
+
+QT_BEGIN_NAMESPACE
+
+QMapData QMapData::shared_null = {
+ &shared_null,
+ { &shared_null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ Q_BASIC_ATOMIC_INITIALIZER(1), 0, 0, 0, false, true
+};
+
+QMapData *QMapData::createData()
+{
+ QMapData *d = new QMapData;
+ Node *e = reinterpret_cast<Node *>(d);
+ e->backward = e;
+ e->forward[0] = e;
+ d->ref = 1;
+ d->topLevel = 0;
+ d->size = 0;
+ d->randomBits = 0;
+ d->insertInOrder = false;
+ d->sharable = true;
+ return d;
+}
+
+void QMapData::continueFreeData(int offset)
+{
+ Node *e = reinterpret_cast<Node *>(this);
+ Node *cur = e->forward[0];
+ Node *prev;
+ while (cur != e) {
+ prev = cur;
+ cur = cur->forward[0];
+ qFree(reinterpret_cast<char *>(prev) - offset);
+ }
+ delete this;
+}
+
+QMapData::Node *QMapData::node_create(Node *update[], int offset)
+{
+ int level = 0;
+ uint mask = (1 << Sparseness) - 1;
+
+ while ((randomBits & mask) == mask && level < LastLevel) {
+ ++level;
+ mask <<= Sparseness;
+ }
+
+ ++randomBits;
+ if (level == 3 && !insertInOrder)
+ randomBits = qrand();
+
+ if (level > topLevel) {
+ Node *e = reinterpret_cast<Node *>(this);
+ level = ++topLevel;
+ e->forward[level] = e;
+ update[level] = e;
+ }
+
+ void *concreteNode = qMalloc(offset + sizeof(Node) + level * sizeof(Node *));
+ Node *abstractNode = reinterpret_cast<Node *>(reinterpret_cast<char *>(concreteNode) + offset);
+
+ abstractNode->backward = update[0];
+ update[0]->forward[0]->backward = abstractNode;
+
+ for (int i = level; i >= 0; i--) {
+ abstractNode->forward[i] = update[i]->forward[i];
+ update[i]->forward[i] = abstractNode;
+ update[i] = abstractNode;
+ }
+ ++size;
+ return abstractNode;
+}
+
+void QMapData::node_delete(Node *update[], int offset, Node *node)
+{
+ node->forward[0]->backward = node->backward;
+
+ for (int i = 0; i <= topLevel; ++i) {
+ if (update[i]->forward[i] != node)
+ break;
+ update[i]->forward[i] = node->forward[i];
+ }
+ --size;
+ qFree(reinterpret_cast<char *>(node) - offset);
+}
+
+#ifdef QT_QMAP_DEBUG
+
+uint QMapData::adjust_ptr(Node *node)
+{
+ if (node == reinterpret_cast<Node *>(this)) {
+ return (uint)0xDEADBEEF;
+ } else {
+ return (uint)node;
+ }
+}
+
+void QMapData::dump()
+{
+ qDebug("Map data (ref = %d, size = %d, randomBits = %#.8x)", ref.atomic, size, randomBits);
+
+ QString preOutput;
+ QVector<QString> output(topLevel + 1);
+ Node *e = reinterpret_cast<Node *>(this);
+
+ QString str;
+ str.sprintf(" %.8x", adjust_ptr(reinterpret_cast<Node *>(this)));
+ preOutput += str;
+
+ Node *update[LastLevel + 1];
+ for (int i = 0; i <= topLevel; ++i) {
+ str.sprintf("%d: [%.8x] -", i, adjust_ptr(forward[i]));
+ output[i] += str;
+ update[i] = forward[i];
+ }
+
+ Node *node = forward[0];
+ while (node != e) {
+ int level = 0;
+ while (level < topLevel && update[level + 1] == node)
+ ++level;
+
+ str.sprintf(" %.8x", adjust_ptr(node));
+ preOutput += str;
+
+ for (int i = 0; i <= level; ++i) {
+ str.sprintf("-> [%.8x] -", adjust_ptr(node->forward[i]));
+ output[i] += str;
+ update[i] = node->forward[i];
+ }
+ for (int j = level + 1; j <= topLevel; ++j)
+ output[j] += "---------------";
+ node = node->forward[0];
+ }
+
+ qDebug(preOutput.ascii());
+ for (int i = 0; i <= topLevel; ++i)
+ qDebug(output[i].ascii());
+}
+#endif
+
+/*!
+ \class QMap
+ \brief The QMap class is a template class that provides a skip-list-based dictionary.
+
+ \ingroup tools
+ \ingroup shared
+ \mainclass
+ \reentrant
+
+ QMap\<Key, T\> is one of Qt's generic \l{container classes}. It
+ stores (key, value) pairs and provides fast lookup of the
+ value associated with a key.
+
+ QMap and QHash provide very similar functionality. The
+ differences are:
+
+ \list
+ \i QHash provides faster lookups than QMap. (See \l{Algorithmic
+ Complexity} for details.)
+ \i When iterating over a QHash, the items are arbitrarily ordered.
+ With QMap, the items are always sorted by key.
+ \i The key type of a QHash must provide operator==() and a global
+ qHash(Key) function. The key type of a QMap must provide
+ operator<() specifying a total order.
+ \endlist
+
+ Here's an example QMap with QString keys and \c int values:
+ \snippet doc/src/snippets/code/src_corelib_tools_qmap.cpp 0
+
+ To insert a (key, value) pair into the map, you can use operator[]():
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qmap.cpp 1
+
+ This inserts the following three (key, value) pairs into the
+ QMap: ("one", 1), ("three", 3), and ("seven", 7). Another way to
+ insert items into the map is to use insert():
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qmap.cpp 2
+
+ To look up a value, use operator[]() or value():
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qmap.cpp 3
+
+ If there is no item with the specified key in the map, these
+ functions return a \l{default-constructed value}.
+
+ If you want to check whether the map contains a certain key, use
+ contains():
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qmap.cpp 4
+
+ There is also a value() overload that uses its second argument as
+ a default value if there is no item with the specified key:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qmap.cpp 5
+
+ In general, we recommend that you use contains() and value()
+ rather than operator[]() for looking up a key in a map. The
+ reason is that operator[]() silently inserts an item into the
+ map if no item exists with the same key (unless the map is
+ const). For example, the following code snippet will create 1000
+ items in memory:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qmap.cpp 6
+
+ To avoid this problem, replace \c map[i] with \c map.value(i)
+ in the code above.
+
+ If you want to navigate through all the (key, value) pairs stored
+ in a QMap, you can use an iterator. QMap provides both
+ \l{Java-style iterators} (QMapIterator and QMutableMapIterator)
+ and \l{STL-style iterators} (QMap::const_iterator and
+ QMap::iterator). Here's how to iterate over a QMap<QString, int>
+ using a Java-style iterator:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qmap.cpp 7
+
+ Here's the same code, but using an STL-style iterator this time:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qmap.cpp 8
+
+ The items are traversed in ascending key order.
+
+ Normally, a QMap allows only one value per key. If you call
+ insert() with a key that already exists in the QMap, the
+ previous value will be erased. For example:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qmap.cpp 9
+
+ However, you can store multiple values per key by using
+ insertMulti() instead of insert() (or using the convenience
+ subclass QMultiMap). If you want to retrieve all the values for a
+ single key, you can use values(const Key &key), which returns a
+ QList<T>:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qmap.cpp 10
+
+ The items that share the same key are available from most
+ recently to least recently inserted. Another approach is to call
+ find() to get the STL-style iterator for the first item with a
+ key and iterate from there:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qmap.cpp 11
+
+ If you only need to extract the values from a map (not the keys),
+ you can also use \l{foreach}:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qmap.cpp 12
+
+ Items can be removed from the map in several ways. One way is to
+ call remove(); this will remove any item with the given key.
+ Another way is to use QMutableMapIterator::remove(). In addition,
+ you can clear the entire map using clear().
+
+ QMap's key and value data types must be \l{assignable data
+ types}. This covers most data types you are likely to encounter,
+ but the compiler won't let you, for example, store a QWidget as a
+ value; instead, store a QWidget *. In addition, QMap's key type
+ must provide operator<(). QMap uses it to keep its items sorted,
+ and assumes that two keys \c x and \c y are equal if neither \c{x
+ < y} nor \c{y < x} is true.
+
+ Example:
+ \snippet doc/src/snippets/code/src_corelib_tools_qmap.cpp 13
+
+ In the example, we start by comparing the employees' names. If
+ they're equal, we compare their dates of birth to break the tie.
+
+ \sa QMapIterator, QMutableMapIterator, QHash, QSet
+*/
+
+/*! \fn QMap::QMap()
+
+ Constructs an empty map.
+
+ \sa clear()
+*/
+
+/*! \fn QMap::QMap(const QMap<Key, T> &other)
+
+ Constructs a copy of \a other.
+
+ This operation occurs in \l{constant time}, because QMap is
+ \l{implicitly shared}. This makes returning a QMap from a
+ function very fast. If a shared instance is modified, it will be
+ copied (copy-on-write), and this takes \l{linear time}.
+
+ \sa operator=()
+*/
+
+/*! \fn QMap::QMap(const std::map<Key, T> & other)
+
+ Constructs a copy of \a other.
+
+ This function is only available if Qt is configured with STL
+ compatibility enabled.
+
+ \sa toStdMap()
+*/
+
+/*! \fn std::map<Key, T> QMap::toStdMap() const
+
+ Returns an STL map equivalent to this QMap.
+
+ This function is only available if Qt is configured with STL
+ compatibility enabled.
+*/
+
+/*! \fn QMap::~QMap()
+
+ Destroys the map. References to the values in the map, and all
+ iterators over this map, become invalid.
+*/
+
+/*! \fn QMap<Key, T> &QMap::operator=(const QMap<Key, T> &other)
+
+ Assigns \a other to this map and returns a reference to this map.
+*/
+
+/*! \fn bool QMap::operator==(const QMap<Key, T> &other) const
+
+ Returns true if \a other is equal to this map; otherwise returns
+ false.
+
+ Two maps are considered equal if they contain the same (key,
+ value) pairs.
+
+ This function requires the value type to implement \c
+ operator==().
+
+ \sa operator!=()
+*/
+
+/*! \fn bool QMap::operator!=(const QMap<Key, T> &other) const
+
+ Returns true if \a other is not equal to this map; otherwise
+ returns false.
+
+ Two maps are considered equal if they contain the same (key,
+ value) pairs.
+
+ This function requires the value type to implement \c
+ operator==().
+
+ \sa operator==()
+*/
+
+/*! \fn int QMap::size() const
+
+ Returns the number of (key, value) pairs in the map.
+
+ \sa isEmpty(), count()
+*/
+
+/*!
+ \fn bool QMap::isEmpty() const
+
+ Returns true if the map contains no items; otherwise returns
+ false.
+
+ \sa size()
+*/
+
+/*! \fn void QMap::detach()
+
+ \internal
+
+ Detaches this map from any other maps with which it may share
+ data.
+
+ \sa isDetached()
+*/
+
+/*! \fn bool QMap::isDetached() const
+
+ \internal
+
+ Returns true if the map's internal data isn't shared with any
+ other map object; otherwise returns false.
+
+ \sa detach()
+*/
+
+/*! \fn void QMap::setSharable(bool sharable)
+
+ \internal
+*/
+
+/*! \fn void QMap::setInsertInOrder(bool sharable)
+
+ \internal
+*/
+
+/*! \fn void QMap::clear()
+
+ Removes all items from the map.
+
+ \sa remove()
+*/
+
+/*! \fn int QMap::remove(const Key &key)
+
+ Removes all the items that have the key \a key from the map.
+ Returns the number of items removed which is usually 1 but will be
+ 0 if the key isn't in the map, or \> 1 if insertMulti() has been
+ used with the \a key.
+
+ \sa clear(), take(), QMultiMap::remove()
+*/
+
+/*! \fn T QMap::take(const Key &key)
+
+ Removes the item with the key \a key from the map and returns
+ the value associated with it.
+
+ If the item does not exist in the map, the function simply
+ returns a \l{default-constructed value}. If there are multiple
+ items for \a key in the map, only the most recently inserted one
+ is removed and returned.
+
+ If you don't use the return value, remove() is more efficient.
+
+ \sa remove()
+*/
+
+/*! \fn bool QMap::contains(const Key &key) const
+
+ Returns true if the map contains an item with key \a key;
+ otherwise returns false.
+
+ \sa count(), QMultiMap::contains()
+*/
+
+/*! \fn const T QMap::value(const Key &key) const
+
+ Returns the value associated with the key \a key.
+
+ If the map contains no item with key \a key, the function
+ returns a \l{default-constructed value}. If there are multiple
+ items for \a key in the map, the value of the most recently
+ inserted one is returned.
+
+ \sa key(), values(), contains(), operator[]()
+*/
+
+/*! \fn const T QMap::value(const Key &key, const T &defaultValue) const
+
+ \overload
+
+ If the map contains no item with key \a key, the function returns
+ \a defaultValue.
+*/
+
+/*! \fn T &QMap::operator[](const Key &key)
+
+ Returns the value associated with the key \a key as a modifiable
+ reference.
+
+ If the map contains no item with key \a key, the function inserts
+ a \l{default-constructed value} into the map with key \a key, and
+ returns a reference to it. If the map contains multiple items
+ with key \a key, this function returns a reference to the most
+ recently inserted value.
+
+ \sa insert(), value()
+*/
+
+/*! \fn const T QMap::operator[](const Key &key) const
+
+ \overload
+
+ Same as value().
+*/
+
+/*! \fn QList<Key> QMap::uniqueKeys() const
+ \since 4.2
+
+ Returns a list containing all the keys in the map in ascending
+ order. Keys that occur multiple times in the map (because items
+ were inserted with insertMulti(), or unite() was used) occur only
+ once in the returned list.
+
+ \sa keys(), values()
+*/
+
+/*! \fn QList<Key> QMap::keys() const
+
+ Returns a list containing all the keys in the map in ascending
+ order. Keys that occur multiple times in the map (because items
+ were inserted with insertMulti(), or unite() was used) also
+ occur multiple times in the list.
+
+ To obtain a list of unique keys, where each key from the map only
+ occurs once, use uniqueKeys().
+
+ The order is guaranteed to be the same as that used by values().
+
+ \sa uniqueKeys(), values(), key()
+*/
+
+/*! \fn QList<Key> QMap::keys(const T &value) const
+
+ \overload
+
+ Returns a list containing all the keys associated with value \a
+ value in ascending order.
+
+ This function can be slow (\l{linear time}), because QMap's
+ internal data structure is optimized for fast lookup by key, not
+ by value.
+*/
+
+/*! \fn Key QMap::key(const T &value) const
+
+ Returns the first key with value \a value.
+
+ If the map contains no item with value \a value, the function
+ returns a \link {default-constructed value} default-constructed
+ key \endlink.
+
+ This function can be slow (\l{linear time}), because QMap's
+ internal data structure is optimized for fast lookup by key, not
+ by value.
+
+ \sa value(), keys()
+*/
+
+/*!
+ \fn Key QMap::key(const T &value, const Key &defaultKey) const
+ \since 4.3
+ \overload
+
+ Returns the first key with value \a value, or \a defaultKey if
+ the map contains no item with value \a value.
+
+ This function can be slow (\l{linear time}), because QMap's
+ internal data structure is optimized for fast lookup by key, not
+ by value.
+*/
+
+/*! \fn QList<T> QMap::values() const
+
+ Returns a list containing all the values in the map, in ascending
+ order of their keys. If a key is associated with multiple values,
+ all of its values will be in the list, and not just the most
+ recently inserted one.
+
+ \sa keys(), value()
+*/
+
+/*! \fn QList<T> QMap::values(const Key &key) const
+
+ \overload
+
+ Returns a list containing all the values associated with key
+ \a key, from the most recently inserted to the least recently
+ inserted one.
+
+ \sa count(), insertMulti()
+*/
+
+/*! \fn int QMap::count(const Key &key) const
+
+ Returns the number of items associated with key \a key.
+
+ \sa contains(), insertMulti(), QMultiMap::count()
+*/
+
+/*! \fn int QMap::count() const
+
+ \overload
+
+ Same as size().
+*/
+
+/*! \fn QMap::iterator QMap::begin()
+
+ Returns an \l{STL-style iterator} pointing to the first item in
+ the map.
+
+ \sa constBegin(), end()
+*/
+
+/*! \fn QMap::const_iterator QMap::begin() const
+
+ \overload
+*/
+
+/*! \fn QMap::const_iterator QMap::constBegin() const
+
+ Returns a const \l{STL-style iterator} pointing to the first item
+ in the map.
+
+ \sa begin(), constEnd()
+*/
+
+/*! \fn QMap::iterator QMap::end()
+
+ Returns an \l{STL-style iterator} pointing to the imaginary item
+ after the last item in the map.
+
+ \sa begin(), constEnd()
+*/
+
+/*! \fn QMap::const_iterator QMap::end() const
+
+ \overload
+*/
+
+/*! \fn QMap::const_iterator QMap::constEnd() const
+
+ Returns a const \l{STL-style iterator} pointing to the imaginary
+ item after the last item in the map.
+
+ \sa constBegin(), end()
+*/
+
+/*! \fn QMap::iterator QMap::erase(iterator pos)
+
+ Removes the (key, value) pair pointed to by the iterator \a pos
+ from the map, and returns an iterator to the next item in the
+ map.
+
+ \sa remove()
+*/
+
+/*! \fn QMap::iterator QMap::find(const Key &key)
+
+ Returns an iterator pointing to the item with key \a key in the
+ map.
+
+ If the map contains no item with key \a key, the function
+ returns end().
+
+ If the map contains multiple items with key \a key, this
+ function returns an iterator that points to the most recently
+ inserted value. The other values are accessible by incrementing
+ the iterator. For example, here's some code that iterates over all
+ the items with the same key:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qmap.cpp 14
+
+ \sa constFind(), value(), values(), lowerBound(), upperBound(), QMultiMap::find()
+*/
+
+/*! \fn QMap::const_iterator QMap::find(const Key &key) const
+
+ \overload
+*/
+
+/*! \fn QMap::iterator QMap::constFind(const Key &key) const
+ \since 4.1
+
+ Returns an const iterator pointing to the item with key \a key in the
+ map.
+
+ If the map contains no item with key \a key, the function
+ returns constEnd().
+
+ \sa find(), QMultiMap::constFind()
+*/
+
+/*! \fn QMap::iterator QMap::lowerBound(const Key &key)
+
+ Returns an iterator pointing to the first item with key \a key in
+ the map. If the map contains no item with key \a key, the
+ function returns an iterator to the nearest item with a greater
+ key.
+
+ Example:
+ \snippet doc/src/snippets/code/src_corelib_tools_qmap.cpp 15
+
+ If the map contains multiple items with key \a key, this
+ function returns an iterator that points to the most recently
+ inserted value. The other values are accessible by incrementing
+ the iterator. For example, here's some code that iterates over all
+ the items with the same key:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qmap.cpp 16
+
+ \sa qLowerBound(), upperBound(), find()
+*/
+
+/*! \fn QMap::const_iterator QMap::lowerBound(const Key &key) const
+
+ \overload
+*/
+
+/*! \fn QMap::iterator QMap::upperBound(const Key &key)
+
+ Returns an iterator pointing to the item that immediately follows
+ the last item with key \a key in the map. If the map contains no
+ item with key \a key, the function returns an iterator to the
+ nearest item with a greater key.
+
+ Example:
+ \snippet doc/src/snippets/code/src_corelib_tools_qmap.cpp 17
+
+ \sa qUpperBound(), lowerBound(), find()
+*/
+
+/*! \fn QMap::const_iterator QMap::upperBound(const Key &key) const
+
+ \overload
+*/
+
+/*! \fn QMap::iterator QMap::insert(const Key &key, const T &value)
+
+ Inserts a new item with the key \a key and a value of \a value.
+
+ If there is already an item with the key \a key, that item's value
+ is replaced with \a value.
+
+ If there are multiple items with the key \a key, the most
+ recently inserted item's value is replaced with \a value.
+
+ \sa insertMulti()
+*/
+
+/*! \fn QMap::iterator QMap::insertMulti(const Key &key, const T &value)
+
+ Inserts a new item with the key \a key and a value of \a value.
+
+ If there is already an item with the same key in the map, this
+ function will simply create a new one. (This behavior is
+ different from insert(), which overwrites the value of an
+ existing item.)
+
+ \sa insert(), values()
+*/
+
+/*! \fn QMap<Key, T> &QMap::unite(const QMap<Key, T> &other)
+
+ Inserts all the items in the \a other map into this map. If a
+ key is common to both maps, the resulting map will contain the
+ key multiple times.
+
+ \sa insertMulti()
+*/
+
+/*! \typedef QMap::Iterator
+
+ Qt-style synonym for QMap::iterator.
+*/
+
+/*! \typedef QMap::ConstIterator
+
+ Qt-style synonym for QMap::const_iterator.
+*/
+
+/*! \typedef QMap::difference_type
+
+ Typedef for ptrdiff_t. Provided for STL compatibility.
+*/
+
+/*! \typedef QMap::key_type
+
+ Typedef for Key. Provided for STL compatibility.
+*/
+
+/*! \typedef QMap::mapped_type
+
+ Typedef for T. Provided for STL compatibility.
+*/
+
+/*! \typedef QMap::size_type
+
+ Typedef for int. Provided for STL compatibility.
+*/
+
+/*!
+ \fn bool QMap::empty() const
+
+ This function is provided for STL compatibility. It is equivalent
+ to isEmpty(), returning true if the map is empty; otherwise
+ returning false.
+*/
+
+/*! \class QMap::iterator
+ \brief The QMap::iterator class provides an STL-style non-const iterator for QMap and QMultiMap.
+
+ QMap features both \l{STL-style iterators} and \l{Java-style
+ iterators}. The STL-style iterators are more low-level and more
+ cumbersome to use; on the other hand, they are slightly faster
+ and, for developers who already know STL, have the advantage of
+ familiarity.
+
+ QMap\<Key, T\>::iterator allows you to iterate over a QMap (or
+ QMultiMap) and to modify the value (but not the key) stored under
+ a particular key. If you want to iterate over a const QMap, you
+ should use QMap::const_iterator. It is generally good practice to
+ use QMap::const_iterator on a non-const QMap as well, unless you
+ need to change the QMap through the iterator. Const iterators are
+ slightly faster, and can improve code readability.
+
+ The default QMap::iterator constructor creates an uninitialized
+ iterator. You must initialize it using a QMap function like
+ QMap::begin(), QMap::end(), or QMap::find() before you can
+ start iterating. Here's a typical loop that prints all the (key,
+ value) pairs stored in a map:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qmap.cpp 18
+
+ Unlike QHash, which stores its items in an arbitrary order, QMap
+ stores its items ordered by key. Items that share the same key
+ (because they were inserted using QMap::insertMulti(), or due to a
+ unite()) will appear consecutively, from the most recently to the
+ least recently inserted value.
+
+ Let's see a few examples of things we can do with a
+ QMap::iterator that we cannot do with a QMap::const_iterator.
+ Here's an example that increments every value stored in the QMap
+ by 2:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qmap.cpp 19
+
+ Here's an example that removes all the items whose key is a
+ string that starts with an underscore character:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qmap.cpp 20
+
+ The call to QMap::erase() removes the item pointed to by the
+ iterator from the map, and returns an iterator to the next item.
+ Here's another way of removing an item while iterating:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qmap.cpp 21
+
+ It might be tempting to write code like this:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qmap.cpp 22
+
+ However, this will potentially crash in \c{++i}, because \c i is
+ a dangling iterator after the call to erase().
+
+ Multiple iterators can be used on the same map. If you add items
+ to the map, existing iterators will remain valid. If you remove
+ items from the map, iterators that point to the removed items
+ will become dangling iterators.
+
+ \sa QMap::const_iterator, QMutableMapIterator
+*/
+
+/*! \fn QMap::iterator::operator QMapData::Node *() const
+
+ \internal
+*/
+
+/*! \typedef QMap::iterator::difference_type
+
+ \internal
+*/
+
+/*! \typedef QMap::iterator::iterator_category
+
+ \internal
+*/
+
+/*! \typedef QMap::iterator::pointer
+
+ \internal
+*/
+
+/*! \typedef QMap::iterator::reference
+
+ \internal
+*/
+
+/*! \typedef QMap::iterator::value_type
+
+ \internal
+*/
+
+/*! \fn QMap::iterator::iterator()
+
+ Constructs an uninitialized iterator.
+
+ Functions like key(), value(), and operator++() must not be
+ called on an uninitialized iterator. Use operator=() to assign a
+ value to it before using it.
+
+ \sa QMap::begin() QMap::end()
+*/
+
+/*! \fn QMap::iterator::iterator(QMapData::Node *node)
+
+ \internal
+*/
+
+/*! \fn const Key &QMap::iterator::key() const
+
+ Returns the current item's key as a const reference.
+
+ There is no direct way of changing an item's key through an
+ iterator, although it can be done by calling QMap::erase()
+ followed by QMap::insert() or QMap::insertMulti().
+
+ \sa value()
+*/
+
+/*! \fn T &QMap::iterator::value() const
+
+ Returns a modifiable reference to the current item's value.
+
+ You can change the value of an item by using value() on
+ the left side of an assignment, for example:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qmap.cpp 23
+
+ \sa key(), operator*()
+*/
+
+/*! \fn T &QMap::iterator::operator*() const
+
+ Returns a modifiable reference to the current item's value.
+
+ Same as value().
+
+ \sa key()
+*/
+
+/*! \fn T *QMap::iterator::operator->() const
+
+ Returns a pointer to the current item's value.
+
+ \sa value()
+*/
+
+/*!
+ \fn bool QMap::iterator::operator==(const iterator &other) const
+ \fn bool QMap::iterator::operator==(const const_iterator &other) const
+
+ Returns true if \a other points to the same item as this
+ iterator; otherwise returns false.
+
+ \sa operator!=()
+*/
+
+/*!
+ \fn bool QMap::iterator::operator!=(const iterator &other) const
+ \fn bool QMap::iterator::operator!=(const const_iterator &other) const
+
+ Returns true if \a other points to a different item than this
+ iterator; otherwise returns false.
+
+ \sa operator==()
+*/
+
+/*! \fn QMap::iterator QMap::iterator::operator++()
+
+ The prefix ++ operator (\c{++i}) advances the iterator to the
+ next item in the map and returns an iterator to the new current
+ item.
+
+ Calling this function on QMap::end() leads to undefined results.
+
+ \sa operator--()
+*/
+
+/*! \fn QMap::iterator QMap::iterator::operator++(int)
+
+ \overload
+
+ The postfix ++ operator (\c{i++}) advances the iterator to the
+ next item in the map and returns an iterator to the previously
+ current item.
+*/
+
+/*! \fn QMap::iterator QMap::iterator::operator--()
+
+ The prefix -- operator (\c{--i}) makes the preceding item
+ current and returns an iterator pointing to the new current item.
+
+ Calling this function on QMap::begin() leads to undefined
+ results.
+
+ \sa operator++()
+*/
+
+/*! \fn QMap::iterator QMap::iterator::operator--(int)
+
+ \overload
+
+ The prefix -- operator (\c{--i}) makes the preceding item
+ current and returns an iterator pointing to the previously
+ current item.
+*/
+
+/*! \fn QMap::iterator QMap::iterator::operator+(int j) const
+
+ Returns an iterator to the item at \a j positions forward from
+ this iterator. (If \a j is negative, the iterator goes backward.)
+
+ This operation can be slow for large \a j values.
+
+ \sa operator-()
+
+*/
+
+/*! \fn QMap::iterator QMap::iterator::operator-(int j) const
+
+ Returns an iterator to the item at \a j positions backward from
+ this iterator. (If \a j is negative, the iterator goes forward.)
+
+ This operation can be slow for large \a j values.
+
+ \sa operator+()
+*/
+
+/*! \fn QMap::iterator &QMap::iterator::operator+=(int j)
+
+ Advances the iterator by \a j items. (If \a j is negative, the
+ iterator goes backward.)
+
+ \sa operator-=(), operator+()
+*/
+
+/*! \fn QMap::iterator &QMap::iterator::operator-=(int j)
+
+ Makes the iterator go back by \a j items. (If \a j is negative,
+ the iterator goes forward.)
+
+ \sa operator+=(), operator-()
+*/
+
+/*! \class QMap::const_iterator
+ \brief The QMap::const_iterator class provides an STL-style const iterator for QMap and QMultiMap.
+
+ QMap features both \l{STL-style iterators} and \l{Java-style
+ iterators}. The STL-style iterators are more low-level and more
+ cumbersome to use; on the other hand, they are slightly faster
+ and, for developers who already know STL, have the advantage of
+ familiarity.
+
+ QMap\<Key, T\>::const_iterator allows you to iterate over a QMap
+ (or a QMultiMap). If you want to modify the QMap as you iterate
+ over it, you must use QMap::iterator instead. It is generally
+ good practice to use QMap::const_iterator on a non-const QMap as
+ well, unless you need to change the QMap through the iterator.
+ Const iterators are slightly faster, and can improve code
+ readability.
+
+ The default QMap::const_iterator constructor creates an
+ uninitialized iterator. You must initialize it using a QMap
+ function like QMap::constBegin(), QMap::constEnd(), or
+ QMap::find() before you can start iterating. Here's a typical
+ loop that prints all the (key, value) pairs stored in a map:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qmap.cpp 24
+
+ Unlike QHash, which stores its items in an arbitrary order, QMap
+ stores its items ordered by key. Items that share the same key
+ (because they were inserted using QMap::insertMulti()) will
+ appear consecutively, from the most recently to the least
+ recently inserted value.
+
+ Multiple iterators can be used on the same map. If you add items
+ to the map, existing iterators will remain valid. If you remove
+ items from the map, iterators that point to the removed items
+ will become dangling iterators.
+
+ \sa QMap::iterator, QMapIterator
+*/
+
+/*! \fn QMap::const_iterator::operator QMapData::Node *() const
+
+ \internal
+*/
+
+/*! \typedef QMap::const_iterator::difference_type
+
+ \internal
+*/
+
+/*! \typedef QMap::const_iterator::iterator_category
+
+ \internal
+*/
+
+/*! \typedef QMap::const_iterator::pointer
+
+ \internal
+*/
+
+/*! \typedef QMap::const_iterator::reference
+
+ \internal
+*/
+
+/*! \typedef QMap::const_iterator::value_type
+
+ \internal
+*/
+
+/*! \fn QMap::const_iterator::const_iterator()
+
+ Constructs an uninitialized iterator.
+
+ Functions like key(), value(), and operator++() must not be
+ called on an uninitialized iterator. Use operator=() to assign a
+ value to it before using it.
+
+ \sa QMap::constBegin() QMap::constEnd()
+*/
+
+/*! \fn QMap::const_iterator::const_iterator(QMapData::Node *node)
+
+ \internal
+*/
+
+/*! \fn QMap::const_iterator::const_iterator(const iterator &other)
+
+ Constructs a copy of \a other.
+*/
+
+/*! \fn const Key &QMap::const_iterator::key() const
+
+ Returns the current item's key.
+
+ \sa value()
+*/
+
+/*! \fn const T &QMap::const_iterator::value() const
+
+ Returns the current item's value.
+
+ \sa key(), operator*()
+*/
+
+/*! \fn const T &QMap::const_iterator::operator*() const
+
+ Returns the current item's value.
+
+ Same as value().
+
+ \sa key()
+*/
+
+/*! \fn const T *QMap::const_iterator::operator->() const
+
+ Returns a pointer to the current item's value.
+
+ \sa value()
+*/
+
+/*! \fn bool QMap::const_iterator::operator==(const const_iterator &other) const
+
+ Returns true if \a other points to the same item as this
+ iterator; otherwise returns false.
+
+ \sa operator!=()
+*/
+
+/*! \fn bool QMap::const_iterator::operator!=(const const_iterator &other) const
+
+ Returns true if \a other points to a different item than this
+ iterator; otherwise returns false.
+
+ \sa operator==()
+*/
+
+/*! \fn QMap::const_iterator QMap::const_iterator::operator++()
+
+ The prefix ++ operator (\c{++i}) advances the iterator to the
+ next item in the map and returns an iterator to the new current
+ item.
+
+ Calling this function on QMap::end() leads to undefined results.
+
+ \sa operator--()
+*/
+
+/*! \fn QMap::const_iterator QMap::const_iterator::operator++(int)
+
+ \overload
+
+ The postfix ++ operator (\c{i++}) advances the iterator to the
+ next item in the map and returns an iterator to the previously
+ current item.
+*/
+
+/*! \fn QMap::const_iterator &QMap::const_iterator::operator--()
+
+ The prefix -- operator (\c{--i}) makes the preceding item
+ current and returns an iterator pointing to the new current item.
+
+ Calling this function on QMap::begin() leads to undefined
+ results.
+
+ \sa operator++()
+*/
+
+/*! \fn QMap::const_iterator QMap::const_iterator::operator--(int)
+
+ \overload
+
+ The postfix -- operator (\c{i--}) makes the preceding item
+ current and returns an iterator pointing to the previously
+ current item.
+*/
+
+/*! \fn QMap::const_iterator QMap::const_iterator::operator+(int j) const
+
+ Returns an iterator to the item at \a j positions forward from
+ this iterator. (If \a j is negative, the iterator goes backward.)
+
+ This operation can be slow for large \a j values.
+
+ \sa operator-()
+*/
+
+/*! \fn QMap::const_iterator QMap::const_iterator::operator-(int j) const
+
+ Returns an iterator to the item at \a j positions backward from
+ this iterator. (If \a j is negative, the iterator goes forward.)
+
+ This operation can be slow for large \a j values.
+
+ \sa operator+()
+*/
+
+/*! \fn QMap::const_iterator &QMap::const_iterator::operator+=(int j)
+
+ Advances the iterator by \a j items. (If \a j is negative, the
+ iterator goes backward.)
+
+ This operation can be slow for large \a j values.
+
+ \sa operator-=(), operator+()
+*/
+
+/*! \fn QMap::const_iterator &QMap::const_iterator::operator-=(int j)
+
+ Makes the iterator go back by \a j items. (If \a j is negative,
+ the iterator goes forward.)
+
+ This operation can be slow for large \a j values.
+
+ \sa operator+=(), operator-()
+*/
+
+/*! \fn QDataStream &operator<<(QDataStream &out, const QMap<Key, T> &map)
+ \relates QMap
+
+ Writes the map \a map to stream \a out.
+
+ This function requires the key and value types to implement \c
+ operator<<().
+
+ \sa \link datastreamformat.html Format of the QDataStream operators \endlink
+*/
+
+/*! \fn QDataStream &operator>>(QDataStream &in, QMap<Key, T> &map)
+ \relates QMap
+
+ Reads a map from stream \a in into \a map.
+
+ This function requires the key and value types to implement \c
+ operator>>().
+
+ \sa \link datastreamformat.html Format of the QDataStream operators \endlink
+*/
+
+/*! \class QMultiMap
+ \brief The QMultiMap class is a convenience QMap subclass that provides multi-valued maps.
+
+ \ingroup tools
+ \ingroup shared
+ \mainclass
+ \reentrant
+
+ QMultiMap\<Key, T\> is one of Qt's generic \l{container classes}.
+ It inherits QMap and extends it with a few convenience functions
+ that make it more suitable than QMap for storing multi-valued
+ maps. A multi-valued map is a map that allows multiple values
+ with the same key; QMap normally doesn't allow that, unless you
+ call QMap::insertMulti().
+
+ Because QMultiMap inherits QMap, all of QMap's functionality also
+ applies to QMultiMap. For example, you can use isEmpty() to test
+ whether the map is empty, and you can traverse a QMultiMap using
+ QMap's iterator classes (for example, QMapIterator). But in
+ addition, it provides an insert() function that corresponds to
+ QMap::insertMulti(), and a replace() function that corresponds to
+ QMap::insert(). It also provides convenient operator+() and
+ operator+=().
+
+ Example:
+ \snippet doc/src/snippets/code/src_corelib_tools_qmap.cpp 25
+
+ Unlike QMap, QMultiMap provides no operator[]. Use value() or
+ replace() if you want to access the most recently inserted item
+ with a certain key.
+
+ If you want to retrieve all the values for a single key, you can
+ use values(const Key &key), which returns a QList<T>:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qmap.cpp 26
+
+ The items that share the same key are available from most
+ recently to least recently inserted.
+
+ If you prefer the STL-style iterators, you can call find() to get
+ the iterator for the first item with a key and iterate from
+ there:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qmap.cpp 27
+
+ QMultiMap's key and value data types must be \l{assignable data
+ types}. This covers most data types you are likely to encounter,
+ but the compiler won't let you, for example, store a QWidget as a
+ value; instead, store a QWidget *. In addition, QMultiMap's key type
+ must provide operator<(). See the QMap documentation for details.
+
+ \sa QMap, QMapIterator, QMutableMapIterator, QMultiHash
+*/
+
+/*! \fn QMultiMap::QMultiMap()
+
+ Constructs an empty map.
+*/
+
+/*! \fn QMultiMap::QMultiMap(const QMap<Key, T> &other)
+
+ Constructs a copy of \a other (which can be a QMap or a
+ QMultiMap).
+
+ \sa operator=()
+*/
+
+/*! \fn QMultiMap::iterator QMultiMap::replace(const Key &key, const T &value)
+
+ Inserts a new item with the key \a key and a value of \a value.
+
+ If there is already an item with the key \a key, that item's value
+ is replaced with \a value.
+
+ If there are multiple items with the key \a key, the most
+ recently inserted item's value is replaced with \a value.
+
+ \sa insert()
+*/
+
+/*! \fn QMultiMap::iterator QMultiMap::insert(const Key &key, const T &value)
+
+ Inserts a new item with the key \a key and a value of \a value.
+
+ If there is already an item with the same key in the map, this
+ function will simply create a new one. (This behavior is
+ different from replace(), which overwrites the value of an
+ existing item.)
+
+ \sa replace()
+*/
+
+/*! \fn QMultiMap &QMultiMap::operator+=(const QMultiMap &other)
+
+ Inserts all the items in the \a other map into this map and
+ returns a reference to this map.
+
+ \sa insert(), operator+()
+*/
+
+/*! \fn QMultiMap QMultiMap::operator+(const QMultiMap &other) const
+
+ Returns a map that contains all the items in this map in
+ addition to all the items in \a other. If a key is common to both
+ maps, the resulting map will contain the key multiple times.
+
+ \sa operator+=()
+*/
+
+/*!
+ \fn bool QMultiMap::contains(const Key &key, const T &value) const
+ \since 4.3
+
+ Returns true if the map contains an item with key \a key and
+ value \a value; otherwise returns false.
+
+ \sa QMap::contains()
+*/
+
+/*!
+ \fn bool QMultiMap::contains(const Key &key) const
+ \overload
+ \sa QMap::contains()
+*/
+
+/*!
+ \fn int QMultiMap::remove(const Key &key, const T &value)
+ \since 4.3
+
+ Removes all the items that have the key \a key and the value \a
+ value from the map. Returns the number of items removed.
+
+ \sa QMap::remove()
+*/
+
+/*!
+ \fn int QMultiMap::remove(const Key &key)
+ \overload
+ \sa QMap::remove()
+*/
+
+/*!
+ \fn int QMultiMap::count(const Key &key, const T &value) const
+ \since 4.3
+
+ Returns the number of items with key \a key and value \a value.
+
+ \sa QMap::count()
+*/
+
+/*!
+ \fn int QMultiMap::count(const Key &key) const
+ \overload
+ \sa QMap::count()
+*/
+
+/*!
+ \fn int QMultiMap::count() const
+ \overload
+ \sa QMap::count()
+*/
+
+/*!
+ \fn typename QMap<Key, T>::iterator QMultiMap::find(const Key &key, const T &value)
+ \since 4.3
+
+ Returns an iterator pointing to the item with key \a key and
+ value \a value in the map.
+
+ If the map contains no such item, the function returns end().
+
+ If the map contains multiple items with key \a key, this
+ function returns an iterator that points to the most recently
+ inserted value.
+
+ \sa QMap::find()
+*/
+
+/*!
+ \fn typename QMap<Key, T>::iterator QMultiMap::find(const Key &key)
+ \overload
+ \sa QMap::find()
+*/
+
+/*!
+ \fn typename QMap<Key, T>::const_iterator QMultiMap::find(const Key &key, const T &value) const
+ \since 4.3
+ \overload
+
+ Returns a const iterator pointing to the item with the given \a key and
+ \a value in the map.
+
+ If the map contains no such item, the function returns end().
+
+ If the map contains multiple items with the specified \a key, this
+ function returns a const iterator that points to the most recently
+ inserted value.
+
+ \sa QMap::find()
+*/
+
+/*!
+ \fn typename QMap<Key, T>::const_iterator QMultiMap::find(const Key &key) const
+ \since 4.3
+ \overload
+ \sa QMap::find()
+*/
+
+/*!
+ \fn typename QMap<Key, T>::const_iterator QMultiMap::constFind(const Key &key, const T &value) const
+ \since 4.3
+
+ Returns an iterator pointing to the item with key \a key and the
+ value \a value in the map.
+
+ If the map contains no such item, the function returns
+ constEnd().
+
+ \sa QMap::constFind()
+*/
+
+/*!
+ \fn typename QMap<Key, T>::const_iterator QMultiMap::constFind(const Key &key) const
+ \overload
+ \sa QMap::constFind()
+*/
+
+/*!
+ \fn T &QMap::iterator::data() const
+
+ Use value() instead.
+*/
+
+/*!
+ \fn const T &QMap::const_iterator::data() const
+
+ Use value() instead.
+*/
+
+/*!
+ \fn iterator QMap::remove(iterator it)
+
+ Use erase(\a it) instead.
+*/
+
+/*!
+ \fn void QMap::erase(const Key &key)
+
+ Use remove(\a key) instead.
+*/
+
+/*!
+ \fn iterator QMap::insert(const Key &key, const T &value, bool overwrite);
+
+ Use the two-argument insert() overload instead. If you don't want
+ to overwrite, call contains() beforehand.
+
+ \oldcode
+ QMap<QString, int> map;
+ ...
+ map.insert("delay", 30000, false);
+ \newcode
+ QMap<QString, int> map;
+ ...
+ if (!map.contains("delay"))
+ map.insert("delay", 30000);
+ \endcode
+*/
+
+/*!
+ \fn iterator QMap::replace(const Key &key, const T &value)
+
+ Use remove() then insert().
+*/
+
+QT_END_NAMESPACE
diff --git a/src/corelib/tools/qmap.h b/src/corelib/tools/qmap.h
new file mode 100644
index 0000000000..5f13e5a7b7
--- /dev/null
+++ b/src/corelib/tools/qmap.h
@@ -0,0 +1,1026 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMAP_H
+#define QMAP_H
+
+#include <QtCore/qatomic.h>
+#include <QtCore/qiterator.h>
+#include <QtCore/qlist.h>
+
+#ifndef QT_NO_STL
+#include <map>
+#endif
+
+#include <new>
+#undef QT_MAP_DEBUG
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Core)
+
+struct Q_CORE_EXPORT QMapData
+{
+ struct Node {
+ Node *backward;
+ Node *forward[1];
+ };
+ enum { LastLevel = 11, Sparseness = 3 };
+
+ QMapData *backward;
+ QMapData *forward[QMapData::LastLevel + 1];
+ QBasicAtomicInt ref;
+ int topLevel;
+ int size;
+ uint randomBits;
+ uint insertInOrder : 1;
+ uint sharable : 1;
+
+ static QMapData *createData();
+ void continueFreeData(int offset);
+ Node *node_create(Node *update[], int offset);
+ void node_delete(Node *update[], int offset, Node *node);
+#ifdef QT_QMAP_DEBUG
+ uint adjust_ptr(Node *node);
+ void dump();
+#endif
+
+ static QMapData shared_null;
+};
+
+
+/*
+ QMap uses qMapLessThanKey() to compare keys. The default
+ implementation uses operator<(). For pointer types,
+ qMapLessThanKey() casts the pointers to integers before it
+ compares them, because operator<() is undefined on pointers
+ that come from different memory blocks. (In practice, this
+ is only a problem when running a program such as
+ BoundsChecker.)
+*/
+
+template <class Key> inline bool qMapLessThanKey(const Key &key1, const Key &key2)
+{
+ return key1 < key2;
+}
+
+#ifndef QT_NO_PARTIAL_TEMPLATE_SPECIALIZATION
+template <class Ptr> inline bool qMapLessThanKey(Ptr *key1, Ptr *key2)
+{
+ Q_ASSERT(sizeof(quintptr) == sizeof(Ptr *));
+ return quintptr(key1) < quintptr(key2);
+}
+
+template <class Ptr> inline bool qMapLessThanKey(const Ptr *key1, const Ptr *key2)
+{
+ Q_ASSERT(sizeof(quintptr) == sizeof(const Ptr *));
+ return quintptr(key1) < quintptr(key2);
+}
+#endif // QT_NO_PARTIAL_TEMPLATE_SPECIALIZATION
+
+template <class Key, class T>
+struct QMapNode {
+ Key key;
+ T value;
+ QMapData::Node *backward;
+ QMapData::Node *forward[1];
+};
+
+template <class Key, class T>
+struct QMapPayloadNode
+{
+ Key key;
+ T value;
+ QMapData::Node *backward;
+};
+
+template <class Key, class T>
+class QMap
+{
+ typedef QMapNode<Key, T> Node;
+ typedef QMapPayloadNode<Key, T> PayloadNode;
+
+ union {
+ QMapData *d;
+ QMapData::Node *e;
+ };
+
+ static inline int payload() { return sizeof(PayloadNode) - sizeof(QMapData::Node *); }
+ static inline Node *concrete(QMapData::Node *node) {
+ return reinterpret_cast<Node *>(reinterpret_cast<char *>(node) - payload());
+ }
+
+public:
+ inline QMap() : d(&QMapData::shared_null) { d->ref.ref(); }
+ inline QMap(const QMap<Key, T> &other) : d(other.d)
+ { d->ref.ref(); if (!d->sharable) detach(); }
+ inline ~QMap() { if (!d) return; if (!d->ref.deref()) freeData(d); }
+
+ QMap<Key, T> &operator=(const QMap<Key, T> &other);
+#ifndef QT_NO_STL
+ explicit QMap(const typename std::map<Key, T> &other);
+ std::map<Key, T> toStdMap() const;
+#endif
+
+ bool operator==(const QMap<Key, T> &other) const;
+ inline bool operator!=(const QMap<Key, T> &other) const { return !(*this == other); }
+
+ inline int size() const { return d->size; }
+
+ inline bool isEmpty() const { return d->size == 0; }
+
+ inline void detach() { if (d->ref != 1) detach_helper(); }
+ inline bool isDetached() const { return d->ref == 1; }
+ inline void setSharable(bool sharable) { if (!sharable) detach(); d->sharable = sharable; }
+ inline void setInsertInOrder(bool ordered) { d->insertInOrder = ordered; }
+
+ void clear();
+
+ int remove(const Key &key);
+ T take(const Key &key);
+
+ bool contains(const Key &key) const;
+ const Key key(const T &value) const;
+ const Key key(const T &value, const Key &defaultKey) const;
+ const T value(const Key &key) const;
+ const T value(const Key &key, const T &defaultValue) const;
+ T &operator[](const Key &key);
+ const T operator[](const Key &key) const;
+
+ QList<Key> uniqueKeys() const;
+ QList<Key> keys() const;
+ QList<Key> keys(const T &value) const;
+ QList<T> values() const;
+ QList<T> values(const Key &key) const;
+ int count(const Key &key) const;
+
+ class const_iterator;
+
+ class iterator
+ {
+ friend class const_iterator;
+ QMapData::Node *i;
+
+ public:
+ typedef std::bidirectional_iterator_tag iterator_category;
+ typedef ptrdiff_t difference_type;
+ typedef T value_type;
+ typedef T *pointer;
+ typedef T &reference;
+
+ // ### Qt 5: get rid of 'operator Node *'
+ inline operator QMapData::Node *() const { return i; }
+ inline iterator() : i(0) { }
+ inline iterator(QMapData::Node *node) : i(node) { }
+
+ inline const Key &key() const { return concrete(i)->key; }
+ inline T &value() const { return concrete(i)->value; }
+#ifdef QT3_SUPPORT
+ inline QT3_SUPPORT T &data() const { return concrete(i)->value; }
+#endif
+ inline T &operator*() const { return concrete(i)->value; }
+ inline T *operator->() const { return &concrete(i)->value; }
+ inline bool operator==(const iterator &o) const { return i == o.i; }
+ inline bool operator!=(const iterator &o) const { return i != o.i; }
+
+ inline iterator &operator++() {
+ i = i->forward[0];
+ return *this;
+ }
+ inline iterator operator++(int) {
+ iterator r = *this;
+ i = i->forward[0];
+ return r;
+ }
+ inline iterator &operator--() {
+ i = i->backward;
+ return *this;
+ }
+ inline iterator operator--(int) {
+ iterator r = *this;
+ i = i->backward;
+ return r;
+ }
+ inline iterator operator+(int j) const
+ { iterator r = *this; if (j > 0) while (j--) ++r; else while (j++) --r; return r; }
+ inline iterator operator-(int j) const { return operator+(-j); }
+ inline iterator &operator+=(int j) { return *this = *this + j; }
+ inline iterator &operator-=(int j) { return *this = *this - j; }
+
+ // ### Qt 5: not sure this is necessary anymore
+#ifdef QT_STRICT_ITERATORS
+ private:
+#else
+ public:
+#endif
+ inline bool operator==(const const_iterator &o) const
+ { return i == o.i; }
+ inline bool operator!=(const const_iterator &o) const
+ { return i != o.i; }
+
+ private:
+ // ### Qt 5: remove
+ inline operator bool() const { return false; }
+ };
+ friend class iterator;
+
+ class const_iterator
+ {
+ friend class iterator;
+ QMapData::Node *i;
+
+ public:
+ typedef std::bidirectional_iterator_tag iterator_category;
+ typedef ptrdiff_t difference_type;
+ typedef T value_type;
+ typedef const T *pointer;
+ typedef const T &reference;
+
+ // ### Qt 5: get rid of 'operator Node *'
+ inline operator QMapData::Node *() const { return i; }
+ inline const_iterator() : i(0) { }
+ inline const_iterator(QMapData::Node *node) : i(node) { }
+#ifdef QT_STRICT_ITERATORS
+ explicit inline const_iterator(const iterator &o)
+#else
+ inline const_iterator(const iterator &o)
+#endif
+ { i = o.i; }
+
+ inline const Key &key() const { return concrete(i)->key; }
+ inline const T &value() const { return concrete(i)->value; }
+#ifdef QT3_SUPPORT
+ inline QT3_SUPPORT const T &data() const { return concrete(i)->value; }
+#endif
+ inline const T &operator*() const { return concrete(i)->value; }
+ inline const T *operator->() const { return &concrete(i)->value; }
+ inline bool operator==(const const_iterator &o) const { return i == o.i; }
+ inline bool operator!=(const const_iterator &o) const { return i != o.i; }
+
+ inline const_iterator &operator++() {
+ i = i->forward[0];
+ return *this;
+ }
+ inline const_iterator operator++(int) {
+ const_iterator r = *this;
+ i = i->forward[0];
+ return r;
+ }
+ inline const_iterator &operator--() {
+ i = i->backward;
+ return *this;
+ }
+ inline const_iterator operator--(int) {
+ const_iterator r = *this;
+ i = i->backward;
+ return r;
+ }
+ inline const_iterator operator+(int j) const
+ { const_iterator r = *this; if (j > 0) while (j--) ++r; else while (j++) --r; return r; }
+ inline const_iterator operator-(int j) const { return operator+(-j); }
+ inline const_iterator &operator+=(int j) { return *this = *this + j; }
+ inline const_iterator &operator-=(int j) { return *this = *this - j; }
+
+ // ### Qt 5: not sure this is necessary anymore
+#ifdef QT_STRICT_ITERATORS
+ private:
+ inline bool operator==(const iterator &o) { return operator==(const_iterator(o)); }
+ inline bool operator!=(const iterator &o) { return operator!=(const_iterator(o)); }
+#endif
+
+ private:
+ // ### Qt 5: remove
+ inline operator bool() const { return false; }
+ };
+ friend class const_iterator;
+
+ // STL style
+ inline iterator begin() { detach(); return iterator(e->forward[0]); }
+ inline const_iterator begin() const { return const_iterator(e->forward[0]); }
+ inline const_iterator constBegin() const { return const_iterator(e->forward[0]); }
+ inline iterator end() {
+ detach();
+ return iterator(e);
+ }
+ inline const_iterator end() const { return const_iterator(e); }
+ inline const_iterator constEnd() const { return const_iterator(e); }
+ iterator erase(iterator it);
+#ifdef QT3_SUPPORT
+ inline QT3_SUPPORT iterator remove(iterator it) { return erase(it); }
+ inline QT3_SUPPORT void erase(const Key &aKey) { remove(aKey); }
+#endif
+
+ // more Qt
+ typedef iterator Iterator;
+ typedef const_iterator ConstIterator;
+ inline int count() const { return d->size; }
+ iterator find(const Key &key);
+ const_iterator find(const Key &key) const;
+ const_iterator constFind(const Key &key) const;
+ iterator lowerBound(const Key &key);
+ const_iterator lowerBound(const Key &key) const;
+ iterator upperBound(const Key &key);
+ const_iterator upperBound(const Key &key) const;
+ iterator insert(const Key &key, const T &value);
+#ifdef QT3_SUPPORT
+ QT3_SUPPORT iterator insert(const Key &key, const T &value, bool overwrite);
+#endif
+ iterator insertMulti(const Key &key, const T &value);
+#ifdef QT3_SUPPORT
+ inline QT3_SUPPORT iterator replace(const Key &aKey, const T &aValue) { return insert(aKey, aValue); }
+#endif
+ QMap<Key, T> &unite(const QMap<Key, T> &other);
+
+ // STL compatibility
+ typedef Key key_type;
+ typedef T mapped_type;
+ typedef ptrdiff_t difference_type;
+ typedef int size_type;
+ inline bool empty() const { return isEmpty(); }
+
+#ifdef QT_QMAP_DEBUG
+ inline void dump() const { d->dump(); }
+#endif
+
+private:
+ void detach_helper();
+ void freeData(QMapData *d);
+ QMapData::Node *findNode(const Key &key) const;
+ QMapData::Node *mutableFindNode(QMapData::Node *update[], const Key &key) const;
+ QMapData::Node *node_create(QMapData *d, QMapData::Node *update[], const Key &key,
+ const T &value);
+};
+
+template <class Key, class T>
+Q_INLINE_TEMPLATE QMap<Key, T> &QMap<Key, T>::operator=(const QMap<Key, T> &other)
+{
+ if (d != other.d) {
+ other.d->ref.ref();
+ if (!d->ref.deref())
+ freeData(d);
+ d = other.d;
+ if (!d->sharable)
+ detach_helper();
+ }
+ return *this;
+}
+
+template <class Key, class T>
+Q_INLINE_TEMPLATE void QMap<Key, T>::clear()
+{
+ *this = QMap<Key, T>();
+}
+
+template <class Key, class T>
+Q_INLINE_TEMPLATE typename QMapData::Node *
+QMap<Key, T>::node_create(QMapData *adt, QMapData::Node *aupdate[], const Key &akey, const T &avalue)
+{
+ QMapData::Node *abstractNode = adt->node_create(aupdate, payload());
+ Node *concreteNode = concrete(abstractNode);
+ new (&concreteNode->key) Key(akey);
+ new (&concreteNode->value) T(avalue);
+ return abstractNode;
+}
+
+template <class Key, class T>
+Q_INLINE_TEMPLATE QMapData::Node *QMap<Key, T>::findNode(const Key &akey) const
+{
+ QMapData::Node *cur = e;
+ QMapData::Node *next = e;
+
+ for (int i = d->topLevel; i >= 0; i--) {
+ while ((next = cur->forward[i]) != e && qMapLessThanKey<Key>(concrete(next)->key, akey))
+ cur = next;
+ }
+
+ if (next != e && !qMapLessThanKey<Key>(akey, concrete(next)->key)) {
+ return next;
+ } else {
+ return e;
+ }
+}
+
+template <class Key, class T>
+Q_INLINE_TEMPLATE const T QMap<Key, T>::value(const Key &akey) const
+{
+ QMapData::Node *node;
+ if (d->size == 0 || (node = findNode(akey)) == e) {
+ return T();
+ } else {
+ return concrete(node)->value;
+ }
+}
+
+template <class Key, class T>
+Q_INLINE_TEMPLATE const T QMap<Key, T>::value(const Key &akey, const T &adefaultValue) const
+{
+ QMapData::Node *node;
+ if (d->size == 0 || (node = findNode(akey)) == e) {
+ return adefaultValue;
+ } else {
+ return concrete(node)->value;
+ }
+}
+
+template <class Key, class T>
+Q_INLINE_TEMPLATE const T QMap<Key, T>::operator[](const Key &akey) const
+{
+ return value(akey);
+}
+
+template <class Key, class T>
+Q_INLINE_TEMPLATE T &QMap<Key, T>::operator[](const Key &akey)
+{
+ detach();
+
+ QMapData::Node *update[QMapData::LastLevel + 1];
+ QMapData::Node *node = mutableFindNode(update, akey);
+ if (node == e)
+ node = node_create(d, update, akey, T());
+ return concrete(node)->value;
+}
+
+template <class Key, class T>
+Q_INLINE_TEMPLATE int QMap<Key, T>::count(const Key &akey) const
+{
+ int cnt = 0;
+ QMapData::Node *node = findNode(akey);
+ if (node != e) {
+ do {
+ ++cnt;
+ node = node->forward[0];
+ } while (node != e && !qMapLessThanKey<Key>(akey, concrete(node)->key));
+ }
+ return cnt;
+}
+
+template <class Key, class T>
+Q_INLINE_TEMPLATE bool QMap<Key, T>::contains(const Key &akey) const
+{
+ return findNode(akey) != e;
+}
+
+template <class Key, class T>
+Q_INLINE_TEMPLATE typename QMap<Key, T>::iterator QMap<Key, T>::insert(const Key &akey,
+ const T &avalue)
+{
+ detach();
+
+ QMapData::Node *update[QMapData::LastLevel + 1];
+ QMapData::Node *node = mutableFindNode(update, akey);
+ if (node == e) {
+ node = node_create(d, update, akey, avalue);
+ } else {
+ concrete(node)->value = avalue;
+ }
+ return iterator(node);
+}
+
+#ifdef QT3_SUPPORT
+template <class Key, class T>
+Q_INLINE_TEMPLATE typename QMap<Key, T>::iterator QMap<Key, T>::insert(const Key &akey,
+ const T &avalue,
+ bool aoverwrite)
+{
+ detach();
+
+ QMapData::Node *update[QMapData::LastLevel + 1];
+ QMapData::Node *node = mutableFindNode(update, akey);
+ if (node == e) {
+ node = node_create(d, update, akey, avalue);
+ } else {
+ if (aoverwrite)
+ concrete(node)->value = avalue;
+ }
+ return iterator(node);
+}
+#endif
+
+template <class Key, class T>
+Q_INLINE_TEMPLATE typename QMap<Key, T>::iterator QMap<Key, T>::insertMulti(const Key &akey,
+ const T &avalue)
+{
+ detach();
+
+ QMapData::Node *update[QMapData::LastLevel + 1];
+ mutableFindNode(update, akey);
+ return iterator(node_create(d, update, akey, avalue));
+}
+
+template <class Key, class T>
+Q_INLINE_TEMPLATE typename QMap<Key, T>::const_iterator QMap<Key, T>::find(const Key &akey) const
+{
+ return const_iterator(findNode(akey));
+}
+
+template <class Key, class T>
+Q_INLINE_TEMPLATE typename QMap<Key, T>::const_iterator QMap<Key, T>::constFind(const Key &akey) const
+{
+ return const_iterator(findNode(akey));
+}
+
+template <class Key, class T>
+Q_INLINE_TEMPLATE typename QMap<Key, T>::iterator QMap<Key, T>::find(const Key &akey)
+{
+ detach();
+ return iterator(findNode(akey));
+}
+
+template <class Key, class T>
+Q_INLINE_TEMPLATE QMap<Key, T> &QMap<Key, T>::unite(const QMap<Key, T> &other)
+{
+ QMap<Key, T> copy(other);
+ const_iterator it = copy.constEnd();
+ const const_iterator b = copy.constBegin();
+ while (it != b) {
+ --it;
+ insertMulti(it.key(), it.value());
+ }
+ return *this;
+}
+
+template <class Key, class T>
+Q_OUTOFLINE_TEMPLATE void QMap<Key, T>::freeData(QMapData *x)
+{
+ if (QTypeInfo<Key>::isComplex || QTypeInfo<T>::isComplex) {
+ QMapData::Node *y = reinterpret_cast<QMapData::Node *>(x);
+ QMapData::Node *cur = y;
+ QMapData::Node *next = cur->forward[0];
+ while (next != y) {
+ cur = next;
+ next = cur->forward[0];
+#if defined(_MSC_VER) && (_MSC_VER >= 1300)
+#pragma warning(disable:4189)
+#endif
+ Node *concreteNode = concrete(cur);
+ concreteNode->key.~Key();
+ concreteNode->value.~T();
+#if defined(_MSC_VER) && (_MSC_VER >= 1300)
+#pragma warning(default:4189)
+#endif
+ }
+ }
+ x->continueFreeData(payload());
+}
+
+template <class Key, class T>
+Q_OUTOFLINE_TEMPLATE int QMap<Key, T>::remove(const Key &akey)
+{
+ detach();
+
+ QMapData::Node *update[QMapData::LastLevel + 1];
+ QMapData::Node *cur = e;
+ QMapData::Node *next = e;
+ int oldSize = d->size;
+
+ for (int i = d->topLevel; i >= 0; i--) {
+ while ((next = cur->forward[i]) != e && qMapLessThanKey<Key>(concrete(next)->key, akey))
+ cur = next;
+ update[i] = cur;
+ }
+
+ if (next != e && !qMapLessThanKey<Key>(akey, concrete(next)->key)) {
+ bool deleteNext = true;
+ do {
+ cur = next;
+ next = cur->forward[0];
+ deleteNext = (next != e && !qMapLessThanKey<Key>(concrete(cur)->key, concrete(next)->key));
+ concrete(cur)->key.~Key();
+ concrete(cur)->value.~T();
+ d->node_delete(update, payload(), cur);
+ } while (deleteNext);
+ }
+ return oldSize - d->size;
+}
+
+template <class Key, class T>
+Q_OUTOFLINE_TEMPLATE T QMap<Key, T>::take(const Key &akey)
+{
+ detach();
+
+ QMapData::Node *update[QMapData::LastLevel + 1];
+ QMapData::Node *cur = e;
+ QMapData::Node *next = e;
+
+ for (int i = d->topLevel; i >= 0; i--) {
+ while ((next = cur->forward[i]) != e && qMapLessThanKey<Key>(concrete(next)->key, akey))
+ cur = next;
+ update[i] = cur;
+ }
+
+ if (next != e && !qMapLessThanKey<Key>(akey, concrete(next)->key)) {
+ T t = concrete(next)->value;
+ concrete(next)->key.~Key();
+ concrete(next)->value.~T();
+ d->node_delete(update, payload(), next);
+ return t;
+ }
+ return T();
+}
+
+template <class Key, class T>
+Q_OUTOFLINE_TEMPLATE typename QMap<Key, T>::iterator QMap<Key, T>::erase(iterator it)
+{
+ QMapData::Node *update[QMapData::LastLevel + 1];
+ QMapData::Node *cur = e;
+ QMapData::Node *next = e;
+
+ if (it == iterator(e))
+ return it;
+
+ for (int i = d->topLevel; i >= 0; i--) {
+ while ((next = cur->forward[i]) != e && qMapLessThanKey<Key>(concrete(next)->key, it.key()))
+ cur = next;
+ update[i] = cur;
+ }
+
+ while (next != e) {
+ cur = next;
+ next = cur->forward[0];
+ if (cur == it) {
+ concrete(cur)->key.~Key();
+ concrete(cur)->value.~T();
+ d->node_delete(update, payload(), cur);
+ return iterator(next);
+ }
+
+ for (int i = 0; i <= d->topLevel; ++i) {
+ if (update[i]->forward[i] != cur)
+ break;
+ update[i] = cur;
+ }
+ }
+ return end();
+}
+
+template <class Key, class T>
+Q_OUTOFLINE_TEMPLATE void QMap<Key, T>::detach_helper()
+{
+ union { QMapData *d; QMapData::Node *e; } x;
+ x.d = QMapData::createData();
+ if (d->size) {
+ x.d->insertInOrder = true;
+ QMapData::Node *update[QMapData::LastLevel + 1];
+ QMapData::Node *cur = e->forward[0];
+ update[0] = x.e;
+ while (cur != e) {
+ Node *concreteNode = concrete(cur);
+ node_create(x.d, update, concreteNode->key, concreteNode->value);
+ cur = cur->forward[0];
+ }
+ x.d->insertInOrder = false;
+ }
+ if (!d->ref.deref())
+ freeData(d);
+ d = x.d;
+}
+
+template <class Key, class T>
+Q_OUTOFLINE_TEMPLATE QMapData::Node *QMap<Key, T>::mutableFindNode(QMapData::Node *aupdate[],
+ const Key &akey) const
+{
+ QMapData::Node *cur = e;
+ QMapData::Node *next = e;
+
+ for (int i = d->topLevel; i >= 0; i--) {
+ while ((next = cur->forward[i]) != e && qMapLessThanKey<Key>(concrete(next)->key, akey))
+ cur = next;
+ aupdate[i] = cur;
+ }
+ if (next != e && !qMapLessThanKey<Key>(akey, concrete(next)->key)) {
+ return next;
+ } else {
+ return e;
+ }
+}
+
+template <class Key, class T>
+Q_OUTOFLINE_TEMPLATE QList<Key> QMap<Key, T>::uniqueKeys() const
+{
+ QList<Key> res;
+ const_iterator i = begin();
+ if (i != end()) {
+ for (;;) {
+ const Key &aKey = i.key();
+ res.append(aKey);
+ do {
+ if (++i == end())
+ goto break_out_of_outer_loop;
+ } while (!(aKey < i.key())); // loop while (key == i.key())
+ }
+ }
+break_out_of_outer_loop:
+ return res;
+}
+
+template <class Key, class T>
+Q_OUTOFLINE_TEMPLATE QList<Key> QMap<Key, T>::keys() const
+{
+ QList<Key> res;
+ const_iterator i = begin();
+ while (i != end()) {
+ res.append(i.key());
+ ++i;
+ }
+ return res;
+}
+
+template <class Key, class T>
+Q_OUTOFLINE_TEMPLATE QList<Key> QMap<Key, T>::keys(const T &avalue) const
+{
+ QList<Key> res;
+ const_iterator i = begin();
+ while (i != end()) {
+ if (i.value() == avalue)
+ res.append(i.key());
+ ++i;
+ }
+ return res;
+}
+
+template <class Key, class T>
+Q_OUTOFLINE_TEMPLATE const Key QMap<Key, T>::key(const T &avalue) const
+{
+ return key(avalue, Key());
+}
+
+template <class Key, class T>
+Q_OUTOFLINE_TEMPLATE const Key QMap<Key, T>::key(const T &avalue, const Key &defaultKey) const
+{
+ const_iterator i = begin();
+ while (i != end()) {
+ if (i.value() == avalue)
+ return i.key();
+ ++i;
+ }
+
+ return defaultKey;
+}
+
+template <class Key, class T>
+Q_OUTOFLINE_TEMPLATE QList<T> QMap<Key, T>::values() const
+{
+ QList<T> res;
+ const_iterator i = begin();
+ while (i != end()) {
+ res.append(i.value());
+ ++i;
+ }
+ return res;
+}
+
+template <class Key, class T>
+Q_OUTOFLINE_TEMPLATE QList<T> QMap<Key, T>::values(const Key &akey) const
+{
+ QList<T> res;
+ QMapData::Node *node = findNode(akey);
+ if (node != e) {
+ do {
+ res.append(concrete(node)->value);
+ node = node->forward[0];
+ } while (node != e && !qMapLessThanKey<Key>(akey, concrete(node)->key));
+ }
+ return res;
+}
+
+template <class Key, class T>
+Q_INLINE_TEMPLATE typename QMap<Key, T>::const_iterator
+QMap<Key, T>::lowerBound(const Key &akey) const
+{
+ QMapData::Node *update[QMapData::LastLevel + 1];
+ mutableFindNode(update, akey);
+ return const_iterator(update[0]->forward[0]);
+}
+
+template <class Key, class T>
+Q_INLINE_TEMPLATE typename QMap<Key, T>::iterator QMap<Key, T>::lowerBound(const Key &akey)
+{
+ detach();
+ return static_cast<QMapData::Node *>(const_cast<const QMap *>(this)->lowerBound(akey));
+}
+
+template <class Key, class T>
+Q_INLINE_TEMPLATE typename QMap<Key, T>::const_iterator
+QMap<Key, T>::upperBound(const Key &akey) const
+{
+ QMapData::Node *update[QMapData::LastLevel + 1];
+ mutableFindNode(update, akey);
+ QMapData::Node *node = update[0]->forward[0];
+ while (node != e && !qMapLessThanKey<Key>(akey, concrete(node)->key))
+ node = node->forward[0];
+ return const_iterator(node);
+}
+
+template <class Key, class T>
+Q_INLINE_TEMPLATE typename QMap<Key, T>::iterator QMap<Key, T>::upperBound(const Key &akey)
+{
+ detach();
+ return static_cast<QMapData::Node *>(const_cast<const QMap *>(this)->upperBound(akey));
+}
+
+template <class Key, class T>
+Q_OUTOFLINE_TEMPLATE bool QMap<Key, T>::operator==(const QMap<Key, T> &other) const
+{
+ if (size() != other.size())
+ return false;
+ if (d == other.d)
+ return true;
+
+ const_iterator it1 = begin();
+ const_iterator it2 = other.begin();
+
+ while (it1 != end()) {
+ if (!(it1.value() == it2.value()) || qMapLessThanKey(it1.key(), it2.key()) || qMapLessThanKey(it2.key(), it1.key()))
+ return false;
+ ++it2;
+ ++it1;
+ }
+ return true;
+}
+
+#ifndef QT_NO_STL
+template <class Key, class T>
+Q_OUTOFLINE_TEMPLATE QMap<Key, T>::QMap(const std::map<Key, T> &other)
+{
+ d = QMapData::createData();
+ d->insertInOrder = true;
+ typename std::map<Key,T>::const_iterator it = other.end();
+ while (it != other.begin()) {
+ --it;
+ insert((*it).first, (*it).second);
+ }
+ d->insertInOrder = false;
+}
+
+template <class Key, class T>
+Q_OUTOFLINE_TEMPLATE std::map<Key, T> QMap<Key, T>::toStdMap() const
+{
+ std::map<Key, T> map;
+ const_iterator it = end();
+ while (it != begin()) {
+ --it;
+ map.insert(std::pair<Key, T>(it.key(), it.value()));
+ }
+ return map;
+}
+
+#endif // QT_NO_STL
+
+template <class Key, class T>
+class QMultiMap : public QMap<Key, T>
+{
+public:
+ QMultiMap() {}
+ QMultiMap(const QMap<Key, T> &other) : QMap<Key, T>(other) {}
+
+ inline typename QMap<Key, T>::iterator replace(const Key &key, const T &value)
+ { return QMap<Key, T>::insert(key, value); }
+ inline typename QMap<Key, T>::iterator insert(const Key &key, const T &value)
+ { return QMap<Key, T>::insertMulti(key, value); }
+
+ inline QMultiMap &operator+=(const QMultiMap &other)
+ { unite(other); return *this; }
+ inline QMultiMap operator+(const QMultiMap &other) const
+ { QMultiMap result = *this; result += other; return result; }
+
+#ifndef Q_NO_USING_KEYWORD
+ using QMap<Key, T>::contains;
+ using QMap<Key, T>::remove;
+ using QMap<Key, T>::count;
+ using QMap<Key, T>::find;
+ using QMap<Key, T>::constFind;
+#else
+ inline bool contains(const Key &key) const
+ { return QMap<Key, T>::contains(key); }
+ inline int remove(const Key &key)
+ { return QMap<Key, T>::remove(key); }
+ inline int count(const Key &key) const
+ { return QMap<Key, T>::count(key); }
+ inline int count() const
+ { return QMap<Key, T>::count(); }
+ inline typename QMap<Key, T>::iterator find(const Key &key)
+ { return QMap<Key, T>::find(key); }
+ inline typename QMap<Key, T>::const_iterator find(const Key &key) const
+ { return QMap<Key, T>::find(key); }
+ inline typename QMap<Key, T>::const_iterator constFind(const Key &key) const
+ { return QMap<Key, T>::constFind(key); }
+#endif
+
+ bool contains(const Key &key, const T &value) const;
+
+ int remove(const Key &key, const T &value);
+
+ int count(const Key &key, const T &value) const;
+
+ typename QMap<Key, T>::iterator find(const Key &key, const T &value) {
+ typename QMap<Key, T>::iterator i(find(key));
+ typename QMap<Key, T>::iterator end(this->end());
+ while (i != end && !qMapLessThanKey<Key>(key, i.key())) {
+ if (i.value() == value)
+ return i;
+ ++i;
+ }
+ return end;
+ }
+ typename QMap<Key, T>::const_iterator find(const Key &key, const T &value) const {
+ typename QMap<Key, T>::const_iterator i(constFind(key));
+ typename QMap<Key, T>::const_iterator end(QMap<Key, T>::constEnd());
+ while (i != end && !qMapLessThanKey<Key>(key, i.key())) {
+ if (i.value() == value)
+ return i;
+ ++i;
+ }
+ return end;
+ }
+ typename QMap<Key, T>::const_iterator constFind(const Key &key, const T &value) const
+ { return find(key, value); }
+private:
+ T &operator[](const Key &key);
+ const T operator[](const Key &key) const;
+};
+
+template <class Key, class T>
+Q_INLINE_TEMPLATE bool QMultiMap<Key, T>::contains(const Key &key, const T &value) const
+{
+ return constFind(key, value) != QMap<Key, T>::constEnd();
+}
+
+template <class Key, class T>
+Q_INLINE_TEMPLATE int QMultiMap<Key, T>::remove(const Key &key, const T &value)
+{
+ int n = 0;
+ typename QMap<Key, T>::iterator i(find(key));
+ typename QMap<Key, T>::const_iterator end(QMap<Key, T>::constEnd());
+ while (i != end && !qMapLessThanKey<Key>(key, i.key())) {
+ if (i.value() == value) {
+ i = erase(i);
+ ++n;
+ } else {
+ ++i;
+ }
+ }
+ return n;
+}
+
+template <class Key, class T>
+Q_INLINE_TEMPLATE int QMultiMap<Key, T>::count(const Key &key, const T &value) const
+{
+ int n = 0;
+ typename QMap<Key, T>::const_iterator i(constFind(key));
+ typename QMap<Key, T>::const_iterator end(QMap<Key, T>::constEnd());
+ while (i != end && !qMapLessThanKey<Key>(key, i.key())) {
+ if (i.value() == value)
+ ++n;
+ ++i;
+ }
+ return n;
+}
+
+Q_DECLARE_ASSOCIATIVE_ITERATOR(Map)
+Q_DECLARE_MUTABLE_ASSOCIATIVE_ITERATOR(Map)
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QMAP_H
diff --git a/src/corelib/tools/qpair.h b/src/corelib/tools/qpair.h
new file mode 100644
index 0000000000..24088e43a0
--- /dev/null
+++ b/src/corelib/tools/qpair.h
@@ -0,0 +1,127 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QPAIR_H
+#define QPAIR_H
+
+#include <QtCore/qdatastream.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Core)
+
+template <class T1, class T2>
+struct QPair
+{
+ typedef T1 first_type;
+ typedef T2 second_type;
+
+ QPair() : first(T1()), second(T2()) {}
+ QPair(const T1 &t1, const T2 &t2) : first(t1), second(t2) {}
+
+ QPair<T1, T2> &operator=(const QPair<T1, T2> &other)
+ { first = other.first; second = other.second; return *this; }
+
+ T1 first;
+ T2 second;
+};
+
+template <class T1, class T2>
+Q_INLINE_TEMPLATE bool operator==(const QPair<T1, T2> &p1, const QPair<T1, T2> &p2)
+{ return p1.first == p2.first && p1.second == p2.second; }
+
+template <class T1, class T2>
+Q_INLINE_TEMPLATE bool operator!=(const QPair<T1, T2> &p1, const QPair<T1, T2> &p2)
+{ return !(p1 == p2); }
+
+template <class T1, class T2>
+Q_INLINE_TEMPLATE bool operator<(const QPair<T1, T2> &p1, const QPair<T1, T2> &p2)
+{
+ return p1.first < p2.first || (!(p2.first < p1.first) && p1.second < p2.second);
+}
+
+template <class T1, class T2>
+Q_INLINE_TEMPLATE bool operator>(const QPair<T1, T2> &p1, const QPair<T1, T2> &p2)
+{
+ return p2 < p1;
+}
+
+template <class T1, class T2>
+Q_INLINE_TEMPLATE bool operator<=(const QPair<T1, T2> &p1, const QPair<T1, T2> &p2)
+{
+ return !(p2 < p1);
+}
+
+template <class T1, class T2>
+Q_INLINE_TEMPLATE bool operator>=(const QPair<T1, T2> &p1, const QPair<T1, T2> &p2)
+{
+ return !(p1 < p2);
+}
+
+template <class T1, class T2>
+Q_OUTOFLINE_TEMPLATE QPair<T1, T2> qMakePair(const T1 &x, const T2 &y)
+{
+ return QPair<T1, T2>(x, y);
+}
+
+#ifndef QT_NO_DATASTREAM
+template <class T1, class T2>
+inline QDataStream& operator>>(QDataStream& s, QPair<T1, T2>& p)
+{
+ s >> p.first >> p.second;
+ return s;
+}
+
+template <class T1, class T2>
+inline QDataStream& operator<<(QDataStream& s, const QPair<T1, T2>& p)
+{
+ s << p.first << p.second;
+ return s;
+}
+#endif
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QPAIR_H
diff --git a/src/corelib/tools/qpodlist_p.h b/src/corelib/tools/qpodlist_p.h
new file mode 100644
index 0000000000..9708f8d2e8
--- /dev/null
+++ b/src/corelib/tools/qpodlist_p.h
@@ -0,0 +1,263 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QPODLIST_P_H
+#define QPODLIST_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/qcontainerfwd.h>
+#include <QtCore/qglobal.h>
+#include <new>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Core)
+
+template<class T, int Prealloc>
+class QPodList
+{
+public:
+ inline explicit QPodList(int size = 0);
+
+ inline QPodList(const QPodList<T, Prealloc> &other)
+ : a(Prealloc), s(0), ptr(reinterpret_cast<T *>(array))
+ {
+ append(other.constData(), other.size());
+ }
+
+ inline ~QPodList() {
+ if (ptr != reinterpret_cast<T *>(array))
+ qFree(ptr);
+ }
+ inline QPodList<T, Prealloc> &operator=(const QPodList<T, Prealloc> &other)
+ {
+ if (this != &other) {
+ clear();
+ append(other.constData(), other.size());
+ }
+ return *this;
+ }
+
+ inline int size() const { return s; }
+ inline int count() const { return s; }
+ inline bool isEmpty() const { return (s == 0); }
+ inline void resize(int size);
+ inline void clear() { resize(0); }
+
+ inline int capacity() const { return a; }
+ inline void reserve(int size);
+
+ inline T &operator[](int idx) {
+ Q_ASSERT(idx >= 0 && idx < s);
+ return ptr[idx];
+ }
+ inline const T &operator[](int idx) const {
+ Q_ASSERT(idx >= 0 && idx < s);
+ return ptr[idx];
+ }
+
+ inline const T &at(int idx) const {
+ Q_ASSERT(idx >= 0 && idx < s);
+ return ptr[idx];
+ }
+
+ inline const T &first() const {
+ return at(0);
+ }
+
+ inline T& append() {
+ const int idx = s++;
+ if (s == a)
+ realloc(s, s<<1);
+ return ptr[idx];
+ }
+ inline void append(const T &t) {
+ append() = t;
+ }
+
+ inline T& insert(int idx) {
+ Q_ASSERT(idx >= 0 && idx <= s);
+ const int sz = s++;
+ if (s == a)
+ realloc(s, s<<1);
+ ::memmove(ptr + idx + 1, ptr + idx, (sz - idx) * sizeof(T));
+ return ptr[idx];
+ }
+ inline void insert(int idx, const T &t) {
+ insert(idx) = t;
+ }
+
+ inline void removeAt(int idx) {
+ Q_ASSERT(idx >= 0 && idx < s);
+ ::memmove(ptr + idx, ptr + idx + 1, (s - idx - 1) * sizeof(T));
+ --s;
+ }
+
+ inline void removeAll(const T &t) {
+ int i = 0;
+ for (int j = 0; j < s; ++j) {
+ if (ptr[j] != t)
+ ptr[i++] = ptr[j];
+ }
+ s = i;
+ }
+
+ inline int indexOf(const T &t, int from = 0) const {
+ if (from < 0)
+ from = qMax(from + s, 0);
+ if (from < s) {
+ const T *n = ptr + from - 1;
+ const T *e = ptr + s;
+ while (++n != e)
+ if (*n == t)
+ return n - ptr;
+ }
+ return -1;
+ }
+
+ inline bool contains(const T &t) const {
+ return indexOf(t) >= 0;
+ }
+
+ inline T takeFirst() {
+ Q_ASSERT(s > 0);
+ T tmp = ptr[0];
+ removeAt(0);
+ return tmp;
+ }
+
+ inline T *data() { return ptr; }
+ inline const T *data() const { return ptr; }
+ inline const T * constData() const { return ptr; }
+
+private:
+ void append(const T *buf, int size);
+ void realloc(int size, int alloc);
+
+ int a;
+ int s;
+ T *ptr;
+ union {
+ // ### Qt 5: Use 'Prealloc * sizeof(T)' as array size
+ char array[sizeof(qint64) * (((Prealloc * sizeof(T)) / sizeof(qint64)) + 1)];
+ qint64 q_for_alignment_1;
+ double q_for_alignment_2;
+ };
+};
+
+template <class T, int Prealloc>
+Q_INLINE_TEMPLATE QPodList<T, Prealloc>::QPodList(int asize)
+ : s(asize) {
+ if (s > Prealloc) {
+ ptr = reinterpret_cast<T *>(qMalloc(s * sizeof(T)));
+ a = s;
+ } else {
+ ptr = reinterpret_cast<T *>(array);
+ a = Prealloc;
+ }
+}
+
+template <class T, int Prealloc>
+Q_INLINE_TEMPLATE void QPodList<T, Prealloc>::resize(int asize)
+{ realloc(asize, qMax(asize, a)); }
+
+template <class T, int Prealloc>
+Q_INLINE_TEMPLATE void QPodList<T, Prealloc>::reserve(int asize)
+{ if (asize > a) realloc(s, asize); }
+
+template <class T, int Prealloc>
+Q_OUTOFLINE_TEMPLATE void QPodList<T, Prealloc>::append(const T *abuf, int asize)
+{
+ Q_ASSERT(abuf);
+ if (asize <= 0)
+ return;
+
+ const int idx = s;
+ const int news = s + asize;
+ if (news >= a)
+ realloc(news, news<<1);
+ else
+ s = news;
+
+ qMemCopy(&ptr[idx], abuf, asize * sizeof(T));
+}
+
+template <class T, int Prealloc>
+Q_OUTOFLINE_TEMPLATE void QPodList<T, Prealloc>::realloc(int asize, int aalloc)
+{
+ Q_ASSERT(aalloc >= asize);
+ T *oldPtr = ptr;
+ int osize = s;
+ s = asize;
+
+ if (aalloc != a) {
+ ptr = reinterpret_cast<T *>(qMalloc(aalloc * sizeof(T)));
+ if (ptr) {
+ a = aalloc;
+ qMemCopy(ptr, oldPtr, osize * sizeof(T));
+ } else {
+ ptr = oldPtr;
+ s = 0;
+ asize = 0;
+ }
+ }
+
+ if (oldPtr != reinterpret_cast<T *>(array) && oldPtr != ptr)
+ qFree(oldPtr);
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QPODLIST_P_H
diff --git a/src/corelib/tools/qpoint.cpp b/src/corelib/tools/qpoint.cpp
new file mode 100644
index 0000000000..feea473102
--- /dev/null
+++ b/src/corelib/tools/qpoint.cpp
@@ -0,0 +1,665 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qpoint.h"
+#include "qdatastream.h"
+#include "qdebug.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QPoint
+ \ingroup multimedia
+
+ \brief The QPoint class defines a point in the plane using integer
+ precision.
+
+ A point is specified by a x coordinate and an y coordinate which
+ can be accessed using the x() and y() functions. The isNull()
+ function returns true if both x and y are set to 0. The
+ coordinates can be set (or altered) using the setX() and setY()
+ functions, or alternatively the rx() and ry() functions which
+ return references to the coordinates (allowing direct
+ manipulation).
+
+ Given a point \e p, the following statements are all equivalent:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qpoint.cpp 0
+
+ A QPoint object can also be used as a vector: Addition and
+ subtraction are defined as for vectors (each component is added
+ separately). A QPoint object can also be divided or multiplied by
+ an \c int or a \c qreal.
+
+ In addition, the QPoint class provides the manhattanLength()
+ function which gives an inexpensive approximation of the length of
+ the QPoint object interpreted as a vector. Finally, QPoint objects
+ can be streamed as well as compared.
+
+ \sa QPointF, QPolygon
+*/
+
+
+/*****************************************************************************
+ QPoint member functions
+ *****************************************************************************/
+
+/*!
+ \fn QPoint::QPoint()
+
+ Constructs a null point, i.e. with coordinates (0, 0)
+
+ \sa isNull()
+*/
+
+/*!
+ \fn QPoint::QPoint(int x, int y)
+
+ Constructs a point with the given coordinates (\a x, \a y).
+
+ \sa setX(), setY()
+*/
+
+/*!
+ \fn bool QPoint::isNull() const
+
+ Returns true if both the x and y coordinates are set to 0,
+ otherwise returns false.
+*/
+
+/*!
+ \fn int QPoint::x() const
+
+ Returns the x coordinate of this point.
+
+ \sa setX(), rx()
+*/
+
+/*!
+ \fn int QPoint::y() const
+
+ Returns the y coordinate of this point.
+
+ \sa setY(), ry()
+*/
+
+/*!
+ \fn void QPoint::setX(int x)
+
+ Sets the x coordinate of this point to the given \a x coordinate.
+
+ \sa x() setY()
+*/
+
+/*!
+ \fn void QPoint::setY(int y)
+
+ Sets the y coordinate of this point to the given \a y coordinate.
+
+ \sa y() setX()
+*/
+
+
+/*!
+ \fn int &QPoint::rx()
+
+ Returns a reference to the x coordinate of this point.
+
+ Using a reference makes it possible to directly manipulate x. For example:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qpoint.cpp 1
+
+ \sa x() setX()
+*/
+
+/*!
+ \fn int &QPoint::ry()
+
+ Returns a reference to the y coordinate of this point.
+
+ Using a reference makes it possible to directly manipulate y. For
+ example:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qpoint.cpp 2
+
+ \sa y(), setY()
+*/
+
+
+/*!
+ \fn QPoint &QPoint::operator+=(const QPoint &point)
+
+ Adds the given \a point to this point and returns a reference to
+ this point. For example:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qpoint.cpp 3
+
+ \sa operator-=()
+*/
+
+/*!
+ \fn QPoint &QPoint::operator-=(const QPoint &point)
+
+ Subtracts the given \a point from this point and returns a
+ reference to this point. For example:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qpoint.cpp 4
+
+ \sa operator+=()
+*/
+
+/*!
+ \fn QPoint &QPoint::operator*=(qreal factor)
+
+ Multiplies this point's coordinates by the given \a factor, and
+ returns a reference to this point. For example:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qpoint.cpp 5
+
+ Note that the result is rounded to the nearest integer as points are held as
+ integers. Use QPointF for floating point accuracy.
+
+ \sa operator/=()
+*/
+
+
+/*!
+ \fn bool operator==(const QPoint &p1, const QPoint &p2)
+ \relates QPoint
+
+ Returns true if \a p1 and \a p2 are equal; otherwise returns
+ false.
+*/
+
+/*!
+ \fn bool operator!=(const QPoint &p1, const QPoint &p2)
+ \relates QPoint
+
+ Returns true if \a p1 and \a p2 are not equal; otherwise returns false.
+*/
+
+/*!
+ \fn const QPoint operator+(const QPoint &p1, const QPoint &p2)
+ \relates QPoint
+
+ Returns a QPoint object that is the sum of the given points, \a p1
+ and \a p2; each component is added separately.
+
+ \sa QPoint::operator+=()
+*/
+
+/*!
+ \fn const QPoint operator-(const QPoint &p1, const QPoint &p2)
+ \relates QPoint
+
+ Returns a QPoint object that is formed by subtracting \a p2 from
+ \a p1; each component is subtracted separately.
+
+ \sa QPoint::operator-=()
+*/
+
+/*!
+ \fn const QPoint operator*(const QPoint &point, qreal factor)
+ \relates QPoint
+
+ Returns a copy of the given \a point multiplied by the given \a factor.
+
+ Note that the result is rounded to the nearest integer as points
+ are held as integers. Use QPointF for floating point accuracy.
+
+ \sa QPoint::operator*=()
+*/
+
+/*!
+ \fn const QPoint operator*(qreal factor, const QPoint &point)
+ \overload
+ \relates QPoint
+
+ Returns a copy of the given \a point multiplied by the given \a factor.
+*/
+
+/*!
+ \fn const QPoint operator-(const QPoint &point)
+ \overload
+ \relates QPoint
+
+ Returns a QPoint object that is formed by changing the sign of
+ both components of the given \a point.
+
+ Equivalent to \c{QPoint(0,0) - point}.
+*/
+
+/*!
+ \fn QPoint &QPoint::operator/=(qreal divisor)
+ \overload
+
+ Divides both x and y by the given \a divisor, and returns a reference to this
+ point. For example:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qpoint.cpp 6
+
+ Note that the result is rounded to the nearest integer as points are held as
+ integers. Use QPointF for floating point accuracy.
+
+ \sa operator*=()
+*/
+
+/*!
+ \fn const QPoint operator/(const QPoint &point, qreal divisor)
+ \relates QPoint
+
+ Returns the QPoint formed by dividing both components of the given \a point
+ by the given \a divisor.
+
+ Note that the result is rounded to the nearest integer as points are held as
+ integers. Use QPointF for floating point accuracy.
+
+ \sa QPoint::operator/=()
+*/
+
+/*****************************************************************************
+ QPoint stream functions
+ *****************************************************************************/
+#ifndef QT_NO_DATASTREAM
+/*!
+ \fn QDataStream &operator<<(QDataStream &stream, const QPoint &point)
+ \relates QPoint
+
+ Writes the given \a point to the given \a stream and returns a
+ reference to the stream.
+
+ \sa {Format of the QDataStream Operators}
+*/
+
+QDataStream &operator<<(QDataStream &s, const QPoint &p)
+{
+ if (s.version() == 1)
+ s << (qint16)p.x() << (qint16)p.y();
+ else
+ s << (qint32)p.x() << (qint32)p.y();
+ return s;
+}
+
+/*!
+ \fn QDataStream &operator>>(QDataStream &stream, QPoint &point)
+ \relates QPoint
+
+ Reads a point from the given \a stream into the given \a point
+ and returns a reference to the stream.
+
+ \sa {Format of the QDataStream Operators}
+*/
+
+QDataStream &operator>>(QDataStream &s, QPoint &p)
+{
+ if (s.version() == 1) {
+ qint16 x, y;
+ s >> x; p.rx() = x;
+ s >> y; p.ry() = y;
+ }
+ else {
+ qint32 x, y;
+ s >> x; p.rx() = x;
+ s >> y; p.ry() = y;
+ }
+ return s;
+}
+
+#endif // QT_NO_DATASTREAM
+/*!
+ Returns the sum of the absolute values of x() and y(),
+ traditionally known as the "Manhattan length" of the vector from
+ the origin to the point. For example:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qpoint.cpp 7
+
+ This is a useful, and quick to calculate, approximation to the
+ true length:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qpoint.cpp 8
+
+ The tradition of "Manhattan length" arises because such distances
+ apply to travelers who can only travel on a rectangular grid, like
+ the streets of Manhattan.
+*/
+int QPoint::manhattanLength() const
+{
+ return qAbs(x())+qAbs(y());
+}
+
+#ifndef QT_NO_DEBUG_STREAM
+QDebug operator<<(QDebug dbg, const QPoint &p) {
+ dbg.nospace() << "QPoint(" << p.x() << ',' << p.y() << ')';
+ return dbg.space();
+}
+
+QDebug operator<<(QDebug d, const QPointF &p)
+{
+ d.nospace() << "QPointF(" << p.x() << ", " << p.y() << ")";
+ return d;
+}
+#endif
+
+/*!
+ \class QPointF
+ \ingroup multimedia
+
+ \brief The QPointF class defines a point in the plane using
+ floating point precision.
+
+ A point is specified by a x coordinate and an y coordinate which
+ can be accessed using the x() and y() functions. The coordinates
+ of the point are specified using floating point numbers for
+ accuracy. The isNull() function returns true if both x and y are
+ set to 0.0. The coordinates can be set (or altered) using the setX()
+ and setY() functions, or alternatively the rx() and ry() functions which
+ return references to the coordinates (allowing direct
+ manipulation).
+
+ Given a point \e p, the following statements are all equivalent:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qpoint.cpp 9
+
+ A QPointF object can also be used as a vector: Addition and
+ subtraction are defined as for vectors (each component is added
+ separately). A QPointF object can also be divided or multiplied by
+ an \c int or a \c qreal.
+
+ In addition, the QPointF class provides a constructor converting a
+ QPoint object into a QPointF object, and a corresponding toPoint()
+ function which returns a QPoint copy of \e this point. Finally,
+ QPointF objects can be streamed as well as compared.
+
+ \sa QPoint, QPolygonF
+*/
+
+/*!
+ \fn QPointF::QPointF()
+
+ Constructs a null point, i.e. with coordinates (0.0, 0.0)
+
+ \sa isNull()
+*/
+
+/*!
+ \fn QPointF::QPointF(const QPoint &point)
+
+ Constructs a copy of the given \a point.
+
+ \sa toPoint()
+*/
+
+/*!
+ \fn QPointF::QPointF(qreal x, qreal y)
+
+ Constructs a point with the given coordinates (\a x, \a y).
+
+ \sa setX(), setY()
+*/
+
+/*!
+ \fn bool QPointF::isNull() const
+
+ Returns true if both the x and y coordinates are set to 0.0,
+ otherwise returns false.
+*/
+
+/*!
+ \fn qreal QPointF::x() const
+
+ Returns the x-coordinate of this point.
+
+ \sa setX(), rx()
+*/
+
+/*!
+ \fn qreal QPointF::y() const
+
+ Returns the y-coordinate of this point.
+
+ \sa setY(), ry()
+*/
+
+/*!
+ \fn void QPointF::setX(qreal x)
+
+ Sets the x coordinate of this point to the given \a x coordinate.
+
+ \sa x() setY()
+*/
+
+/*!
+ \fn void QPointF::setY(qreal y)
+
+ Sets the y coordinate of this point to the given \a y coordinate.
+
+ \sa y(), setX()
+*/
+
+/*!
+ \fn qreal& QPointF::rx()
+
+ Returns a reference to the x coordinate of this point.
+
+ Using a reference makes it possible to directly manipulate x. For example:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qpoint.cpp 10
+
+ \sa x(), setX()
+*/
+
+/*!
+ \fn qreal& QPointF::ry()
+
+ Returns a reference to the y coordinate of this point.
+
+ Using a reference makes it possible to directly manipulate y. For example:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qpoint.cpp 11
+
+ \sa y() setY()
+*/
+
+/*!
+ \fn QPointF& QPointF::operator+=(const QPointF &point)
+
+ Adds the given \a point to this point and returns a reference to
+ this point. For example:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qpoint.cpp 12
+
+ \sa operator-=()
+*/
+
+/*!
+ \fn QPointF& QPointF::operator-=(const QPointF &point)
+
+ Subtracts the given \a point from this point and returns a reference
+ to this point. For example:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qpoint.cpp 13
+
+ \sa operator+=()
+*/
+
+/*!
+ \fn QPointF& QPointF::operator*=(qreal factor)
+
+ Multiplies this point's coordinates by the given \a factor, and
+ returns a reference to this point. For example:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qpoint.cpp 14
+
+ \sa operator/=()
+*/
+
+/*!
+ \fn QPointF& QPointF::operator/=(qreal divisor)
+
+ Divides both x and y by the given \a divisor, and returns a reference
+ to this point. For example:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qpoint.cpp 15
+
+ \sa operator*=()
+*/
+
+/*!
+ \fn const QPointF operator+(const QPointF &p1, const QPointF &p2)
+ \relates QPointF
+
+ Returns a QPointF object that is the sum of the given points, \a p1
+ and \a p2; each component is added separately.
+
+ \sa QPointF::operator+=()
+*/
+
+/*!
+ \fn const QPointF operator-(const QPointF &p1, const QPointF &p2)
+ \relates QPointF
+
+ Returns a QPointF object that is formed by subtracting \a p2 from \a p1;
+ each component is subtracted separately.
+
+ \sa QPointF::operator-=()
+*/
+
+/*!
+ \fn const QPointF operator*(const QPointF &point, qreal factor)
+ \relates QPointF
+
+ Returns a copy of the given \a point, multiplied by the given \a factor.
+
+ \sa QPointF::operator*=()
+*/
+
+/*!
+ \fn const QPointF operator*(qreal factor, const QPointF &point)
+ \relates QPointF
+
+ \overload
+
+ Returns a copy of the given \a point, multiplied by the given \a factor.
+*/
+
+/*!
+ \fn const QPointF operator-(const QPointF &point)
+ \relates QPointF
+ \overload
+
+ Returns a QPointF object that is formed by changing the sign of
+ both components of the given \a point.
+
+ Equivalent to \c {QPointF(0,0) - point}.
+*/
+
+/*!
+ \fn const QPointF operator/(const QPointF &point, qreal divisor)
+ \relates QPointF
+
+ Returns the QPointF object formed by dividing both components of
+ the given \a point by the given \a divisor.
+
+ \sa QPointF::operator/=()
+*/
+
+/*!
+ \fn QPoint QPointF::toPoint() const
+
+ Rounds the coordinates of this point to the nearest integer, and
+ returns a QPoint object with the rounded coordinates.
+
+ \sa QPointF()
+*/
+
+/*!
+ \fn bool operator==(const QPointF &p1, const QPointF &p2)
+ \relates QPointF
+
+ Returns true if \a p1 is equal to \a p2; otherwise returns false.
+*/
+
+/*!
+ \fn bool operator!=(const QPointF &p1, const QPointF &p2);
+ \relates QPointF
+
+ Returns true if \a p1 is not equal to \a p2; otherwise returns false.
+*/
+
+#ifndef QT_NO_DATASTREAM
+/*!
+ \fn QDataStream &operator<<(QDataStream &stream, const QPointF &point)
+ \relates QPointF
+
+ Writes the given \a point to the given \a stream and returns a
+ reference to the stream.
+
+ \sa {Format of the QDataStream Operators}
+*/
+
+QDataStream &operator<<(QDataStream &s, const QPointF &p)
+{
+ s << double(p.x()) << double(p.y());
+ return s;
+}
+
+/*!
+ \fn QDataStream &operator>>(QDataStream &stream, QPointF &point)
+ \relates QPointF
+
+ Reads a point from the given \a stream into the given \a point
+ and returns a reference to the stream.
+
+ \sa {Format of the QDataStream Operators}
+*/
+
+QDataStream &operator>>(QDataStream &s, QPointF &p)
+{
+ double x, y;
+ s >> x;
+ s >> y;
+ p.setX(qreal(x));
+ p.setY(qreal(y));
+ return s;
+}
+#endif // QT_NO_DATASTREAM
+
+QT_END_NAMESPACE
diff --git a/src/corelib/tools/qpoint.h b/src/corelib/tools/qpoint.h
new file mode 100644
index 0000000000..1dab7e2a23
--- /dev/null
+++ b/src/corelib/tools/qpoint.h
@@ -0,0 +1,361 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QPOINT_H
+#define QPOINT_H
+
+#include <QtCore/qnamespace.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Core)
+
+class Q_CORE_EXPORT QPoint
+{
+public:
+ QPoint();
+ QPoint(int xpos, int ypos);
+
+ bool isNull() const;
+
+ int x() const;
+ int y() const;
+ void setX(int x);
+ void setY(int y);
+
+ int manhattanLength() const;
+
+ int &rx();
+ int &ry();
+
+ QPoint &operator+=(const QPoint &p);
+ QPoint &operator-=(const QPoint &p);
+ QPoint &operator*=(qreal c);
+ QPoint &operator/=(qreal c);
+
+ friend inline bool operator==(const QPoint &, const QPoint &);
+ friend inline bool operator!=(const QPoint &, const QPoint &);
+ friend inline const QPoint operator+(const QPoint &, const QPoint &);
+ friend inline const QPoint operator-(const QPoint &, const QPoint &);
+ friend inline const QPoint operator*(const QPoint &, qreal);
+ friend inline const QPoint operator*(qreal, const QPoint &);
+ friend inline const QPoint operator-(const QPoint &);
+ friend inline const QPoint operator/(const QPoint &, qreal);
+
+private:
+ friend class QTransform;
+ // ### Qt 5; remove the ifdef and just have the same order on all platforms.
+#if defined(Q_OS_MAC)
+ int yp;
+ int xp;
+#else
+ int xp;
+ int yp;
+#endif
+};
+
+Q_DECLARE_TYPEINFO(QPoint, Q_MOVABLE_TYPE);
+
+/*****************************************************************************
+ QPoint stream functions
+ *****************************************************************************/
+#ifndef QT_NO_DATASTREAM
+Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QPoint &);
+Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QPoint &);
+#endif
+
+/*****************************************************************************
+ QPoint inline functions
+ *****************************************************************************/
+
+inline QPoint::QPoint()
+{ xp=0; yp=0; }
+
+inline QPoint::QPoint(int xpos, int ypos)
+{ xp = xpos; yp = ypos; }
+
+inline bool QPoint::isNull() const
+{ return xp == 0 && yp == 0; }
+
+inline int QPoint::x() const
+{ return xp; }
+
+inline int QPoint::y() const
+{ return yp; }
+
+inline void QPoint::setX(int xpos)
+{ xp = xpos; }
+
+inline void QPoint::setY(int ypos)
+{ yp = ypos; }
+
+inline int &QPoint::rx()
+{ return xp; }
+
+inline int &QPoint::ry()
+{ return yp; }
+
+inline QPoint &QPoint::operator+=(const QPoint &p)
+{ xp+=p.xp; yp+=p.yp; return *this; }
+
+inline QPoint &QPoint::operator-=(const QPoint &p)
+{ xp-=p.xp; yp-=p.yp; return *this; }
+
+inline QPoint &QPoint::operator*=(qreal c)
+{ xp = qRound(xp*c); yp = qRound(yp*c); return *this; }
+
+inline bool operator==(const QPoint &p1, const QPoint &p2)
+{ return p1.xp == p2.xp && p1.yp == p2.yp; }
+
+inline bool operator!=(const QPoint &p1, const QPoint &p2)
+{ return p1.xp != p2.xp || p1.yp != p2.yp; }
+
+inline const QPoint operator+(const QPoint &p1, const QPoint &p2)
+{ return QPoint(p1.xp+p2.xp, p1.yp+p2.yp); }
+
+inline const QPoint operator-(const QPoint &p1, const QPoint &p2)
+{ return QPoint(p1.xp-p2.xp, p1.yp-p2.yp); }
+
+inline const QPoint operator*(const QPoint &p, qreal c)
+{ return QPoint(qRound(p.xp*c), qRound(p.yp*c)); }
+
+inline const QPoint operator*(qreal c, const QPoint &p)
+{ return QPoint(qRound(p.xp*c), qRound(p.yp*c)); }
+
+inline const QPoint operator-(const QPoint &p)
+{ return QPoint(-p.xp, -p.yp); }
+
+inline QPoint &QPoint::operator/=(qreal c)
+{
+ xp = qRound(xp/c);
+ yp = qRound(yp/c);
+ return *this;
+}
+
+inline const QPoint operator/(const QPoint &p, qreal c)
+{
+ return QPoint(qRound(p.xp/c), qRound(p.yp/c));
+}
+
+#ifndef QT_NO_DEBUG_STREAM
+Q_CORE_EXPORT QDebug operator<<(QDebug, const QPoint &);
+#endif
+
+
+
+
+
+class Q_CORE_EXPORT QPointF
+{
+public:
+ QPointF();
+ QPointF(const QPoint &p);
+ QPointF(qreal xpos, qreal ypos);
+
+ bool isNull() const;
+
+ qreal x() const;
+ qreal y() const;
+ void setX(qreal x);
+ void setY(qreal y);
+
+ qreal &rx();
+ qreal &ry();
+
+ QPointF &operator+=(const QPointF &p);
+ QPointF &operator-=(const QPointF &p);
+ QPointF &operator*=(qreal c);
+ QPointF &operator/=(qreal c);
+
+ friend inline bool operator==(const QPointF &, const QPointF &);
+ friend inline bool operator!=(const QPointF &, const QPointF &);
+ friend inline const QPointF operator+(const QPointF &, const QPointF &);
+ friend inline const QPointF operator-(const QPointF &, const QPointF &);
+ friend inline const QPointF operator*(qreal, const QPointF &);
+ friend inline const QPointF operator*(const QPointF &, qreal);
+ friend inline const QPointF operator-(const QPointF &);
+ friend inline const QPointF operator/(const QPointF &, qreal);
+
+ QPoint toPoint() const;
+
+private:
+ friend class QMatrix;
+ friend class QTransform;
+
+ qreal xp;
+ qreal yp;
+};
+
+Q_DECLARE_TYPEINFO(QPointF, Q_MOVABLE_TYPE);
+
+/*****************************************************************************
+ QPointF stream functions
+ *****************************************************************************/
+#ifndef QT_NO_DATASTREAM
+Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QPointF &);
+Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QPointF &);
+#endif
+
+/*****************************************************************************
+ QPointF inline functions
+ *****************************************************************************/
+
+inline QPointF::QPointF() : xp(0), yp(0) { }
+
+inline QPointF::QPointF(qreal xpos, qreal ypos) : xp(xpos), yp(ypos) { }
+
+inline QPointF::QPointF(const QPoint &p) : xp(p.x()), yp(p.y()) { }
+
+inline bool QPointF::isNull() const
+{
+ return qIsNull(xp) && qIsNull(yp);
+}
+
+inline qreal QPointF::x() const
+{
+ return xp;
+}
+
+inline qreal QPointF::y() const
+{
+ return yp;
+}
+
+inline void QPointF::setX(qreal xpos)
+{
+ xp = xpos;
+}
+
+inline void QPointF::setY(qreal ypos)
+{
+ yp = ypos;
+}
+
+inline qreal &QPointF::rx()
+{
+ return xp;
+}
+
+inline qreal &QPointF::ry()
+{
+ return yp;
+}
+
+inline QPointF &QPointF::operator+=(const QPointF &p)
+{
+ xp+=p.xp;
+ yp+=p.yp;
+ return *this;
+}
+
+inline QPointF &QPointF::operator-=(const QPointF &p)
+{
+ xp-=p.xp; yp-=p.yp; return *this;
+}
+
+inline QPointF &QPointF::operator*=(qreal c)
+{
+ xp*=c; yp*=c; return *this;
+}
+
+inline bool operator==(const QPointF &p1, const QPointF &p2)
+{
+ return qFuzzyCompare(p1.xp, p2.xp) && qFuzzyCompare(p1.yp, p2.yp);
+}
+
+inline bool operator!=(const QPointF &p1, const QPointF &p2)
+{
+ return !qFuzzyCompare(p1.xp, p2.xp) || !qFuzzyCompare(p1.yp, p2.yp);
+}
+
+inline const QPointF operator+(const QPointF &p1, const QPointF &p2)
+{
+ return QPointF(p1.xp+p2.xp, p1.yp+p2.yp);
+}
+
+inline const QPointF operator-(const QPointF &p1, const QPointF &p2)
+{
+ return QPointF(p1.xp-p2.xp, p1.yp-p2.yp);
+}
+
+inline const QPointF operator*(const QPointF &p, qreal c)
+{
+ return QPointF(p.xp*c, p.yp*c);
+}
+
+inline const QPointF operator*(qreal c, const QPointF &p)
+{
+ return QPointF(p.xp*c, p.yp*c);
+}
+
+inline const QPointF operator-(const QPointF &p)
+{
+ return QPointF(-p.xp, -p.yp);
+}
+
+inline QPointF &QPointF::operator/=(qreal c)
+{
+ xp/=c;
+ yp/=c;
+ return *this;
+}
+
+inline const QPointF operator/(const QPointF &p, qreal c)
+{
+ return QPointF(p.xp/c, p.yp/c);
+}
+
+inline QPoint QPointF::toPoint() const
+{
+ return QPoint(qRound(xp), qRound(yp));
+}
+
+#ifndef QT_NO_DEBUG_STREAM
+Q_CORE_EXPORT QDebug operator<<(QDebug d, const QPointF &p);
+#endif
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QPOINT_H
diff --git a/src/corelib/tools/qqueue.cpp b/src/corelib/tools/qqueue.cpp
new file mode 100644
index 0000000000..de16f8c286
--- /dev/null
+++ b/src/corelib/tools/qqueue.cpp
@@ -0,0 +1,129 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \class QQueue
+ \brief The QQueue class is a generic container that provides a queue.
+
+ \ingroup tools
+ \ingroup shared
+ \mainclass
+ \reentrant
+
+ QQueue\<T\> is one of Qt's generic \l{container classes}. It
+ implements a queue data structure for items of a same type.
+
+ A queue is a first in, first out (FIFO) structure. Items are
+ added to the tail of the queue using enqueue() and retrieved from
+ the head using dequeue(). The head() function provides access to
+ the head item without removing it.
+
+ Example:
+ \snippet doc/src/snippets/code/src_corelib_tools_qqueue.cpp 0
+
+ The example will output 1, 2, 3 in that order.
+
+ QQueue inherits from QList. All of QList's functionality also
+ applies to QQueue. For example, you can use isEmpty() to test
+ whether the queue is empty, and you can traverse a QQueue using
+ QList's iterator classes (for example, QListIterator). But in
+ addition, QQueue provides three convenience functions that make
+ it easy to implement FIFO semantics: enqueue(), dequeue(), and
+ head().
+
+ QQueue's value type must be an \l{assignable data type}. This
+ covers most data types that are commonly used, but the compiler
+ won't let you, for example, store a QWidget as a value. Use
+ QWidget* instead.
+
+ \sa QList, QStack
+*/
+
+/*!
+ \fn QQueue::QQueue()
+
+ Constructs an empty queue.
+*/
+
+/*!
+ \fn QQueue::~QQueue()
+
+ Destroys the queue. References to the values in the queue, and all
+ iterators over this queue, become invalid.
+*/
+
+/*!
+ \fn void QQueue::enqueue(const T& t)
+
+ Adds value \a t to the tail of the queue.
+
+ This is the same as QList::append().
+
+ \sa dequeue(), head()
+*/
+
+/*!
+ \fn T &QQueue::head()
+
+ Returns a reference to the queue's head item. This function
+ assumes that the queue isn't empty.
+
+ This is the same as QList::first().
+
+ \sa dequeue(), enqueue(), isEmpty()
+*/
+
+/*!
+ \fn const T &QQueue::head() const
+
+ \overload
+*/
+
+/*!
+ \fn T QQueue::dequeue()
+
+ Removes the head item in the queue and returns it. This function
+ assumes that the queue isn't empty.
+
+ This is the same as QList::takeFirst().
+
+ \sa head(), enqueue(), isEmpty()
+*/
diff --git a/src/corelib/tools/qqueue.h b/src/corelib/tools/qqueue.h
new file mode 100644
index 0000000000..8c7385e1c5
--- /dev/null
+++ b/src/corelib/tools/qqueue.h
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQUEUE_H
+#define QQUEUE_H
+
+#include <QtCore/qlist.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Core)
+
+template <class T>
+class QQueue : public QList<T>
+{
+public:
+ inline QQueue() {}
+ inline ~QQueue() {}
+ inline void enqueue(const T &t) { QList<T>::append(t); }
+ inline T dequeue() { return QList<T>::takeFirst(); }
+ inline T &head() { return QList<T>::first(); }
+ inline const T &head() const { return QList<T>::first(); }
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QQUEUE_H
diff --git a/src/corelib/tools/qrect.cpp b/src/corelib/tools/qrect.cpp
new file mode 100644
index 0000000000..3930a0d6a4
--- /dev/null
+++ b/src/corelib/tools/qrect.cpp
@@ -0,0 +1,2471 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qrect.h"
+#include "qdatastream.h"
+#include "qdebug.h"
+#include "qmath.h"
+
+#include <math.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QRect
+ \ingroup multimedia
+
+ \brief The QRect class defines a rectangle in the plane using
+ integer precision.
+
+ A rectangle is normally expressed as an upper-left corner and a
+ size. The size (width and height) of a QRect is always equivalent
+ to the mathematical rectangle that forms the basis for its
+ rendering.
+
+ A QRect can be constructed with a set of left, top, width and
+ height integers, or from a QPoint and a QSize. The following code
+ creates two identical rectangles.
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qrect.cpp 0
+
+ There is a third constructor that creates a QRect using the
+ top-left and bottom-right coordinates, but we recommend that you
+ avoid using it. The rationale is that for historical reasons the
+ values returned by the bottom() and right() functions deviate from
+ the true bottom-right corner of the rectangle.
+
+ The QRect class provides a collection of functions that return the
+ various rectangle coordinates, and enable manipulation of
+ these. QRect also provide functions to move the rectangle relative
+ to the various coordinates. In addition there is a moveTo()
+ function that moves the rectangle, leaving its top left corner at
+ the given coordinates. Alternatively, the translate() function
+ moves the rectangle the given offset relative to the current
+ position, and the translated() function returns a translated copy
+ of this rectangle.
+
+ The size() function returns the rectange's dimensions as a
+ QSize. The dimensions can also be retrieved separately using the
+ width() and height() functions. To manipulate the dimensions use
+ the setSize(), setWidth() or setHeight() functions. Alternatively,
+ the size can be changed by applying either of the functions
+ setting the rectangle coordinates, for example, setBottom() or
+ setRight().
+
+ The contains() function tells whether a given point is inside the
+ rectangle or not, and the intersects() function returns true if
+ this rectangle intersects with a given rectangle. The QRect class
+ also provides the intersected() function which returns the
+ intersection rectangle, and the united() function which returns the
+ rectangle that encloses the given rectangle and this:
+
+ \table
+ \row
+ \o \inlineimage qrect-intersect.png
+ \o \inlineimage qrect-unite.png
+ \row
+ \o intersected()
+ \o united()
+ \endtable
+
+ The isEmpty() function returns true if left() > right() or top() >
+ bottom(). Note that an empty rectangle is not valid: The isValid()
+ function returns true if left() <= right() \e and top() <=
+ bottom(). A null rectangle (isNull() == true) on the other hand,
+ has both width and height set to 0.
+
+ Note that due to the way QRect and QRectF are defined, an
+ empty QRect is defined in essentially the same way as QRectF.
+
+ Finally, QRect objects can be streamed as well as compared.
+
+ \tableofcontents
+
+ \section1 Rendering
+
+ When using an \l {QPainter::Antialiasing}{anti-aliased} painter,
+ the boundary line of a QRect will be rendered symmetrically on
+ both sides of the mathematical rectangle's boundary line. But when
+ using an aliased painter (the default) other rules apply.
+
+ Then, when rendering with a one pixel wide pen the QRect's boundary
+ line will be rendered to the right and below the mathematical
+ rectangle's boundary line.
+
+ When rendering with a two pixels wide pen the boundary line will
+ be split in the middle by the mathematical rectangle. This will be
+ the case whenever the pen is set to an even number of pixels,
+ while rendering with a pen with an odd number of pixels, the spare
+ pixel will be rendered to the right and below the mathematical
+ rectangle as in the one pixel case.
+
+ \table
+ \row
+ \o \inlineimage qrect-diagram-zero.png
+ \o \inlineimage qrect-diagram-one.png
+ \row
+ \o Logical representation
+ \o One pixel wide pen
+ \row
+ \o \inlineimage qrect-diagram-two.png
+ \o \inlineimage qrect-diagram-three.png
+ \row
+ \o Two pixel wide pen
+ \o Three pixel wide pen
+ \endtable
+
+ \section1 Coordinates
+
+ The QRect class provides a collection of functions that return the
+ various rectangle coordinates, and enable manipulation of
+ these. QRect also provide functions to move the rectangle relative
+ to the various coordinates.
+
+ For example the left(), setLeft() and moveLeft() functions as an
+ example: left() returns the x-coordinate of the rectangle's left
+ edge, setLeft() sets the left edge of the rectangle to the given x
+ coordinate (it may change the width, but will never change the
+ rectangle's right edge) and moveLeft() moves the entire rectangle
+ horizontally, leaving the rectangle's left edge at the given x
+ coordinate and its size unchanged.
+
+ \image qrect-coordinates.png
+
+ Note that for historical reasons the values returned by the
+ bottom() and right() functions deviate from the true bottom-right
+ corner of the rectangle: The right() function returns \e { left()
+ + width() - 1} and the bottom() function returns \e {top() +
+ height() - 1}. The same is the case for the point returned by the
+ bottomRight() convenience function. In addition, the x and y
+ coordinate of the topRight() and bottomLeft() functions,
+ respectively, contain the same deviation from the true right and
+ bottom edges.
+
+ We recommend that you use x() + width() and y() + height() to find
+ the true bottom-right corner, and avoid right() and
+ bottom(). Another solution is to use QRectF: The QRectF class
+ defines a rectangle in the plane using floating point accuracy for
+ coordinates, and the QRectF::right() and QRectF::bottom()
+ functions \e do return the right and bottom coordinates.
+
+ It is also possible to add offsets to this rectangle's coordinates
+ using the adjust() function, as well as retrieve a new rectangle
+ based on adjustments of the original one using the adjusted()
+ function. If either of the width and height is negative, use the
+ normalized() function to retrieve a rectangle where the corners
+ are swapped.
+
+ In addition, QRect provides the getCoords() function which extracts
+ the position of the rectangle's top-left and bottom-right corner,
+ and the getRect() function which extracts the rectangle's top-left
+ corner, width and height. Use the setCoords() and setRect()
+ function to manipulate the rectangle's coordinates and dimensions
+ in one go.
+
+ \sa QRectF, QRegion
+*/
+
+/*****************************************************************************
+ QRect member functions
+ *****************************************************************************/
+
+/*!
+ \fn QRect::QRect()
+
+ Constructs a null rectangle.
+
+ \sa isNull()
+*/
+
+/*!
+ \fn QRect::QRect(const QPoint &topLeft, const QPoint &bottomRight)
+
+ Constructs a rectangle with the given \a topLeft and \a bottomRight corners.
+
+ \sa setTopLeft(), setBottomRight()
+*/
+
+
+/*!
+ \fn QRect::QRect(const QPoint &topLeft, const QSize &size)
+
+ Constructs a rectangle with the given \a topLeft corner and the
+ given \a size.
+
+ \sa setTopLeft(), setSize()
+*/
+
+
+/*!
+ \fn QRect::QRect(int x, int y, int width, int height)
+
+ Constructs a rectangle with (\a x, \a y) as its top-left corner
+ and the given \a width and \a height.
+
+ \sa setRect()
+*/
+
+
+/*!
+ \fn bool QRect::isNull() const
+
+ Returns true if the rectangle is a null rectangle, otherwise
+ returns false.
+
+ A null rectangle has both the width and the height set to 0 (i.e.,
+ right() == left() - 1 and bottom() == top() - 1). A null rectangle
+ is also empty, and hence is not valid.
+
+ \sa isEmpty(), isValid()
+*/
+
+/*!
+ \fn bool QRect::isEmpty() const
+
+ Returns true if the rectangle is empty, otherwise returns false.
+
+ An empty rectangle has a left() > right() or top() > bottom(). An
+ empty rectangle is not valid (i.e., isEmpty() == !isValid()).
+
+ Use the normalized() function to retrieve a rectangle where the
+ corners are swapped.
+
+ \sa isNull(), isValid(), normalized()
+*/
+
+/*!
+ \fn bool QRect::isValid() const
+
+ Returns true if the rectangle is valid, otherwise returns false.
+
+ A valid rectangle has a left() < right() and top() <
+ bottom(). Note that non-trivial operations like intersections are
+ not defined for invalid rectangles. A valid rectangle is not empty
+ (i.e., isValid() == !isEmpty()).
+
+ \sa isNull(), isEmpty(), normalized()
+*/
+
+
+/*!
+ Returns a normalized rectangle; i.e., a rectangle that has a
+ non-negative width and height.
+
+ If width() < 0 the function swaps the left and right corners, and
+ it swaps the top and bottom corners if height() < 0.
+
+ \sa isValid(), isEmpty()
+*/
+
+QRect QRect::normalized() const
+{
+ QRect r;
+ if (x2 < x1 - 1) { // swap bad x values
+ r.x1 = x2;
+ r.x2 = x1;
+ } else {
+ r.x1 = x1;
+ r.x2 = x2;
+ }
+ if (y2 < y1 - 1) { // swap bad y values
+ r.y1 = y2;
+ r.y2 = y1;
+ } else {
+ r.y1 = y1;
+ r.y2 = y2;
+ }
+ return r;
+}
+
+
+/*!
+ \fn QRect QRect::normalize() const
+ \compat
+
+ Returns a normalized rectangle; i.e., a rectangle that has a
+ non-negative width and height.
+
+ Use the normalized() function instead
+*/
+
+/*!
+ \fn int QRect::left() const
+
+ Returns the x-coordinate of the rectangle's left edge. Equivalent
+ to x().
+
+ \sa setLeft(), topLeft(), bottomLeft()
+*/
+
+/*!
+ \fn int QRect::top() const
+
+ Returns the y-coordinate of the rectangle's top edge.
+ Equivalent to y().
+
+ \sa setTop(), topLeft(), topRight()
+*/
+
+/*!
+ \fn int QRect::right() const
+
+ Returns the x-coordinate of the rectangle's right edge.
+
+ Note that for historical reasons this function returns left() +
+ width() - 1; use x() + width() to retrieve the true x-coordinate.
+
+ \sa setRight(), topRight(), bottomRight()
+*/
+
+/*!
+ \fn int QRect::bottom() const
+
+ Returns the y-coordinate of the rectangle's bottom edge.
+
+ Note that for historical reasons this function returns top() +
+ height() - 1; use y() + height() to retrieve the true y-coordinate.
+
+ \sa setBottom(), bottomLeft(), bottomRight()
+*/
+
+/*!
+ \fn int &QRect::rLeft()
+ \compat
+
+ Returns a reference to the left coordinate of the rectangle.
+
+ Use the left() function instead.
+*/
+
+/*!
+ \fn int &QRect::rTop()
+ \compat
+
+ Returns a reference to the top coordinate of the rectangle.
+
+ Use the top() function instead.
+*/
+
+/*!
+ \fn int &QRect::rRight()
+ \compat
+
+ Returns a reference to the right coordinate of the rectangle.
+
+ Use the right() function instead.
+*/
+
+/*!
+ \fn int &QRect::rBottom()
+ \compat
+
+ Returns a reference to the bottom coordinate of the rectangle.
+
+ Use the bottom() function instead.
+*/
+
+/*!
+ \fn int QRect::x() const
+
+ Returns the x-coordinate of the rectangle's left edge. Equivalent to left().
+
+ \sa setX(), y(), topLeft()
+*/
+
+/*!
+ \fn int QRect::y() const
+
+ Returns the y-coordinate of the rectangle's top edge. Equivalent to top().
+
+ \sa setY(), x(), topLeft()
+*/
+
+/*!
+ \fn void QRect::setLeft(int x)
+
+ Sets the left edge of the rectangle to the given \a x
+ coordinate. May change the width, but will never change the right
+ edge of the rectangle.
+
+ Equivalent to setX().
+
+ \sa left(), moveLeft()
+*/
+
+/*!
+ \fn void QRect::setTop(int y)
+
+ Sets the top edge of the rectangle to the given \a y
+ coordinate. May change the height, but will never change the
+ bottom edge of the rectangle.
+
+ Equivalent to setY().
+
+ \sa top(), moveTop()
+*/
+
+/*!
+ \fn void QRect::setRight(int x)
+
+ Sets the right edge of the rectangle to the given \a x
+ coordinate. May change the width, but will never change the left
+ edge of the rectangle.
+
+ \sa right(), moveRight()
+*/
+
+/*!
+ \fn void QRect::setBottom(int y)
+
+ Sets the bottom edge of the rectangle to the given \a y
+ coordinate. May change the height, but will never change the top
+ edge of the rectangle.
+
+ \sa bottom(), moveBottom(),
+*/
+
+/*!
+ \fn void QRect::setX(int x)
+
+ Sets the left edge of the rectangle to the given \a x
+ coordinate. May change the width, but will never change the right
+ edge of the rectangle.
+
+ Equivalent to setLeft().
+
+ \sa x(), setY(), setTopLeft()
+*/
+
+/*!
+ \fn void QRect::setY(int y)
+
+ Sets the top edge of the rectangle to the given \a y
+ coordinate. May change the height, but will never change the
+ bottom edge of the rectangle.
+
+ Equivalent to setTop().
+
+ \sa y(), setX(), setTopLeft()
+*/
+
+/*!
+ \fn void QRect::setTopLeft(const QPoint &position)
+
+ Set the top-left corner of the rectangle to the given \a
+ position. May change the size, but will never change the
+ bottom-right corner of the rectangle.
+
+ \sa topLeft(), moveTopLeft()
+*/
+
+/*!
+ \fn void QRect::setBottomRight(const QPoint &position)
+
+ Set the bottom-right corner of the rectangle to the given \a
+ position. May change the size, but will never change the
+ top-left corner of the rectangle.
+
+ \sa bottomRight(), moveBottomRight()
+*/
+
+/*!
+ \fn void QRect::setTopRight(const QPoint &position)
+
+ Set the top-right corner of the rectangle to the given \a
+ position. May change the size, but will never change the
+ bottom-left corner of the rectangle.
+
+ \sa topRight(), moveTopRight()
+*/
+
+/*!
+ \fn void QRect::setBottomLeft(const QPoint &position)
+
+ Set the bottom-left corner of the rectangle to the given \a
+ position. May change the size, but will never change the
+ top-right corner of the rectangle.
+
+ \sa bottomLeft(), moveBottomLeft()
+*/
+
+/*!
+ \fn QPoint QRect::topLeft() const
+
+ Returns the position of the rectangle's top-left corner.
+
+ \sa setTopLeft(), top(), left()
+*/
+
+/*!
+ \fn QPoint QRect::bottomRight() const
+
+ Returns the position of the rectangle's bottom-right corner.
+
+ Note that for historical reasons this function returns
+ QPoint(left() + width() -1, top() + height() - 1).
+
+ \sa setBottomRight(), bottom(), right()
+*/
+
+/*!
+ \fn QPoint QRect::topRight() const
+
+ Returns the position of the rectangle's top-right corner.
+
+ Note that for historical reasons this function returns
+ QPoint(left() + width() -1, top()).
+
+ \sa setTopRight(), top(), right()
+*/
+
+/*!
+ \fn QPoint QRect::bottomLeft() const
+
+ Returns the position of the rectangle's bottom-left corner. Note
+ that for historical reasons this function returns QPoint(left(),
+ top() + height() - 1).
+
+ \sa setBottomLeft(), bottom(), left()
+*/
+
+/*!
+ \fn QPoint QRect::center() const
+
+ Returns the center point of the rectangle.
+
+ \sa moveCenter()
+*/
+
+
+/*!
+ \fn void QRect::getRect(int *x, int *y, int *width, int *height) const
+
+ Extracts the position of the rectangle's top-left corner to *\a x
+ and *\a y, and its dimensions to *\a width and *\a height.
+
+ \sa setRect(), getCoords()
+*/
+
+
+/*!
+ \fn void QRect::getCoords(int *x1, int *y1, int *x2, int *y2) const
+
+ Extracts the position of the rectangle's top-left corner to *\a x1
+ and *\a y1, and the position of the bottom-right corner to *\a x2
+ and *\a y2.
+
+ \sa setCoords(), getRect()
+*/
+
+/*!
+ \fn void QRect::rect(int *x, int *y, int *width, int *height) const
+ \compat
+
+ Extracts the position of the rectangle's top-left corner to *\a x and
+ *\a y, and its dimensions to *\a width and * \a height.
+
+ Use the getRect() function instead.
+*/
+
+
+/*!
+ \fn void QRect::coords(int *x1, int *y1, int *x2, int *y2) const
+ \compat
+
+ Extracts the position of the rectangle's top-left corner to *\a x1
+ and *\a y1, and the position of the bottom-right corner to *\a x2
+ and *\a y2.
+
+ Use the getCoords() function instead.
+*/
+
+/*!
+ \fn void QRect::moveLeft(int x)
+
+ Moves the rectangle horizontally, leaving the rectangle's left
+ edge at the given \a x coordinate. The rectangle's size is
+ unchanged.
+
+ \sa left(), setLeft(), moveRight()
+*/
+
+/*!
+ \fn void QRect::moveTop(int y)
+
+ Moves the rectangle vertically, leaving the rectangle's top edge
+ at the given \a y coordinate. The rectangle's size is unchanged.
+
+ \sa top(), setTop(), moveBottom()
+*/
+
+
+/*!
+ \fn void QRect::moveRight(int x)
+
+ Moves the rectangle horizontally, leaving the rectangle's right
+ edge at the given \a x coordinate. The rectangle's size is
+ unchanged.
+
+ \sa right(), setRight(), moveLeft()
+*/
+
+
+/*!
+ \fn void QRect::moveBottom(int y)
+
+ Moves the rectangle vertically, leaving the rectangle's bottom
+ edge at the given \a y coordinate. The rectangle's size is
+ unchanged.
+
+ \sa bottom(), setBottom(), moveTop()
+*/
+
+
+/*!
+ \fn void QRect::moveTopLeft(const QPoint &position)
+
+ Moves the rectangle, leaving the top-left corner at the given \a
+ position. The rectangle's size is unchanged.
+
+ \sa setTopLeft(), moveTop(), moveLeft()
+*/
+
+
+/*!
+ \fn void QRect::moveBottomRight(const QPoint &position)
+
+ Moves the rectangle, leaving the bottom-right corner at the given
+ \a position. The rectangle's size is unchanged.
+
+ \sa setBottomRight(), moveRight(), moveBottom()
+*/
+
+
+/*!
+ \fn void QRect::moveTopRight(const QPoint &position)
+
+ Moves the rectangle, leaving the top-right corner at the given \a
+ position. The rectangle's size is unchanged.
+
+ \sa setTopRight(), moveTop(), moveRight()
+*/
+
+
+/*!
+ \fn void QRect::moveBottomLeft(const QPoint &position)
+
+ Moves the rectangle, leaving the bottom-left corner at the given
+ \a position. The rectangle's size is unchanged.
+
+ \sa setBottomLeft(), moveBottom(), moveLeft()
+*/
+
+
+/*!
+ \fn void QRect::moveCenter(const QPoint &position)
+
+ Moves the rectangle, leaving the center point at the given \a
+ position. The rectangle's size is unchanged.
+
+ \sa center()
+*/
+
+void QRect::moveCenter(const QPoint &p)
+{
+ int w = x2 - x1;
+ int h = y2 - y1;
+ x1 = p.x() - w/2;
+ y1 = p.y() - h/2;
+ x2 = x1 + w;
+ y2 = y1 + h;
+}
+
+/*!
+ \fn void QRect::moveBy(int dx, int dy)
+ \compat
+
+ Moves the rectangle \a dx along the x axis and \a dy along the y
+ axis, relative to the current position.
+
+ Use the translate() function instead.
+*/
+
+/*!
+ \fn void QRect::moveBy(const QPoint &)
+ \compat
+
+ Use the translate() function instead.
+*/
+
+/*!
+ \fn void QRect::moveTo(int x, int y)
+
+ Moves the rectangle, leaving the top-left corner at the given
+ position (\a x, \a y). The rectangle's size is unchanged.
+
+ \sa translate(), moveTopLeft()
+*/
+
+/*!
+ \fn void QRect::moveTo(const QPoint &position)
+
+ Moves the rectangle, leaving the top-left corner at the given \a
+ position.
+*/
+
+/*!
+ \fn void QRect::translate(int dx, int dy)
+
+ Moves the rectangle \a dx along the x axis and \a dy along the y
+ axis, relative to the current position. Positive values move the
+ rectangle to the right and down.
+
+ \sa moveTopLeft(), moveTo(), translated()
+*/
+
+
+/*!
+ \fn void QRect::translate(const QPoint &offset)
+ \overload
+
+ Moves the rectangle \a{offset}.\l{QPoint::x()}{x()} along the x
+ axis and \a{offset}.\l{QPoint::y()}{y()} along the y axis,
+ relative to the current position.
+*/
+
+
+/*!
+ \fn QRect QRect::translated(int dx, int dy) const
+
+ Returns a copy of the rectangle that is translated \a dx along the
+ x axis and \a dy along the y axis, relative to the current
+ position. Positive values move the rectangle to the right and
+ down.
+
+ \sa translate()
+
+*/
+
+
+/*!
+ \fn QRect QRect::translated(const QPoint &offset) const
+
+ \overload
+
+ Returns a copy of the rectangle that is translated
+ \a{offset}.\l{QPoint::x()}{x()} along the x axis and
+ \a{offset}.\l{QPoint::y()}{y()} along the y axis, relative to the
+ current position.
+*/
+
+
+/*!
+ \fn void QRect::setRect(int x, int y, int width, int height)
+
+ Sets the coordinates of the rectangle's top-left corner to (\a{x},
+ \a{y}), and its size to the given \a width and \a height.
+
+ \sa getRect(), setCoords()
+*/
+
+
+/*!
+ \fn void QRect::setCoords(int x1, int y1, int x2, int y2)
+
+ Sets the coordinates of the rectangle's top-left corner to (\a x1,
+ \a y1), and the coordinates of its bottom-right corner to (\a x2,
+ \a y2).
+
+ \sa getCoords(), setRect()
+*/
+
+
+/*!
+ \fn void QRect::addCoords(int dx1, int dy1, int dx2, int dy2)
+ \compat
+
+ Adds \a dx1, \a dy1, \a dx2 and \a dy2 to the existing coordinates
+ of the rectangle respectively.
+
+ Use the adjust() function instead.
+*/
+
+/*! \fn QRect QRect::adjusted(int dx1, int dy1, int dx2, int dy2) const
+
+ Returns a new rectangle with \a dx1, \a dy1, \a dx2 and \a dy2
+ added respectively to the existing coordinates of this rectangle.
+
+ \sa adjust()
+*/
+
+/*! \fn void QRect::adjust(int dx1, int dy1, int dx2, int dy2)
+
+ Adds \a dx1, \a dy1, \a dx2 and \a dy2 respectively to the
+ existing coordinates of the rectangle.
+
+ \sa adjusted(), setRect()
+*/
+
+/*!
+ \fn QSize QRect::size() const
+
+ Returns the size of the rectangle.
+
+ \sa setSize(), width(), height()
+*/
+
+/*!
+ \fn int QRect::width() const
+
+ Returns the width of the rectangle.
+
+ \sa setWidth(), height(), size()
+*/
+
+/*!
+ \fn int QRect::height() const
+
+ Returns the height of the rectangle.
+
+ \sa setHeight(), width(), size()
+*/
+
+/*!
+ \fn void QRect::setWidth(int width)
+
+ Sets the width of the rectangle to the given \a width. The right
+ edge is changed, but not the left one.
+
+ \sa width(), setSize()
+*/
+
+
+/*!
+ \fn void QRect::setHeight(int height)
+
+ Sets the height of the rectangle to the given \a height. The bottom
+ edge is changed, but not the top one.
+
+ \sa height(), setSize()
+*/
+
+
+/*!
+ \fn void QRect::setSize(const QSize &size)
+
+ Sets the size of the rectangle to the given \a size. The top-left
+ corner is not moved.
+
+ \sa size(), setWidth(), setHeight()
+*/
+
+
+/*!
+ \fn bool QRect::contains(const QPoint &point, bool proper) const
+
+ Returns true if the the given \a point is inside or on the edge of
+ the rectangle, otherwise returns false. If \a proper is true, this
+ function only returns true if the given \a point is \e inside the
+ rectangle (i.e., not on the edge).
+
+ \sa intersects()
+*/
+
+bool QRect::contains(const QPoint &p, bool proper) const
+{
+ int l, r;
+ if (x2 < x1 - 1) {
+ l = x2;
+ r = x1;
+ } else {
+ l = x1;
+ r = x2;
+ }
+ if (proper) {
+ if (p.x() <= l || p.x() >= r)
+ return false;
+ } else {
+ if (p.x() < l || p.x() > r)
+ return false;
+ }
+ int t, b;
+ if (y2 < y1 - 1) {
+ t = y2;
+ b = y1;
+ } else {
+ t = y1;
+ b = y2;
+ }
+ if (proper) {
+ if (p.y() <= t || p.y() >= b)
+ return false;
+ } else {
+ if (p.y() < t || p.y() > b)
+ return false;
+ }
+ return true;
+}
+
+
+/*!
+ \fn bool QRect::contains(int x, int y, bool proper) const
+ \overload
+
+ Returns true if the point (\a x, \a y) is inside or on the edge of
+ the rectangle, otherwise returns false. If \a proper is true, this
+ function only returns true if the point is entirely inside the
+ rectangle(not on the edge).
+*/
+
+/*!
+ \fn bool QRect::contains(int x, int y) const
+ \overload
+
+ Returns true if the point (\a x, \a y) is inside this rectangle,
+ otherwise returns false.
+*/
+
+/*!
+ \fn bool QRect::contains(const QRect &rectangle, bool proper) const
+ \overload
+
+ Returns true if the given \a rectangle is inside this rectangle.
+ otherwise returns false. If \a proper is true, this function only
+ returns true if the \a rectangle is entirely inside this
+ rectangle (not on the edge).
+*/
+
+bool QRect::contains(const QRect &r, bool proper) const
+{
+ if (isNull() || r.isNull())
+ return false;
+
+ int l1 = x1;
+ int r1 = x1;
+ if (x2 - x1 + 1 < 0)
+ l1 = x2;
+ else
+ r1 = x2;
+
+ int l2 = r.x1;
+ int r2 = r.x1;
+ if (r.x2 - r.x1 + 1 < 0)
+ l2 = r.x2;
+ else
+ r2 = r.x2;
+
+ if (proper) {
+ if (l2 <= l1 || r2 >= r1)
+ return false;
+ } else {
+ if (l2 < l1 || r2 > r1)
+ return false;
+ }
+
+ int t1 = y1;
+ int b1 = y1;
+ if (y2 - y1 + 1 < 0)
+ t1 = y2;
+ else
+ b1 = y2;
+
+ int t2 = r.y1;
+ int b2 = r.y1;
+ if (r.y2 - r.y1 + 1 < 0)
+ t2 = r.y2;
+ else
+ b2 = r.y2;
+
+ if (proper) {
+ if (t2 <= t1 || b2 >= b1)
+ return false;
+ } else {
+ if (t2 < t1 || b2 > b1)
+ return false;
+ }
+
+ return true;
+}
+
+/*!
+ \fn QRect& QRect::operator|=(const QRect &rectangle)
+
+ Unites this rectangle with the given \a rectangle.
+
+ \sa united(), operator|()
+*/
+
+/*!
+ \fn QRect& QRect::operator&=(const QRect &rectangle)
+
+ Intersects this rectangle with the given \a rectangle.
+
+ \sa intersected(), operator&()
+*/
+
+
+/*!
+ \fn QRect QRect::operator|(const QRect &rectangle) const
+
+ Returns the bounding rectangle of this rectangle and the given \a
+ rectangle.
+
+ \sa operator|=(), united()
+*/
+
+QRect QRect::operator|(const QRect &r) const
+{
+ if (isNull())
+ return r;
+ if (r.isNull())
+ return *this;
+
+ int l1 = x1;
+ int r1 = x1;
+ if (x2 - x1 + 1 < 0)
+ l1 = x2;
+ else
+ r1 = x2;
+
+ int l2 = r.x1;
+ int r2 = r.x1;
+ if (r.x2 - r.x1 + 1 < 0)
+ l2 = r.x2;
+ else
+ r2 = r.x2;
+
+ int t1 = y1;
+ int b1 = y1;
+ if (y2 - y1 + 1 < 0)
+ t1 = y2;
+ else
+ b1 = y2;
+
+ int t2 = r.y1;
+ int b2 = r.y1;
+ if (r.y2 - r.y1 + 1 < 0)
+ t2 = r.y2;
+ else
+ b2 = r.y2;
+
+ QRect tmp;
+ tmp.x1 = qMin(l1, l2);
+ tmp.x2 = qMax(r1, r2);
+ tmp.y1 = qMin(t1, t2);
+ tmp.y2 = qMax(b1, b2);
+ return tmp;
+}
+
+/*!
+ \fn QRect QRect::unite(const QRect &rectangle) const
+ \obsolete
+
+ Use united(\a rectangle) instead.
+*/
+
+/*!
+ \fn QRect QRect::united(const QRect &rectangle) const
+ \since 4.2
+
+ Returns the bounding rectangle of this rectangle and the given \a rectangle.
+
+ \image qrect-unite.png
+
+ \sa intersected()
+*/
+
+
+/*!
+ \fn QRect QRect::operator&(const QRect &rectangle) const
+
+ Returns the intersection of this rectangle and the given \a
+ rectangle. Returns an empty rectangle if there is no intersection.
+
+ \sa operator&=(), intersected()
+*/
+
+QRect QRect::operator&(const QRect &r) const
+{
+ if (isNull() || r.isNull())
+ return QRect();
+
+ int l1 = x1;
+ int r1 = x1;
+ if (x2 - x1 + 1 < 0)
+ l1 = x2;
+ else
+ r1 = x2;
+
+ int l2 = r.x1;
+ int r2 = r.x1;
+ if (r.x2 - r.x1 + 1 < 0)
+ l2 = r.x2;
+ else
+ r2 = r.x2;
+
+ if (l1 > r2 || l2 > r1)
+ return QRect();
+
+ int t1 = y1;
+ int b1 = y1;
+ if (y2 - y1 + 1 < 0)
+ t1 = y2;
+ else
+ b1 = y2;
+
+ int t2 = r.y1;
+ int b2 = r.y1;
+ if (r.y2 - r.y1 + 1 < 0)
+ t2 = r.y2;
+ else
+ b2 = r.y2;
+
+ if (t1 > b2 || t2 > b1)
+ return QRect();
+
+ QRect tmp;
+ tmp.x1 = qMax(l1, l2);
+ tmp.x2 = qMin(r1, r2);
+ tmp.y1 = qMax(t1, t2);
+ tmp.y2 = qMin(b1, b2);
+ return tmp;
+}
+
+/*!
+ \fn QRect QRect::intersect(const QRect &rectangle) const
+ \obsolete
+
+ Use intersected(\a rectangle) instead.
+*/
+
+/*!
+ \fn QRect QRect::intersected(const QRect &rectangle) const
+ \since 4.2
+
+ Returns the intersection of this rectangle and the given \a
+ rectangle. Note that \c{r.intersected(s)} is equivalent to \c{r & s}.
+
+ \image qrect-intersect.png
+
+ \sa intersects(), united(), operator&=()
+*/
+
+/*!
+ \fn bool QRect::intersects(const QRect &rectangle) const
+
+ Returns true if this rectangle intersects with the given \a
+ rectangle (i.e., there is at least one pixel that is within both
+ rectangles), otherwise returns false.
+
+ The intersection rectangle can be retrieved using the intersected()
+ function.
+
+ \sa contains()
+*/
+
+bool QRect::intersects(const QRect &r) const
+{
+ if (isNull() || r.isNull())
+ return false;
+
+ int l1 = x1;
+ int r1 = x1;
+ if (x2 - x1 + 1 < 0)
+ l1 = x2;
+ else
+ r1 = x2;
+
+ int l2 = r.x1;
+ int r2 = r.x1;
+ if (r.x2 - r.x1 + 1 < 0)
+ l2 = r.x2;
+ else
+ r2 = r.x2;
+
+ if (l1 > r2 || l2 > r1)
+ return false;
+
+ int t1 = y1;
+ int b1 = y1;
+ if (y2 - y1 + 1 < 0)
+ t1 = y2;
+ else
+ b1 = y2;
+
+ int t2 = r.y1;
+ int b2 = r.y1;
+ if (r.y2 - r.y1 + 1 < 0)
+ t2 = r.y2;
+ else
+ b2 = r.y2;
+
+ if (t1 > b2 || t2 > b1)
+ return false;
+
+ return true;
+}
+
+/*!
+ \fn bool operator==(const QRect &r1, const QRect &r2)
+ \relates QRect
+
+ Returns true if the rectangles \a r1 and \a r2 are equal,
+ otherwise returns false.
+*/
+
+
+/*!
+ \fn bool operator!=(const QRect &r1, const QRect &r2)
+ \relates QRect
+
+ Returns true if the rectangles \a r1 and \a r2 are different, otherwise
+ returns false.
+*/
+
+
+/*****************************************************************************
+ QRect stream functions
+ *****************************************************************************/
+#ifndef QT_NO_DATASTREAM
+/*!
+ \fn QDataStream &operator<<(QDataStream &stream, const QRect &rectangle)
+ \relates QRect
+
+ Writes the given \a rectangle to the given \a stream, and returns
+ a reference to the stream.
+
+ \sa {Format of the QDataStream Operators}
+*/
+
+QDataStream &operator<<(QDataStream &s, const QRect &r)
+{
+ if (s.version() == 1)
+ s << (qint16)r.left() << (qint16)r.top()
+ << (qint16)r.right() << (qint16)r.bottom();
+ else
+ s << (qint32)r.left() << (qint32)r.top()
+ << (qint32)r.right() << (qint32)r.bottom();
+ return s;
+}
+
+/*!
+ \fn QDataStream &operator>>(QDataStream &stream, QRect &rectangle)
+ \relates QRect
+
+ Reads a rectangle from the given \a stream into the given \a
+ rectangle, and returns a reference to the stream.
+
+ \sa {Format of the QDataStream Operators}
+*/
+
+QDataStream &operator>>(QDataStream &s, QRect &r)
+{
+ if (s.version() == 1) {
+ qint16 x1, y1, x2, y2;
+ s >> x1; s >> y1; s >> x2; s >> y2;
+ r.setCoords(x1, y1, x2, y2);
+ }
+ else {
+ qint32 x1, y1, x2, y2;
+ s >> x1; s >> y1; s >> x2; s >> y2;
+ r.setCoords(x1, y1, x2, y2);
+ }
+ return s;
+}
+
+#endif // QT_NO_DATASTREAM
+
+
+#ifndef QT_NO_DEBUG_STREAM
+QDebug operator<<(QDebug dbg, const QRect &r) {
+ dbg.nospace() << "QRect(" << r.x() << ',' << r.y() << ' '
+ << r.width() << 'x' << r.height() << ')';
+ return dbg.space();
+}
+#endif
+
+/*!
+ \class QRectF
+ \ingroup multimedia
+
+ \brief The QRectF class defines a rectangle in the plane using floating
+ point precision.
+
+ A rectangle is normally expressed as an upper-left corner and a
+ size. The size (width and height) of a QRectF is always equivalent
+ to the mathematical rectangle that forms the basis for its
+ rendering.
+
+ A QRectF can be constructed with a set of left, top, width and
+ height integers, or from a QPoint and a QSize. The following code
+ creates two identical rectangles.
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qrect.cpp 1
+
+ There is also a third constructor creating a QRectF from a QRect,
+ and a corresponding toRect() function that returns a QRect object
+ based on the values of this rectangle (note that the coordinates
+ in the returned rectangle are rounded to the nearest integer).
+
+ The QRectF class provides a collection of functions that return
+ the various rectangle coordinates, and enable manipulation of
+ these. QRectF also provide functions to move the rectangle
+ relative to the various coordinates. In addition there is a
+ moveTo() function that moves the rectangle, leaving its top left
+ corner at the given coordinates. Alternatively, the translate()
+ function moves the rectangle the given offset relative to the
+ current position, and the translated() function returns a
+ translated copy of this rectangle.
+
+ The size() function returns the rectange's dimensions as a
+ QSize. The dimensions can also be retrieved separately using the
+ width() and height() functions. To manipulate the dimensions use
+ the setSize(), setWidth() or setHeight() functions. Alternatively,
+ the size can be changed by applying either of the functions
+ setting the rectangle coordinates, for example, setBottom() or
+ setRight().
+
+ The contains() function tells whether a given point is inside the
+ rectangle or not, and the intersects() function returns true if
+ this rectangle intersects with a given rectangle (otherwise
+ false). The QRectF class also provides the intersected() function
+ which returns the intersection rectangle, and the united() function
+ which returns the rectangle that encloses the given rectangle and
+ this:
+
+ \table
+ \row
+ \o \inlineimage qrect-intersect.png
+ \o \inlineimage qrect-unite.png
+ \row
+ \o intersected()
+ \o united()
+ \endtable
+
+ The isEmpty() function returns true if the rectangle's width or
+ height is less than, or equal to, 0. Note that an empty rectangle
+ is not valid: The isValid() function returns true if both width
+ and height is larger than 0. A null rectangle (isNull() == true)
+ on the other hand, has both width and height set to 0.
+
+ Note that due to the way QRect and QRectF are defined, an
+ empty QRectF is defined in essentially the same way as QRect.
+
+ Finally, QRectF objects can be streamed as well as compared.
+
+ \tableofcontents
+
+ \section1 Rendering
+
+ When using an \l {QPainter::Antialiasing}{anti-aliased} painter,
+ the boundary line of a QRectF will be rendered symmetrically on both
+ sides of the mathematical rectangle's boundary line. But when
+ using an aliased painter (the default) other rules apply.
+
+ Then, when rendering with a one pixel wide pen the QRectF's boundary
+ line will be rendered to the right and below the mathematical
+ rectangle's boundary line.
+
+ When rendering with a two pixels wide pen the boundary line will
+ be split in the middle by the mathematical rectangle. This will be
+ the case whenever the pen is set to an even number of pixels,
+ while rendering with a pen with an odd number of pixels, the spare
+ pixel will be rendered to the right and below the mathematical
+ rectangle as in the one pixel case.
+
+ \table
+ \row
+ \o \inlineimage qrect-diagram-zero.png
+ \o \inlineimage qrectf-diagram-one.png
+ \row
+ \o Logical representation
+ \o One pixel wide pen
+ \row
+ \o \inlineimage qrectf-diagram-two.png
+ \o \inlineimage qrectf-diagram-three.png
+ \row
+ \o Two pixel wide pen
+ \o Three pixel wide pen
+ \endtable
+
+ \section1 Coordinates
+
+ The QRectF class provides a collection of functions that return
+ the various rectangle coordinates, and enable manipulation of
+ these. QRectF also provide functions to move the rectangle
+ relative to the various coordinates.
+
+ For example: the bottom(), setBottom() and moveBottom() functions:
+ bottom() returns the y-coordinate of the rectangle's bottom edge,
+ setBottom() sets the bottom edge of the rectangle to the given y
+ coordinate (it may change the height, but will never change the
+ rectangle's top edge) and moveBottom() moves the entire rectangle
+ vertically, leaving the rectangle's bottom edge at the given y
+ coordinate and its size unchanged.
+
+ \image qrectf-coordinates.png
+
+ It is also possible to add offsets to this rectangle's coordinates
+ using the adjust() function, as well as retrieve a new rectangle
+ based on adjustments of the original one using the adjusted()
+ function. If either of the width and height is negative, use the
+ normalized() function to retrieve a rectangle where the corners
+ are swapped.
+
+ In addition, QRectF provides the getCoords() function which extracts
+ the position of the rectangle's top-left and bottom-right corner,
+ and the getRect() function which extracts the rectangle's top-left
+ corner, width and height. Use the setCoords() and setRect()
+ function to manipulate the rectangle's coordinates and dimensions
+ in one go.
+
+ \sa QRect, QRegion
+*/
+
+/*****************************************************************************
+ QRectF member functions
+ *****************************************************************************/
+
+/*!
+ \fn QRectF::QRectF()
+
+ Constructs a null rectangle.
+
+ \sa isNull()
+*/
+
+/*!
+ \fn QRectF::QRectF(const QPointF &topLeft, const QSizeF &size)
+
+ Constructs a rectangle with the given \a topLeft corner and the given \a size.
+
+ \sa setTopLeft(), setSize()
+*/
+
+/*!
+ \fn QRectF::QRectF(const QPointF &topLeft, const QPointF &bottomRight)
+ \since 4.3
+
+ Constructs a rectangle with the given \a topLeft and \a bottomRight corners.
+
+ \sa setTopLeft(), setBottomRight()
+*/
+
+/*!
+ \fn QRectF::QRectF(qreal x, qreal y, qreal width, qreal height)
+
+ Constructs a rectangle with (\a x, \a y) as its top-left corner
+ and the given \a width and \a height.
+
+ \sa setRect()
+*/
+
+/*!
+ \fn QRectF::QRectF(const QRect &rectangle)
+
+ Constructs a QRectF rectangle from the given QRect \a rectangle.
+
+ \sa toRect()
+*/
+
+/*!
+ \fn bool QRectF::isNull() const
+
+ Returns true if the rectangle is a null rectangle, otherwise returns false.
+
+ A null rectangle has both the width and the height set to 0. A
+ null rectangle is also empty, and hence not valid.
+
+ \sa isEmpty(), isValid()
+*/
+
+/*!
+ \fn bool QRectF::isEmpty() const
+
+ Returns true if the rectangle is empty, otherwise returns false.
+
+ An empty rectangle has width() <= 0 or height() <= 0. An empty
+ rectangle is not valid (i.e., isEmpty() == !isValid()).
+
+ Use the normalized() function to retrieve a rectangle where the
+ corners are swapped.
+
+ \sa isNull(), isValid(), normalized()
+*/
+
+/*!
+ \fn bool QRectF::isValid() const
+
+ Returns true if the rectangle is valid, otherwise returns false.
+
+ A valid rectangle has a width() > 0 and height() > 0. Note that
+ non-trivial operations like intersections are not defined for
+ invalid rectangles. A valid rectangle is not empty (i.e., isValid()
+ == !isEmpty()).
+
+ \sa isNull(), isEmpty(), normalized()
+*/
+
+
+/*!
+ Returns a normalized rectangle; i.e., a rectangle that has a
+ non-negative width and height.
+
+ If width() < 0 the function swaps the left and right corners, and
+ it swaps the top and bottom corners if height() < 0.
+
+ \sa isValid(), isEmpty()
+*/
+
+QRectF QRectF::normalized() const
+{
+ QRectF r = *this;
+ if (r.w < 0) {
+ r.xp += r.w;
+ r.w = -r.w;
+ }
+ if (r.h < 0) {
+ r.yp += r.h;
+ r.h = -r.h;
+ }
+ return r;
+}
+
+/*!
+ \fn qreal QRectF::x() const
+
+ Returns the x-coordinate of the rectangle's left edge. Equivalent
+ to left().
+
+
+ \sa setX(), y(), topLeft()
+*/
+
+/*!
+ \fn qreal QRectF::y() const
+
+ Returns the y-coordinate of the rectangle's top edge. Equivalent
+ to top().
+
+ \sa setY(), x(), topLeft()
+*/
+
+
+/*!
+ \fn void QRectF::setLeft(qreal x)
+
+ Sets the left edge of the rectangle to the given \a x
+ coordinate. May change the width, but will never change the right
+ edge of the rectangle.
+
+ Equivalent to setX().
+
+ \sa left(), moveLeft()
+*/
+
+/*!
+ \fn void QRectF::setTop(qreal y)
+
+ Sets the top edge of the rectangle to the given \a y coordinate. May
+ change the height, but will never change the bottom edge of the
+ rectangle.
+
+ Equivalent to setY().
+
+ \sa top(), moveTop()
+*/
+
+/*!
+ \fn void QRectF::setRight(qreal x)
+
+ Sets the right edge of the rectangle to the given \a x
+ coordinate. May change the width, but will never change the left
+ edge of the rectangle.
+
+ \sa right(), moveRight()
+*/
+
+/*!
+ \fn void QRectF::setBottom(qreal y)
+
+ Sets the bottom edge of the rectangle to the given \a y
+ coordinate. May change the height, but will never change the top
+ edge of the rectangle.
+
+ \sa bottom(), moveBottom()
+*/
+
+/*!
+ \fn void QRectF::setX(qreal x)
+
+ Sets the left edge of the rectangle to the given \a x
+ coordinate. May change the width, but will never change the right
+ edge of the rectangle.
+
+ Equivalent to setLeft().
+
+ \sa x(), setY(), setTopLeft()
+*/
+
+/*!
+ \fn void QRectF::setY(qreal y)
+
+ Sets the top edge of the rectangle to the given \a y
+ coordinate. May change the height, but will never change the
+ bottom edge of the rectangle.
+
+ Equivalent to setTop().
+
+ \sa y(), setX(), setTopLeft()
+*/
+
+/*!
+ \fn void QRectF::setTopLeft(const QPointF &position)
+
+ Set the top-left corner of the rectangle to the given \a
+ position. May change the size, but will never change the
+ bottom-right corner of the rectangle.
+
+ \sa topLeft(), moveTopLeft()
+*/
+
+/*!
+ \fn void QRectF::setBottomRight(const QPointF &position)
+
+ Set the bottom-right corner of the rectangle to the given \a
+ position. May change the size, but will never change the
+ top-left corner of the rectangle.
+
+ \sa bottomRight(), moveBottomRight()
+*/
+
+/*!
+ \fn void QRectF::setTopRight(const QPointF &position)
+
+ Set the top-right corner of the rectangle to the given \a
+ position. May change the size, but will never change the
+ bottom-left corner of the rectangle.
+
+ \sa topRight(), moveTopRight()
+*/
+
+/*!
+ \fn void QRectF::setBottomLeft(const QPointF &position)
+
+ Set the bottom-left corner of the rectangle to the given \a
+ position. May change the size, but will never change the
+ top-right corner of the rectangle.
+
+ \sa bottomLeft(), moveBottomLeft()
+*/
+
+/*!
+ \fn QPointF QRectF::center() const
+
+ Returns the center point of the rectangle.
+
+ \sa moveCenter()
+*/
+
+
+/*!
+ \fn void QRectF::getRect(qreal *x, qreal *y, qreal *width, qreal *height) const
+
+ Extracts the position of the rectangle's top-left corner to *\a x and
+ *\a y, and its dimensions to *\a width and *\a height.
+
+ \sa setRect(), getCoords()
+*/
+
+
+/*!
+ \fn void QRectF::getCoords(qreal *x1, qreal *y1, qreal *x2, qreal *y2) const
+
+ Extracts the position of the rectangle's top-left corner to *\a x1
+ and *\a y1, and the position of the bottom-right corner to *\a x2 and
+ *\a y2.
+
+ \sa setCoords(), getRect()
+*/
+
+/*!
+ \fn void QRectF::moveLeft(qreal x)
+
+ Moves the rectangle horizontally, leaving the rectangle's left
+ edge at the given \a x coordinate. The rectangle's size is
+ unchanged.
+
+ \sa left(), setLeft(), moveRight()
+*/
+
+/*!
+ \fn void QRectF::moveTop(qreal y)
+
+ Moves the rectangle vertically, leaving the rectangle's top line
+ at the given \a y coordinate. The rectangle's size is unchanged.
+
+ \sa top(), setTop(), moveBottom()
+*/
+
+
+/*!
+ \fn void QRectF::moveRight(qreal x)
+
+ Moves the rectangle horizontally, leaving the rectangle's right
+ edge at the given \a x coordinate. The rectangle's size is
+ unchanged.
+
+ \sa right(), setRight(), moveLeft()
+*/
+
+
+/*!
+ \fn void QRectF::moveBottom(qreal y)
+
+ Moves the rectangle vertically, leaving the rectangle's bottom
+ edge at the given \a y coordinate. The rectangle's size is
+ unchanged.
+
+ \sa bottom(), setBottom(), moveTop()
+*/
+
+
+/*!
+ \fn void QRectF::moveTopLeft(const QPointF &position)
+
+ Moves the rectangle, leaving the top-left corner at the given \a
+ position. The rectangle's size is unchanged.
+
+ \sa setTopLeft(), moveTop(), moveLeft()
+*/
+
+
+/*!
+ \fn void QRectF::moveBottomRight(const QPointF &position)
+
+ Moves the rectangle, leaving the bottom-right corner at the given
+ \a position. The rectangle's size is unchanged.
+
+ \sa setBottomRight(), moveBottom(), moveRight()
+*/
+
+
+/*!
+ \fn void QRectF::moveTopRight(const QPointF &position)
+
+ Moves the rectangle, leaving the top-right corner at the given
+ \a position. The rectangle's size is unchanged.
+
+ \sa setTopRight(), moveTop(), moveRight()
+*/
+
+
+/*!
+ \fn void QRectF::moveBottomLeft(const QPointF &position)
+
+ Moves the rectangle, leaving the bottom-left corner at the given
+ \a position. The rectangle's size is unchanged.
+
+ \sa setBottomLeft(), moveBottom(), moveLeft()
+*/
+
+
+/*!
+ \fn void QRectF::moveTo(qreal x, qreal y)
+
+ Moves the rectangle, leaving the top-left corner at the given
+ position (\a x, \a y). The rectangle's size is unchanged.
+
+ \sa translate(), moveTopLeft()
+*/
+
+/*!
+ \fn void QRectF::moveTo(const QPointF &position)
+ \overload
+
+ Moves the rectangle, leaving the top-left corner at the given \a
+ position.
+*/
+
+/*!
+ \fn void QRectF::translate(qreal dx, qreal dy)
+
+ Moves the rectangle \a dx along the x-axis and \a dy along the y-axis,
+ relative to the current position. Positive values move the rectangle to the
+ right and downwards.
+
+ \sa moveTopLeft(), moveTo(), translated()
+*/
+
+
+/*!
+ \fn void QRectF::translate(const QPointF &offset)
+ \overload
+
+ Moves the rectangle \a{offset}.\l{QPointF::x()}{x()} along the x
+ axis and \a{offset}.\l{QPointF::y()}{y()} along the y axis,
+ relative to the current position.
+*/
+
+
+/*!
+ \fn QRectF QRectF::translated(qreal dx, qreal dy) const
+
+ Returns a copy of the rectangle that is translated \a dx along the
+ x axis and \a dy along the y axis, relative to the current
+ position. Positive values move the rectangle to the right and
+ down.
+
+ \sa translate()
+*/
+
+
+/*!
+ \fn QRectF QRectF::translated(const QPointF &offset) const
+ \overload
+
+ Returns a copy of the rectangle that is translated
+ \a{offset}.\l{QPointF::x()}{x()} along the x axis and
+ \a{offset}.\l{QPointF::y()}{y()} along the y axis, relative to the
+ current position.
+*/
+
+
+/*!
+ \fn void QRectF::setRect(qreal x, qreal y, qreal width, qreal height)
+
+ Sets the coordinates of the rectangle's top-left corner to (\a x,
+ \a y), and its size to the given \a width and \a height.
+
+ \sa getRect(), setCoords()
+*/
+
+
+/*!
+ \fn void QRectF::setCoords(qreal x1, qreal y1, qreal x2, qreal y2)
+
+ Sets the coordinates of the rectangle's top-left corner to (\a x1,
+ \a y1), and the coordinates of its bottom-right corner to (\a x2,
+ \a y2).
+
+ \sa getCoords() setRect()
+*/
+
+/*!
+ \fn QRectF QRectF::adjusted(qreal dx1, qreal dy1, qreal dx2, qreal dy2) const
+
+ Returns a new rectangle with \a dx1, \a dy1, \a dx2 and \a dy2
+ added respectively to the existing coordinates of this rectangle.
+
+ \sa adjust()
+*/
+
+/*! \fn void QRectF::adjust(qreal dx1, qreal dy1, qreal dx2, qreal dy2)
+
+ Adds \a dx1, \a dy1, \a dx2 and \a dy2 respectively to the
+ existing coordinates of the rectangle.
+
+ \sa adjusted(), setRect()
+*/
+/*!
+ \fn QSizeF QRectF::size() const
+
+ Returns the size of the rectangle.
+
+ \sa setSize(), width(), height()
+*/
+
+/*!
+ \fn qreal QRectF::width() const
+
+ Returns the width of the rectangle.
+
+ \sa setWidth(), height(), size()
+*/
+
+/*!
+ \fn qreal QRectF::height() const
+
+ Returns the height of the rectangle.
+
+ \sa setHeight(), width(), size()
+*/
+
+/*!
+ \fn void QRectF::setWidth(qreal width)
+
+ Sets the width of the rectangle to the given \a width. The right
+ edge is changed, but not the left one.
+
+ \sa width(), setSize()
+*/
+
+
+/*!
+ \fn void QRectF::setHeight(qreal height)
+
+ Sets the height of the rectangle to the given \a height. The bottom
+ edge is changed, but not the top one.
+
+ \sa height(), setSize()
+*/
+
+
+/*!
+ \fn void QRectF::setSize(const QSizeF &size)
+
+ Sets the size of the rectangle to the given \a size. The top-left
+ corner is not moved.
+
+ \sa size(), setWidth(), setHeight()
+*/
+
+
+/*!
+ \fn bool QRectF::contains(const QPointF &point) const
+
+ Returns true if the given \a point is inside or on the edge of the
+ rectangle; otherwise returns false.
+
+ \sa intersects()
+*/
+
+bool QRectF::contains(const QPointF &p) const
+{
+ qreal l = xp;
+ qreal r = xp;
+ if (w < 0)
+ l += w;
+ else
+ r += w;
+ if (l == r) // null rect
+ return false;
+
+ if (p.x() < l || p.x() > r)
+ return false;
+
+ qreal t = yp;
+ qreal b = yp;
+ if (h < 0)
+ t += h;
+ else
+ b += h;
+ if (t == b) // null rect
+ return false;
+
+ if (p.y() < t || p.y() > b)
+ return false;
+
+ return true;
+}
+
+
+/*!
+ \fn bool QRectF::contains(qreal x, qreal y) const
+ \overload
+
+ Returns true if the point (\a x, \a y) is inside or on the edge of
+ the rectangle; otherwise returns false.
+*/
+
+/*!
+ \fn bool QRectF::contains(const QRectF &rectangle) const
+ \overload
+
+ Returns true if the given \a rectangle is inside this rectangle;
+ otherwise returns false.
+*/
+
+bool QRectF::contains(const QRectF &r) const
+{
+ qreal l1 = xp;
+ qreal r1 = xp;
+ if (w < 0)
+ l1 += w;
+ else
+ r1 += w;
+ if (l1 == r1) // null rect
+ return false;
+
+ qreal l2 = r.xp;
+ qreal r2 = r.xp;
+ if (r.w < 0)
+ l2 += r.w;
+ else
+ r2 += r.w;
+ if (l2 == r2) // null rect
+ return false;
+
+ if (l2 < l1 || r2 > r1)
+ return false;
+
+ qreal t1 = yp;
+ qreal b1 = yp;
+ if (h < 0)
+ t1 += h;
+ else
+ b1 += h;
+ if (t1 == b1) // null rect
+ return false;
+
+ qreal t2 = r.yp;
+ qreal b2 = r.yp;
+ if (r.h < 0)
+ t2 += r.h;
+ else
+ b2 += r.h;
+ if (t2 == b2) // null rect
+ return false;
+
+ if (t2 < t1 || b2 > b1)
+ return false;
+
+ return true;
+}
+
+/*!
+ \fn qreal QRectF::left() const
+
+ Returns the x-coordinate of the rectangle's left edge. Equivalent
+ to x().
+
+ \sa setLeft(), topLeft(), bottomLeft()
+*/
+
+/*!
+ \fn qreal QRectF::top() const
+
+ Returns the y-coordinate of the rectangle's top edge. Equivalent
+ to y().
+
+ \sa setTop(), topLeft(), topRight()
+*/
+
+/*!
+ \fn qreal QRectF::right() const
+
+ Returns the x-coordinate of the rectangle's right edge.
+
+ \sa setRight(), topRight(), bottomRight()
+*/
+
+/*!
+ \fn qreal QRectF::bottom() const
+
+ Returns the y-coordinate of the rectangle's bottom edge.
+
+ \sa setBottom(), bottomLeft(), bottomRight()
+*/
+
+/*!
+ \fn QPointF QRectF::topLeft() const
+
+ Returns the position of the rectangle's top-left corner.
+
+ \sa setTopLeft(), top(), left()
+*/
+
+/*!
+ \fn QPointF QRectF::bottomRight() const
+
+ Returns the position of the rectangle's bottom-right corner.
+
+ \sa setBottomRight(), bottom(), right()
+*/
+
+/*!
+ \fn QPointF QRectF::topRight() const
+
+ Returns the position of the rectangle's top-right corner.
+
+ \sa setTopRight(), top(), right()
+*/
+
+/*!
+ \fn QPointF QRectF::bottomLeft() const
+
+ Returns the position of the rectangle's bottom-left corner.
+
+ \sa setBottomLeft(), bottom(), left()
+*/
+
+/*!
+ \fn QRectF& QRectF::operator|=(const QRectF &rectangle)
+
+ Unites this rectangle with the given \a rectangle.
+
+ \sa united(), operator|()
+*/
+
+/*!
+ \fn QRectF& QRectF::operator&=(const QRectF &rectangle)
+
+ Intersects this rectangle with the given \a rectangle.
+
+ \sa intersected(), operator|=()
+*/
+
+
+/*!
+ \fn QRectF QRectF::operator|(const QRectF &rectangle) const
+
+ Returns the bounding rectangle of this rectangle and the given \a rectangle.
+
+ \sa united(), operator|=()
+*/
+
+QRectF QRectF::operator|(const QRectF &r) const
+{
+ qreal l1 = xp;
+ qreal r1 = xp;
+ if (w < 0)
+ l1 += w;
+ else
+ r1 += w;
+ if (l1 == r1) // null rect
+ return r;
+
+ qreal l2 = r.xp;
+ qreal r2 = r.xp;
+ if (r.w < 0)
+ l2 += r.w;
+ else
+ r2 += r.w;
+ if (l2 == r2) // null rect
+ return *this;
+
+ qreal t1 = yp;
+ qreal b1 = yp;
+ if (h < 0)
+ t1 += h;
+ else
+ b1 += h;
+ if (t1 == b1) // null rect
+ return r;
+
+ qreal t2 = r.yp;
+ qreal b2 = r.yp;
+ if (r.h < 0)
+ t2 += r.h;
+ else
+ b2 += r.h;
+ if (t2 == b2) // null rect
+ return *this;
+
+ QRectF tmp;
+ tmp.xp = qMin(l1, l2);
+ tmp.yp = qMin(t1, t2);
+ tmp.w = qMax(r1, r2) - tmp.xp;
+ tmp.h = qMax(b1, b2) - tmp.yp;
+ return tmp;
+}
+
+/*!
+ \fn QRectF QRectF::unite(const QRectF &rectangle) const
+ \obsolete
+
+ Use united(\a rectangle) instead.
+*/
+
+/*!
+ \fn QRectF QRectF::united(const QRectF &rectangle) const
+ \since 4.2
+
+ Returns the bounding rectangle of this rectangle and the given \a
+ rectangle.
+
+ \image qrect-unite.png
+
+ \sa intersected()
+*/
+
+
+/*!
+ \fn QRectF QRectF::operator &(const QRectF &rectangle) const
+
+ Returns the intersection of this rectangle and the given \a
+ rectangle. Returns an empty rectangle if there is no intersection.
+
+ \sa operator&=(), intersected()
+*/
+
+QRectF QRectF::operator&(const QRectF &r) const
+{
+ qreal l1 = xp;
+ qreal r1 = xp;
+ if (w < 0)
+ l1 += w;
+ else
+ r1 += w;
+ if (l1 == r1) // null rect
+ return QRectF();
+
+ qreal l2 = r.xp;
+ qreal r2 = r.xp;
+ if (r.w < 0)
+ l2 += r.w;
+ else
+ r2 += r.w;
+ if (l2 == r2) // null rect
+ return QRectF();
+
+ if (l1 >= r2 || l2 >= r1)
+ return QRectF();
+
+ qreal t1 = yp;
+ qreal b1 = yp;
+ if (h < 0)
+ t1 += h;
+ else
+ b1 += h;
+ if (t1 == b1) // null rect
+ return QRectF();
+
+ qreal t2 = r.yp;
+ qreal b2 = r.yp;
+ if (r.h < 0)
+ t2 += r.h;
+ else
+ b2 += r.h;
+ if (t2 == b2) // null rect
+ return QRectF();
+
+ if (t1 >= b2 || t2 >= b1)
+ return QRectF();
+
+ QRectF tmp;
+ tmp.xp = qMax(l1, l2);
+ tmp.yp = qMax(t1, t2);
+ tmp.w = qMin(r1, r2) - tmp.xp;
+ tmp.h = qMin(b1, b2) - tmp.yp;
+ return tmp;
+}
+
+/*!
+ \fn QRectF QRectF::intersect(const QRectF &rectangle) const
+ \obsolete
+
+ Use intersected(\a rectangle) instead.
+*/
+
+/*!
+ \fn QRectF QRectF::intersected(const QRectF &rectangle) const
+ \since 4.2
+
+ Returns the intersection of this rectangle and the given \a
+ rectangle. Note that \c {r.intersected(s)} is equivalent to \c
+ {r & s}.
+
+ \image qrect-intersect.png
+
+ \sa intersects(), united(), operator&=()
+*/
+
+/*!
+ \fn bool QRectF::intersects(const QRectF &rectangle) const
+
+ Returns true if this rectangle intersects with the given \a
+ rectangle (i.e. there is a non-empty area of overlap between
+ them), otherwise returns false.
+
+ The intersection rectangle can be retrieved using the intersected()
+ function.
+
+ \sa contains()
+*/
+
+bool QRectF::intersects(const QRectF &r) const
+{
+ qreal l1 = xp;
+ qreal r1 = xp;
+ if (w < 0)
+ l1 += w;
+ else
+ r1 += w;
+ if (l1 == r1) // null rect
+ return false;
+
+ qreal l2 = r.xp;
+ qreal r2 = r.xp;
+ if (r.w < 0)
+ l2 += r.w;
+ else
+ r2 += r.w;
+ if (l2 == r2) // null rect
+ return false;
+
+ if (l1 >= r2 || l2 >= r1)
+ return false;
+
+ qreal t1 = yp;
+ qreal b1 = yp;
+ if (h < 0)
+ t1 += h;
+ else
+ b1 += h;
+ if (t1 == b1) // null rect
+ return false;
+
+ qreal t2 = r.yp;
+ qreal b2 = r.yp;
+ if (r.h < 0)
+ t2 += r.h;
+ else
+ b2 += r.h;
+ if (t2 == b2) // null rect
+ return false;
+
+ if (t1 >= b2 || t2 >= b1)
+ return false;
+
+ return true;
+}
+
+/*!
+ \fn QRect QRectF::toRect() const
+
+ Returns a QRect based on the values of this rectangle. Note that the
+ coordinates in the returned rectangle are rounded to the nearest integer.
+
+ \sa QRectF(), toAlignedRect()
+*/
+
+/*!
+ \fn QRect QRectF::toAlignedRect() const
+ \since 4.3
+
+ Returns a QRect based on the values of this rectangle that is the
+ smallest possible integer rectangle that completely contains this
+ rectangle.
+
+ \sa toRect()
+*/
+
+QRect QRectF::toAlignedRect() const
+{
+ int xmin = int(qFloor(xp));
+ int xmax = int(qCeil(xp + w));
+ int ymin = int(qFloor(yp));
+ int ymax = int(qCeil(yp + h));
+ return QRect(xmin, ymin, xmax - xmin, ymax - ymin);
+}
+
+/*!
+ \fn void QRectF::moveCenter(const QPointF &position)
+
+ Moves the rectangle, leaving the center point at the given \a
+ position. The rectangle's size is unchanged.
+
+ \sa center()
+*/
+
+/*!
+ \fn bool operator==(const QRectF &r1, const QRectF &r2)
+ \relates QRectF
+
+ Returns true if the rectangles \a r1 and \a r2 are equal,
+ otherwise returns false.
+*/
+
+
+/*!
+ \fn bool operator!=(const QRectF &r1, const QRectF &r2)
+ \relates QRectF
+
+ Returns true if the rectangles \a r1 and \a r2 are different, otherwise
+ returns false.
+*/
+
+/*****************************************************************************
+ QRectF stream functions
+ *****************************************************************************/
+#ifndef QT_NO_DATASTREAM
+/*!
+ \fn QDataStream &operator<<(QDataStream &stream, const QRectF &rectangle)
+
+ \relates QRectF
+
+ Writes the \a rectangle to the \a stream, and returns a reference to the
+ stream.
+
+ \sa \link datastreamformat.html Format of the QDataStream operators \endlink
+*/
+
+QDataStream &operator<<(QDataStream &s, const QRectF &r)
+{
+ s << double(r.x()) << double(r.y()) << double(r.width()) << double(r.height());
+ return s;
+}
+
+/*!
+ \fn QDataStream &operator>>(QDataStream &stream, QRectF &rectangle)
+
+ \relates QRectF
+
+ Reads a \a rectangle from the \a stream, and returns a reference to the
+ stream.
+
+ \sa \link datastreamformat.html Format of the QDataStream operators \endlink
+*/
+
+QDataStream &operator>>(QDataStream &s, QRectF &r)
+{
+ double x, y, w, h;
+ s >> x;
+ s >> y;
+ s >> w;
+ s >> h;
+ r.setRect(qreal(x), qreal(y), qreal(w), qreal(h));
+ return s;
+}
+
+#endif // QT_NO_DATASTREAM
+
+
+#ifndef QT_NO_DEBUG_STREAM
+QDebug operator<<(QDebug dbg, const QRectF &r) {
+ dbg.nospace() << "QRectF(" << r.x() << ',' << r.y() << ' '
+ << r.width() << 'x' << r.height() << ')';
+ return dbg.space();
+}
+#endif
+
+QT_END_NAMESPACE
diff --git a/src/corelib/tools/qrect.h b/src/corelib/tools/qrect.h
new file mode 100644
index 0000000000..194787e3d7
--- /dev/null
+++ b/src/corelib/tools/qrect.h
@@ -0,0 +1,858 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QRECT_H
+#define QRECT_H
+
+#include <QtCore/qsize.h>
+#include <QtCore/qpoint.h>
+
+#ifdef topLeft
+#error qrect.h must be included before any header file that defines topLeft
+#endif
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Core)
+
+class Q_CORE_EXPORT QRect
+{
+public:
+ QRect() { x1 = y1 = 0; x2 = y2 = -1; }
+ QRect(const QPoint &topleft, const QPoint &bottomright);
+ QRect(const QPoint &topleft, const QSize &size);
+ QRect(int left, int top, int width, int height);
+
+ bool isNull() const;
+ bool isEmpty() const;
+ bool isValid() const;
+
+ int left() const;
+ int top() const;
+ int right() const;
+ int bottom() const;
+ QRect normalized() const;
+
+#ifdef QT3_SUPPORT
+ QT3_SUPPORT int &rLeft() { return x1; }
+ QT3_SUPPORT int &rTop() { return y1; }
+ QT3_SUPPORT int &rRight() { return x2; }
+ QT3_SUPPORT int &rBottom() { return y2; }
+
+ QT3_SUPPORT QRect normalize() const { return normalized(); }
+#endif
+
+ int x() const;
+ int y() const;
+ void setLeft(int pos);
+ void setTop(int pos);
+ void setRight(int pos);
+ void setBottom(int pos);
+ void setX(int x);
+ void setY(int y);
+
+ void setTopLeft(const QPoint &p);
+ void setBottomRight(const QPoint &p);
+ void setTopRight(const QPoint &p);
+ void setBottomLeft(const QPoint &p);
+
+ QPoint topLeft() const;
+ QPoint bottomRight() const;
+ QPoint topRight() const;
+ QPoint bottomLeft() const;
+ QPoint center() const;
+
+ void moveLeft(int pos);
+ void moveTop(int pos);
+ void moveRight(int pos);
+ void moveBottom(int pos);
+ void moveTopLeft(const QPoint &p);
+ void moveBottomRight(const QPoint &p);
+ void moveTopRight(const QPoint &p);
+ void moveBottomLeft(const QPoint &p);
+ void moveCenter(const QPoint &p);
+
+ inline void translate(int dx, int dy);
+ inline void translate(const QPoint &p);
+ inline QRect translated(int dx, int dy) const;
+ inline QRect translated(const QPoint &p) const;
+
+ void moveTo(int x, int t);
+ void moveTo(const QPoint &p);
+
+#ifdef QT3_SUPPORT
+ QT3_SUPPORT void moveBy(int dx, int dy) { translate(dx, dy); }
+ QT3_SUPPORT void moveBy(const QPoint &p) { translate(p); }
+#endif
+
+ void setRect(int x, int y, int w, int h);
+ inline void getRect(int *x, int *y, int *w, int *h) const;
+
+ void setCoords(int x1, int y1, int x2, int y2);
+#ifdef QT3_SUPPORT
+ QT3_SUPPORT void addCoords(int x1, int y1, int x2, int y2);
+#endif
+ inline void getCoords(int *x1, int *y1, int *x2, int *y2) const;
+
+ inline void adjust(int x1, int y1, int x2, int y2);
+ inline QRect adjusted(int x1, int y1, int x2, int y2) const;
+
+ QSize size() const;
+ int width() const;
+ int height() const;
+ void setWidth(int w);
+ void setHeight(int h);
+ void setSize(const QSize &s);
+
+ QRect operator|(const QRect &r) const;
+ QRect operator&(const QRect &r) const;
+ QRect& operator|=(const QRect &r);
+ QRect& operator&=(const QRect &r);
+
+ bool contains(const QPoint &p, bool proper=false) const;
+ bool contains(int x, int y) const; // inline methods, _don't_ merge these
+ bool contains(int x, int y, bool proper) const;
+ bool contains(const QRect &r, bool proper = false) const;
+ QRect unite(const QRect &r) const; // ### Qt 5: make QT4_SUPPORT
+ QRect united(const QRect &other) const;
+ QRect intersect(const QRect &r) const; // ### Qt 5: make QT4_SUPPORT
+ QRect intersected(const QRect &other) const;
+ bool intersects(const QRect &r) const;
+
+ friend Q_CORE_EXPORT_INLINE bool operator==(const QRect &, const QRect &);
+ friend Q_CORE_EXPORT_INLINE bool operator!=(const QRect &, const QRect &);
+
+#ifdef QT3_SUPPORT
+ inline QT3_SUPPORT void rect(int *x, int *y, int *w, int *h) const { getRect(x, y, w, h); }
+ inline QT3_SUPPORT void coords(int *ax1, int *ay1, int *ax2, int *ay2) const
+ { getCoords(ax1, ay1, ax2, ay2); }
+#endif
+
+private:
+#if defined(Q_WS_X11)
+ friend void qt_setCoords(QRect *r, int xp1, int yp1, int xp2, int yp2);
+#endif
+ // ### Qt 5; remove the ifdef and just have the same order on all platforms.
+#if defined(Q_OS_MAC)
+ int y1;
+ int x1;
+ int y2;
+ int x2;
+#else
+ int x1;
+ int y1;
+ int x2;
+ int y2;
+#endif
+
+};
+Q_DECLARE_TYPEINFO(QRect, Q_MOVABLE_TYPE);
+
+Q_CORE_EXPORT_INLINE bool operator==(const QRect &, const QRect &);
+Q_CORE_EXPORT_INLINE bool operator!=(const QRect &, const QRect &);
+
+
+/*****************************************************************************
+ QRect stream functions
+ *****************************************************************************/
+#ifndef QT_NO_DATASTREAM
+Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QRect &);
+Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QRect &);
+#endif
+
+/*****************************************************************************
+ QRect inline member functions
+ *****************************************************************************/
+
+inline QRect::QRect(int aleft, int atop, int awidth, int aheight)
+{
+ x1 = aleft;
+ y1 = atop;
+ x2 = (aleft + awidth - 1);
+ y2 = (atop + aheight - 1);
+}
+
+inline QRect::QRect(const QPoint &atopLeft, const QPoint &abottomRight)
+{
+ x1 = atopLeft.x();
+ y1 = atopLeft.y();
+ x2 = abottomRight.x();
+ y2 = abottomRight.y();
+}
+
+inline QRect::QRect(const QPoint &atopLeft, const QSize &asize)
+{
+ x1 = atopLeft.x();
+ y1 = atopLeft.y();
+ x2 = (x1+asize.width() - 1);
+ y2 = (y1+asize.height() - 1);
+}
+
+inline bool QRect::isNull() const
+{ return x2 == x1 - 1 && y2 == y1 - 1; }
+
+inline bool QRect::isEmpty() const
+{ return x1 > x2 || y1 > y2; }
+
+inline bool QRect::isValid() const
+{ return x1 <= x2 && y1 <= y2; }
+
+inline int QRect::left() const
+{ return x1; }
+
+inline int QRect::top() const
+{ return y1; }
+
+inline int QRect::right() const
+{ return x2; }
+
+inline int QRect::bottom() const
+{ return y2; }
+
+inline int QRect::x() const
+{ return x1; }
+
+inline int QRect::y() const
+{ return y1; }
+
+inline void QRect::setLeft(int pos)
+{ x1 = pos; }
+
+inline void QRect::setTop(int pos)
+{ y1 = pos; }
+
+inline void QRect::setRight(int pos)
+{ x2 = pos; }
+
+inline void QRect::setBottom(int pos)
+{ y2 = pos; }
+
+inline void QRect::setTopLeft(const QPoint &p)
+{ x1 = p.x(); y1 = p.y(); }
+
+inline void QRect::setBottomRight(const QPoint &p)
+{ x2 = p.x(); y2 = p.y(); }
+
+inline void QRect::setTopRight(const QPoint &p)
+{ x2 = p.x(); y1 = p.y(); }
+
+inline void QRect::setBottomLeft(const QPoint &p)
+{ x1 = p.x(); y2 = p.y(); }
+
+inline void QRect::setX(int ax)
+{ x1 = ax; }
+
+inline void QRect::setY(int ay)
+{ y1 = ay; }
+
+inline QPoint QRect::topLeft() const
+{ return QPoint(x1, y1); }
+
+inline QPoint QRect::bottomRight() const
+{ return QPoint(x2, y2); }
+
+inline QPoint QRect::topRight() const
+{ return QPoint(x2, y1); }
+
+inline QPoint QRect::bottomLeft() const
+{ return QPoint(x1, y2); }
+
+inline QPoint QRect::center() const
+{ return QPoint((x1+x2)/2, (y1+y2)/2); }
+
+inline int QRect::width() const
+{ return x2 - x1 + 1; }
+
+inline int QRect::height() const
+{ return y2 - y1 + 1; }
+
+inline QSize QRect::size() const
+{ return QSize(width(), height()); }
+
+inline void QRect::translate(int dx, int dy)
+{
+ x1 += dx;
+ y1 += dy;
+ x2 += dx;
+ y2 += dy;
+}
+
+inline void QRect::translate(const QPoint &p)
+{
+ x1 += p.x();
+ y1 += p.y();
+ x2 += p.x();
+ y2 += p.y();
+}
+
+inline QRect QRect::translated(int dx, int dy) const
+{ return QRect(QPoint(x1 + dx, y1 + dy), QPoint(x2 + dx, y2 + dy)); }
+
+inline QRect QRect::translated(const QPoint &p) const
+{ return QRect(QPoint(x1 + p.x(), y1 + p.y()), QPoint(x2 + p.x(), y2 + p.y())); }
+
+inline void QRect::moveTo(int ax, int ay)
+{
+ x2 += ax - x1;
+ y2 += ay - y1;
+ x1 = ax;
+ y1 = ay;
+}
+
+inline void QRect::moveTo(const QPoint &p)
+{
+ x2 += p.x() - x1;
+ y2 += p.y() - y1;
+ x1 = p.x();
+ y1 = p.y();
+}
+
+inline void QRect::moveLeft(int pos)
+{ x2 += (pos - x1); x1 = pos; }
+
+inline void QRect::moveTop(int pos)
+{ y2 += (pos - y1); y1 = pos; }
+
+inline void QRect::moveRight(int pos)
+{
+ x1 += (pos - x2);
+ x2 = pos;
+}
+
+inline void QRect::moveBottom(int pos)
+{
+ y1 += (pos - y2);
+ y2 = pos;
+}
+
+inline void QRect::moveTopLeft(const QPoint &p)
+{
+ moveLeft(p.x());
+ moveTop(p.y());
+}
+
+inline void QRect::moveBottomRight(const QPoint &p)
+{
+ moveRight(p.x());
+ moveBottom(p.y());
+}
+
+inline void QRect::moveTopRight(const QPoint &p)
+{
+ moveRight(p.x());
+ moveTop(p.y());
+}
+
+inline void QRect::moveBottomLeft(const QPoint &p)
+{
+ moveLeft(p.x());
+ moveBottom(p.y());
+}
+
+inline void QRect::getRect(int *ax, int *ay, int *aw, int *ah) const
+{
+ *ax = x1;
+ *ay = y1;
+ *aw = x2 - x1 + 1;
+ *ah = y2 - y1 + 1;
+}
+
+inline void QRect::setRect(int ax, int ay, int aw, int ah)
+{
+ x1 = ax;
+ y1 = ay;
+ x2 = (ax + aw - 1);
+ y2 = (ay + ah - 1);
+}
+
+inline void QRect::getCoords(int *xp1, int *yp1, int *xp2, int *yp2) const
+{
+ *xp1 = x1;
+ *yp1 = y1;
+ *xp2 = x2;
+ *yp2 = y2;
+}
+
+inline void QRect::setCoords(int xp1, int yp1, int xp2, int yp2)
+{
+ x1 = xp1;
+ y1 = yp1;
+ x2 = xp2;
+ y2 = yp2;
+}
+
+#ifdef QT3_SUPPORT
+inline void QRect::addCoords(int dx1, int dy1, int dx2, int dy2)
+{
+ adjust(dx1, dy1, dx2, dy2);
+}
+#endif
+
+inline QRect QRect::adjusted(int xp1, int yp1, int xp2, int yp2) const
+{ return QRect(QPoint(x1 + xp1, y1 + yp1), QPoint(x2 + xp2, y2 + yp2)); }
+
+inline void QRect::adjust(int dx1, int dy1, int dx2, int dy2)
+{
+ x1 += dx1;
+ y1 += dy1;
+ x2 += dx2;
+ y2 += dy2;
+}
+
+inline void QRect::setWidth(int w)
+{ x2 = (x1 + w - 1); }
+
+inline void QRect::setHeight(int h)
+{ y2 = (y1 + h - 1); }
+
+inline void QRect::setSize(const QSize &s)
+{
+ x2 = (s.width() + x1 - 1);
+ y2 = (s.height() + y1 - 1);
+}
+
+inline bool QRect::contains(int ax, int ay, bool aproper) const
+{
+ return contains(QPoint(ax, ay), aproper);
+}
+
+inline bool QRect::contains(int ax, int ay) const
+{
+ return contains(QPoint(ax, ay), false);
+}
+
+inline QRect& QRect::operator|=(const QRect &r)
+{
+ *this = *this | r;
+ return *this;
+}
+
+inline QRect& QRect::operator&=(const QRect &r)
+{
+ *this = *this & r;
+ return *this;
+}
+
+inline QRect QRect::intersect(const QRect &r) const
+{
+ return *this & r;
+}
+
+inline QRect QRect::intersected(const QRect &other) const
+{
+ return intersect(other);
+}
+
+inline QRect QRect::unite(const QRect &r) const
+{
+ return *this | r;
+}
+
+inline QRect QRect::united(const QRect &r) const
+{
+ return unite(r);
+}
+
+inline bool operator==(const QRect &r1, const QRect &r2)
+{
+ return r1.x1==r2.x1 && r1.x2==r2.x2 && r1.y1==r2.y1 && r1.y2==r2.y2;
+}
+
+inline bool operator!=(const QRect &r1, const QRect &r2)
+{
+ return r1.x1!=r2.x1 || r1.x2!=r2.x2 || r1.y1!=r2.y1 || r1.y2!=r2.y2;
+}
+
+#ifndef QT_NO_DEBUG_STREAM
+Q_CORE_EXPORT QDebug operator<<(QDebug, const QRect &);
+#endif
+
+
+class Q_CORE_EXPORT QRectF
+{
+public:
+ QRectF() { xp = yp = 0.; w = h = 0.; }
+ QRectF(const QPointF &topleft, const QSizeF &size);
+ QRectF(const QPointF &topleft, const QPointF &bottomRight);
+ QRectF(qreal left, qreal top, qreal width, qreal height);
+ QRectF(const QRect &rect);
+
+ bool isNull() const;
+ bool isEmpty() const;
+ bool isValid() const;
+ QRectF normalized() const;
+
+ inline qreal left() const { return xp; }
+ inline qreal top() const { return yp; }
+ inline qreal right() const { return xp + w; }
+ inline qreal bottom() const { return yp + h; }
+
+ inline qreal x() const;
+ inline qreal y() const;
+ inline void setLeft(qreal pos);
+ inline void setTop(qreal pos);
+ inline void setRight(qreal pos);
+ inline void setBottom(qreal pos);
+ inline void setX(qreal pos) { setLeft(pos); }
+ inline void setY(qreal pos) { setTop(pos); }
+
+ inline QPointF topLeft() const { return QPointF(xp, yp); }
+ inline QPointF bottomRight() const { return QPointF(xp+w, yp+h); }
+ inline QPointF topRight() const { return QPointF(xp+w, yp); }
+ inline QPointF bottomLeft() const { return QPointF(xp, yp+h); }
+ inline QPointF center() const;
+
+ void setTopLeft(const QPointF &p);
+ void setBottomRight(const QPointF &p);
+ void setTopRight(const QPointF &p);
+ void setBottomLeft(const QPointF &p);
+
+ void moveLeft(qreal pos);
+ void moveTop(qreal pos);
+ void moveRight(qreal pos);
+ void moveBottom(qreal pos);
+ void moveTopLeft(const QPointF &p);
+ void moveBottomRight(const QPointF &p);
+ void moveTopRight(const QPointF &p);
+ void moveBottomLeft(const QPointF &p);
+ void moveCenter(const QPointF &p);
+
+ void translate(qreal dx, qreal dy);
+ void translate(const QPointF &p);
+
+ QRectF translated(qreal dx, qreal dy) const;
+ QRectF translated(const QPointF &p) const;
+
+ void moveTo(qreal x, qreal t);
+ void moveTo(const QPointF &p);
+
+ void setRect(qreal x, qreal y, qreal w, qreal h);
+ void getRect(qreal *x, qreal *y, qreal *w, qreal *h) const;
+
+ void setCoords(qreal x1, qreal y1, qreal x2, qreal y2);
+ void getCoords(qreal *x1, qreal *y1, qreal *x2, qreal *y2) const;
+
+ inline void adjust(qreal x1, qreal y1, qreal x2, qreal y2);
+ inline QRectF adjusted(qreal x1, qreal y1, qreal x2, qreal y2) const;
+
+ QSizeF size() const;
+ qreal width() const;
+ qreal height() const;
+ void setWidth(qreal w);
+ void setHeight(qreal h);
+ void setSize(const QSizeF &s);
+
+ QRectF operator|(const QRectF &r) const;
+ QRectF operator&(const QRectF &r) const;
+ QRectF& operator|=(const QRectF &r);
+ QRectF& operator&=(const QRectF &r);
+
+ bool contains(const QPointF &p) const;
+ bool contains(qreal x, qreal y) const;
+ bool contains(const QRectF &r) const;
+ QRectF unite(const QRectF &r) const; // ### Qt 5: make QT4_SUPPORT
+ QRectF united(const QRectF &other) const;
+ QRectF intersect(const QRectF &r) const; // ### Qt 5: make QT4_SUPPORT
+ QRectF intersected(const QRectF &other) const;
+ bool intersects(const QRectF &r) const;
+
+ friend Q_CORE_EXPORT_INLINE bool operator==(const QRectF &, const QRectF &);
+ friend Q_CORE_EXPORT_INLINE bool operator!=(const QRectF &, const QRectF &);
+
+ QRect toRect() const;
+ QRect toAlignedRect() const;
+
+private:
+ qreal xp;
+ qreal yp;
+ qreal w;
+ qreal h;
+};
+Q_DECLARE_TYPEINFO(QRectF, Q_MOVABLE_TYPE);
+
+Q_CORE_EXPORT_INLINE bool operator==(const QRectF &, const QRectF &);
+Q_CORE_EXPORT_INLINE bool operator!=(const QRectF &, const QRectF &);
+
+
+/*****************************************************************************
+ QRectF stream functions
+ *****************************************************************************/
+#ifndef QT_NO_DATASTREAM
+Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QRectF &);
+Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QRectF &);
+#endif
+
+/*****************************************************************************
+ QRectF inline member functions
+ *****************************************************************************/
+
+inline QRectF::QRectF(qreal aleft, qreal atop, qreal awidth, qreal aheight)
+ : xp(aleft), yp(atop), w(awidth), h(aheight)
+{
+}
+
+inline QRectF::QRectF(const QPointF &atopLeft, const QSizeF &asize)
+{
+ xp = atopLeft.x();
+ yp = atopLeft.y();
+ w = asize.width();
+ h = asize.height();
+}
+
+inline QRectF::QRectF(const QPointF &atopLeft, const QPointF &abottomRight)
+{
+ xp = atopLeft.x();
+ yp = atopLeft.y();
+ w = abottomRight.x() - xp;
+ h = abottomRight.y() - yp;
+}
+
+inline QRectF::QRectF(const QRect &r)
+ : xp(r.x()), yp(r.y()), w(r.width()), h(r.height())
+{
+}
+
+inline bool QRectF::isNull() const
+{ return qIsNull(w) && qIsNull(h); }
+
+inline bool QRectF::isEmpty() const
+{ return w <= 0. || h <= 0.; }
+
+inline bool QRectF::isValid() const
+{ return w > 0. && h > 0.; }
+
+inline qreal QRectF::x() const
+{ return xp; }
+
+inline qreal QRectF::y() const
+{ return yp; }
+
+inline void QRectF::setLeft(qreal pos) { qreal diff = pos - xp; xp += diff; w -= diff; }
+
+inline void QRectF::setRight(qreal pos) { w = pos - xp; }
+
+inline void QRectF::setTop(qreal pos) { qreal diff = pos - yp; yp += diff; h -= diff; }
+
+inline void QRectF::setBottom(qreal pos) { h = pos - yp; }
+
+inline void QRectF::setTopLeft(const QPointF &p) { setLeft(p.x()); setTop(p.y()); }
+
+inline void QRectF::setTopRight(const QPointF &p) { setRight(p.x()); setTop(p.y()); }
+
+inline void QRectF::setBottomLeft(const QPointF &p) { setLeft(p.x()); setBottom(p.y()); }
+
+inline void QRectF::setBottomRight(const QPointF &p) { setRight(p.x()); setBottom(p.y()); }
+
+inline QPointF QRectF::center() const
+{ return QPointF(xp + w/2, yp + h/2); }
+
+inline void QRectF::moveLeft(qreal pos) { xp = pos; }
+
+inline void QRectF::moveTop(qreal pos) { yp = pos; }
+
+inline void QRectF::moveRight(qreal pos) { xp = pos - w; }
+
+inline void QRectF::moveBottom(qreal pos) { yp = pos - h; }
+
+inline void QRectF::moveTopLeft(const QPointF &p) { moveLeft(p.x()); moveTop(p.y()); }
+
+inline void QRectF::moveTopRight(const QPointF &p) { moveRight(p.x()); moveTop(p.y()); }
+
+inline void QRectF::moveBottomLeft(const QPointF &p) { moveLeft(p.x()); moveBottom(p.y()); }
+
+inline void QRectF::moveBottomRight(const QPointF &p) { moveRight(p.x()); moveBottom(p.y()); }
+
+inline void QRectF::moveCenter(const QPointF &p) { xp = p.x() - w/2; yp = p.y() - h/2; }
+
+inline qreal QRectF::width() const
+{ return w; }
+
+inline qreal QRectF::height() const
+{ return h; }
+
+inline QSizeF QRectF::size() const
+{ return QSizeF(w, h); }
+
+inline void QRectF::translate(qreal dx, qreal dy)
+{
+ xp += dx;
+ yp += dy;
+}
+
+inline void QRectF::translate(const QPointF &p)
+{
+ xp += p.x();
+ yp += p.y();
+}
+
+inline void QRectF::moveTo(qreal ax, qreal ay)
+{
+ xp = ax;
+ yp = ay;
+}
+
+inline void QRectF::moveTo(const QPointF &p)
+{
+ xp = p.x();
+ yp = p.y();
+}
+
+inline QRectF QRectF::translated(qreal dx, qreal dy) const
+{ return QRectF(xp + dx, yp + dy, w, h); }
+
+inline QRectF QRectF::translated(const QPointF &p) const
+{ return QRectF(xp + p.x(), yp + p.y(), w, h); }
+
+inline void QRectF::getRect(qreal *ax, qreal *ay, qreal *aaw, qreal *aah) const
+{
+ *ax = this->xp;
+ *ay = this->yp;
+ *aaw = this->w;
+ *aah = this->h;
+}
+
+inline void QRectF::setRect(qreal ax, qreal ay, qreal aaw, qreal aah)
+{
+ this->xp = ax;
+ this->yp = ay;
+ this->w = aaw;
+ this->h = aah;
+}
+
+inline void QRectF::getCoords(qreal *xp1, qreal *yp1, qreal *xp2, qreal *yp2) const
+{
+ *xp1 = xp;
+ *yp1 = yp;
+ *xp2 = xp + w;
+ *yp2 = yp + h;
+}
+
+inline void QRectF::setCoords(qreal xp1, qreal yp1, qreal xp2, qreal yp2)
+{
+ xp = xp1;
+ yp = yp1;
+ w = xp2 - xp1;
+ h = yp2 - yp1;
+}
+
+inline void QRectF::adjust(qreal xp1, qreal yp1, qreal xp2, qreal yp2)
+{ xp += xp1; yp += yp1; w += xp2 - xp1; h += yp2 - yp1; }
+
+inline QRectF QRectF::adjusted(qreal xp1, qreal yp1, qreal xp2, qreal yp2) const
+{ return QRectF(xp + xp1, yp + yp1, w + xp2 - xp1, h + yp2 - yp1); }
+
+inline void QRectF::setWidth(qreal aw)
+{ this->w = aw; }
+
+inline void QRectF::setHeight(qreal ah)
+{ this->h = ah; }
+
+inline void QRectF::setSize(const QSizeF &s)
+{
+ w = s.width();
+ h = s.height();
+}
+
+inline bool QRectF::contains(qreal ax, qreal ay) const
+{
+ return contains(QPointF(ax, ay));
+}
+
+inline QRectF& QRectF::operator|=(const QRectF &r)
+{
+ *this = *this | r;
+ return *this;
+}
+
+inline QRectF& QRectF::operator&=(const QRectF &r)
+{
+ *this = *this & r;
+ return *this;
+}
+
+inline QRectF QRectF::intersect(const QRectF &r) const
+{
+ return *this & r;
+}
+
+inline QRectF QRectF::intersected(const QRectF &r) const
+{
+ return intersect(r);
+}
+
+inline QRectF QRectF::unite(const QRectF &r) const
+{
+ return *this | r;
+}
+
+inline QRectF QRectF::united(const QRectF &r) const
+{
+ return unite(r);
+}
+
+inline bool operator==(const QRectF &r1, const QRectF &r2)
+{
+ return qFuzzyCompare(r1.xp, r2.xp) && qFuzzyCompare(r1.yp, r2.yp)
+ && qFuzzyCompare(r1.w, r2.w) && qFuzzyCompare(r1.h, r2.h);
+}
+
+inline bool operator!=(const QRectF &r1, const QRectF &r2)
+{
+ return !qFuzzyCompare(r1.xp, r2.xp) || !qFuzzyCompare(r1.yp, r2.yp)
+ || !qFuzzyCompare(r1.w, r2.w) || !qFuzzyCompare(r1.h, r2.h);
+}
+
+inline QRect QRectF::toRect() const
+{
+ return QRect(qRound(xp), qRound(yp), qRound(w), qRound(h));
+}
+
+#ifndef QT_NO_DEBUG_STREAM
+Q_CORE_EXPORT QDebug operator<<(QDebug, const QRectF &);
+#endif
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QRECT_H
diff --git a/src/corelib/tools/qregexp.cpp b/src/corelib/tools/qregexp.cpp
new file mode 100644
index 0000000000..e1c39219ea
--- /dev/null
+++ b/src/corelib/tools/qregexp.cpp
@@ -0,0 +1,4070 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qregexp.h"
+
+#include "qalgorithms.h"
+#include "qbitarray.h"
+#include "qcache.h"
+#include "qdatastream.h"
+#include "qlist.h"
+#include "qmap.h"
+#include "qmutex.h"
+#include "qstring.h"
+#include "qstringlist.h"
+#include "qstringmatcher.h"
+#include "qvector.h"
+
+#include <limits.h>
+
+QT_BEGIN_NAMESPACE
+
+int qFindString(const QChar *haystack, int haystackLen, int from,
+ const QChar *needle, int needleLen, Qt::CaseSensitivity cs);
+
+// error strings for the regexp parser
+#define RXERR_OK QT_TRANSLATE_NOOP("QRegExp", "no error occurred")
+#define RXERR_DISABLED QT_TRANSLATE_NOOP("QRegExp", "disabled feature used")
+#define RXERR_CHARCLASS QT_TRANSLATE_NOOP("QRegExp", "bad char class syntax")
+#define RXERR_LOOKAHEAD QT_TRANSLATE_NOOP("QRegExp", "bad lookahead syntax")
+#define RXERR_REPETITION QT_TRANSLATE_NOOP("QRegExp", "bad repetition syntax")
+#define RXERR_OCTAL QT_TRANSLATE_NOOP("QRegExp", "invalid octal value")
+#define RXERR_LEFTDELIM QT_TRANSLATE_NOOP("QRegExp", "missing left delim")
+#define RXERR_END QT_TRANSLATE_NOOP("QRegExp", "unexpected end")
+#define RXERR_LIMIT QT_TRANSLATE_NOOP("QRegExp", "met internal limit")
+
+/*
+ WARNING! Be sure to read qregexp.tex before modifying this file.
+*/
+
+/*!
+ \class QRegExp
+ \reentrant
+ \brief The QRegExp class provides pattern matching using regular expressions.
+
+ \ingroup tools
+ \ingroup misc
+ \ingroup shared
+ \mainclass
+ \keyword regular expression
+
+ A regular expression, or "regexp", is a pattern for matching
+ substrings in a text. This is useful in many contexts, e.g.,
+
+ \table
+ \row \i Validation
+ \i A regexp can test whether a substring meets some criteria,
+ e.g. is an integer or contains no whitespace.
+ \row \i Searching
+ \i A regexp provides more powerful pattern matching than
+ simple substring matching, e.g., match one of the words
+ \e{mail}, \e{letter} or \e{correspondence}, but none of the
+ words \e{email}, \e{mailman}, \e{mailer}, \e{letterbox}, etc.
+ \row \i Search and Replace
+ \i A regexp can replace all occurrences of a substring with a
+ different substring, e.g., replace all occurrences of \e{&}
+ with \e{\&amp;} except where the \e{&} is already followed by
+ an \e{amp;}.
+ \row \i String Splitting
+ \i A regexp can be used to identify where a string should be
+ split apart, e.g. splitting tab-delimited strings.
+ \endtable
+
+ A brief introduction to regexps is presented, a description of
+ Qt's regexp language, some examples, and the function
+ documentation itself. QRegExp is modeled on Perl's regexp
+ language. It fully supports Unicode. QRegExp can also be used in a
+ simpler, \e{wildcard mode} that is similar to the functionality
+ found in command shells. The syntax rules used by QRegExp can be
+ changed with setPatternSyntax(). In particular, the pattern syntax
+ can be set to QRegExp::FixedString, which means the pattern to be
+ matched is interpreted as a plain string, i.e., special characters
+ (e.g., backslash) are not escaped.
+
+ A good text on regexps is \e {Mastering Regular Expressions}
+ (Third Edition) by Jeffrey E. F. Friedl, ISBN 0-596-52812-4.
+
+ \tableofcontents
+
+ \section1 Introduction
+
+ Regexps are built up from expressions, quantifiers, and
+ assertions. The simplest expression is a character, e.g. \bold{x}
+ or \bold{5}. An expression can also be a set of characters
+ enclosed in square brackets. \bold{[ABCD]} will match an \bold{A}
+ or a \bold{B} or a \bold{C} or a \bold{D}. We can write this same
+ expression as \bold{[A-D]}, and an experession to match any
+ captital letter in the English alphabet is written as
+ \bold{[A-Z]}.
+
+ A quantifier specifies the number of occurrences of an expression
+ that must be matched. \bold{x{1,1}} means match one and only one
+ \bold{x}. \bold{x{1,5}} means match a sequence of \bold{x}
+ characters that contains at least one \bold{x} but no more than
+ five.
+
+ Note that in general regexps cannot be used to check for balanced
+ brackets or tags. For example, a regexp can be written to match an
+ opening html \c{<b>} and its closing \c{</b>}, if the \c{<b>} tags
+ are not nested, but if the \c{<b>} tags are nested, that same
+ regexp will match an opening \c{<b>} tag with the wrong closing
+ \c{</b>}. For the fragment \c{<b>bold <b>bolder</b></b>}, the
+ first \c{<b>} would be matched with the first \c{</b>}, which is
+ not correct. However, it is possible to write a regexp that will
+ match nested brackets or tags correctly, but only if the number of
+ nesting levels is fixed and known. If the number of nesting levels
+ is not fixed and known, it is impossible to write a regexp that
+ will not fail.
+
+ Suppose we want a regexp to match integers in the range 0 to 99.
+ At least one digit is required, so we start with the expression
+ \bold{[0-9]{1,1}}, which matches a single digit exactly once. This
+ regexp matches integers in the range 0 to 9. To match integers up
+ to 99, increase the maximum number of occurrences to 2, so the
+ regexp becomes \bold{[0-9]{1,2}}. This regexp satisfies the
+ original requirement to match integers from 0 to 99, but it will
+ also match integers that occur in the middle of strings. If we
+ want the matched integer to be the whole string, we must use the
+ anchor assertions, \bold{^} (caret) and \bold{$} (dollar). When
+ \bold{^} is the first character in a regexp, it means the regexp
+ must match from the beginning of the string. When \bold{$} is the
+ last character of the regexp, it means the regexp must match to
+ the end of the string. The regexp becomes \bold{^[0-9]{1,2}$}.
+ Note that assertions, e.g. \bold{^} and \bold{$}, do not match
+ characters but locations in the string.
+
+ If you have seen regexps described elsewhere, they may have looked
+ different from the ones shown here. This is because some sets of
+ characters and some quantifiers are so common that they have been
+ given special symbols to represent them. \bold{[0-9]} can be
+ replaced with the symbol \bold{\\d}. The quantifier to match
+ exactly one occurrence, \bold{{1,1}}, can be replaced with the
+ expression itself, i.e. \bold{x{1,1}} is the same as \bold{x}. So
+ our 0 to 99 matcher could be written as \bold{^\\d{1,2}$}. It can
+ also be written \bold{^\\d\\d{0,1}$}, i.e. \e{From the start of
+ the string, match a digit, followed immediately by 0 or 1 digits}.
+ In practice, it would be written as \bold{^\\d\\d?$}. The \bold{?}
+ is shorthand for the quantifier \bold{{0,1}}, i.e. 0 or 1
+ occurrences. \bold{?} makes an expression optional. The regexp
+ \bold{^\\d\\d?$} means \e{From the beginning of the string, match
+ one digit, followed immediately by 0 or 1 more digit, followed
+ immediately by end of string}.
+
+ To write a regexp that matches one of the words 'mail' \e or
+ 'letter' \e or 'correspondence' but does not match words that
+ contain these words, e.g., 'email', 'mailman', 'mailer', and
+ 'letterbox', start with a regexp that matches 'mail'. Expressed
+ fully, the regexp is \bold{m{1,1}a{1,1}i{1,1}l{1,1}}, but because
+ a character expression is automatically quantified by
+ \bold{{1,1}}, we can simplify the regexp to \bold{mail}, i.e., an
+ 'm' followed by an 'a' followed by an 'i' followed by an 'l'. Now
+ we can use the vertical bar \bold{|}, which means \bold{or}, to
+ include the other two words, so our regexp for matching any of the
+ three words becomes \bold{mail|letter|correspondence}. Match
+ 'mail' \bold{or} 'letter' \bold{or} 'correspondence'. While this
+ regexp will match one of the three words we want to match, it will
+ also match words we don't want to match, e.g., 'email'. To
+ prevent the regexp from matching unwanted words, we must tell it
+ to begin and end the match at word boundaries. First we enclose
+ our regexp in parentheses, \bold{(mail|letter|correspondence)}.
+ Parentheses group expressions together, and they identify a part
+ of the regexp that we wish to \l{capturing text}{capture}.
+ Enclosing the expression in parentheses allows us to use it as a
+ component in more complex regexps. It also allows us to examine
+ which of the three words was actually matched. To force the match
+ to begin and end on word boundaries, we enclose the regexp in
+ \bold{\\b} \e{word boundary} assertions:
+ \bold{\\b(mail|letter|correspondence)\\b}. Now the regexp means:
+ \e{Match a word boundary, followed by the regexp in parentheses,
+ followed by a word boundary}. The \bold{\\b} assertion matches a
+ \e position in the regexp, not a \e character. A word boundary is
+ any non-word character, e.g., a space, newline, or the beginning
+ or ending of a string.
+
+ If we want to replace ampersand characters with the HTML entity
+ \bold{\&amp;}, the regexp to match is simply \bold{\&}. But this
+ regexp will also match ampersands that have already been converted
+ to HTML entities. We want to replace only ampersands that are not
+ already followed by \bold{amp;}. For this, we need the negative
+ lookahead assertion, \bold{(?!}__\bold{)}. The regexp can then be
+ written as \bold{\&(?!amp;)}, i.e. \e{Match an ampersand that is}
+ \bold{not} \e{followed by} \bold{amp;}.
+
+ If we want to count all the occurrences of 'Eric' and 'Eirik' in a
+ string, two valid solutions are \bold{\\b(Eric|Eirik)\\b} and
+ \bold{\\bEi?ri[ck]\\b}. The word boundary assertion '\\b' is
+ required to avoid matching words that contain either name,
+ e.g. 'Ericsson'. Note that the second regexp matches more
+ spellings than we want: 'Eric', 'Erik', 'Eiric' and 'Eirik'.
+
+ Some of the examples discussed above are implemented in the
+ \link #code-examples code examples \endlink section.
+
+ \target characters-and-abbreviations-for-sets-of-characters
+ \section1 Characters and Abbreviations for Sets of Characters
+
+ \table
+ \header \i Element \i Meaning
+ \row \i \bold{c}
+ \i A character represents itself unless it has a special
+ regexp meaning. e.g. \bold{c} matches the character \e c.
+ \row \i \bold{\\c}
+ \i A character that follows a backslash matches the character
+ itself, except as specified below. e.g., To match a literal
+ caret at the beginning of a string, write \bold{\\^}.
+ \row \i \bold{\\a}
+ \i Matches the ASCII bell (BEL, 0x07).
+ \row \i \bold{\\f}
+ \i Matches the ASCII form feed (FF, 0x0C).
+ \row \i \bold{\\n}
+ \i Matches the ASCII line feed (LF, 0x0A, Unix newline).
+ \row \i \bold{\\r}
+ \i Matches the ASCII carriage return (CR, 0x0D).
+ \row \i \bold{\\t}
+ \i Matches the ASCII horizontal tab (HT, 0x09).
+ \row \i \bold{\\v}
+ \i Matches the ASCII vertical tab (VT, 0x0B).
+ \row \i \bold{\\x\e{hhhh}}
+ \i Matches the Unicode character corresponding to the
+ hexadecimal number \e{hhhh} (between 0x0000 and 0xFFFF).
+ \row \i \bold{\\0\e{ooo}} (i.e., \\zero \e{ooo})
+ \i matches the ASCII/Latin1 character for the octal number
+ \e{ooo} (between 0 and 0377).
+ \row \i \bold{. (dot)}
+ \i Matches any character (including newline).
+ \row \i \bold{\\d}
+ \i Matches a digit (QChar::isDigit()).
+ \row \i \bold{\\D}
+ \i Matches a non-digit.
+ \row \i \bold{\\s}
+ \i Matches a whitespace character (QChar::isSpace()).
+ \row \i \bold{\\S}
+ \i Matches a non-whitespace character.
+ \row \i \bold{\\w}
+ \i Matches a word character (QChar::isLetterOrNumber(), QChar::isMark(), or '_').
+ \row \i \bold{\\W}
+ \i Matches a non-word character.
+ \row \i \bold{\\\e{n}}
+ \i The \e{n}-th \l backreference, e.g. \\1, \\2, etc.
+ \endtable
+
+ \bold{Note:} The C++ compiler transforms backslashes in strings.
+ To include a \bold{\\} in a regexp, enter it twice, i.e. \c{\\}.
+ To match the backslash character itself, enter it four times, i.e.
+ \c{\\\\}.
+
+ \target sets-of-characters
+ \section1 Sets of Characters
+
+ Square brackets mean match any character contained in the square
+ brackets. The character set abbreviations described above can
+ appear in a character set in square brackets. Except for the
+ character set abbreviations and the following two exceptions,
+ characters do not have special meanings in square brackets.
+
+ \table
+ \row \i \bold{^}
+
+ \i The caret negates the character set if it occurs as the
+ first character (i.e. immediately after the opening square
+ bracket). \bold{[abc]} matches 'a' or 'b' or 'c', but
+ \bold{[^abc]} matches anything \e but 'a' or 'b' or 'c'.
+
+ \row \i \bold{-}
+
+ \i The dash indicates a range of characters. \bold{[W-Z]}
+ matches 'W' or 'X' or 'Y' or 'Z'.
+
+ \endtable
+
+ Using the predefined character set abbreviations is more portable
+ than using character ranges across platforms and languages. For
+ example, \bold{[0-9]} matches a digit in Western alphabets but
+ \bold{\\d} matches a digit in \e any alphabet.
+
+ Note: In other regexp documentation, sets of characters are often
+ called "character classes".
+
+ \target quantifiers
+ \section1 Quantifiers
+
+ By default, an expression is automatically quantified by
+ \bold{{1,1}}, i.e. it should occur exactly once. In the following
+ list, \bold{\e {E}} stands for expression. An expression is a
+ character, or an abbreviation for a set of characters, or a set of
+ characters in square brackets, or an expression in parentheses.
+
+ \table
+ \row \i \bold{\e {E}?}
+
+ \i Matches zero or one occurrences of \e E. This quantifier
+ means \e{The previous expression is optional}, because it
+ will match whether or not the expression is found. \bold{\e
+ {E}?} is the same as \bold{\e {E}{0,1}}. e.g., \bold{dents?}
+ matches 'dent' or 'dents'.
+
+ \row \i \bold{\e {E}+}
+
+ \i Matches one or more occurrences of \e E. \bold{\e {E}+} is
+ the same as \bold{\e {E}{1,}}. e.g., \bold{0+} matches '0',
+ '00', '000', etc.
+
+ \row \i \bold{\e {E}*}
+
+ \i Matches zero or more occurrences of \e E. It is the same
+ as \bold{\e {E}{0,}}. The \bold{*} quantifier is often used
+ in error where \bold{+} should be used. For example, if
+ \bold{\\s*$} is used in an expression to match strings that
+ end in whitespace, it will match every string because
+ \bold{\\s*$} means \e{Match zero or more whitespaces followed
+ by end of string}. The correct regexp to match strings that
+ have at least one trailing whitespace character is
+ \bold{\\s+$}.
+
+ \row \i \bold{\e {E}{n}}
+
+ \i Matches exactly \e n occurrences of \e E. \bold{\e {E}{n}}
+ is the same as repeating \e E \e n times. For example,
+ \bold{x{5}} is the same as \bold{xxxxx}. It is also the same
+ as \bold{\e {E}{n,n}}, e.g. \bold{x{5,5}}.
+
+ \row \i \bold{\e {E}{n,}}
+ \i Matches at least \e n occurrences of \e E.
+
+ \row \i \bold{\e {E}{,m}}
+ \i Matches at most \e m occurrences of \e E. \bold{\e {E}{,m}}
+ is the same as \bold{\e {E}{0,m}}.
+
+ \row \i \bold{\e {E}{n,m}}
+ \i Matches at least \e n and at most \e m occurrences of \e E.
+ \endtable
+
+ To apply a quantifier to more than just the preceding character,
+ use parentheses to group characters together in an expression. For
+ example, \bold{tag+} matches a 't' followed by an 'a' followed by
+ at least one 'g', whereas \bold{(tag)+} matches at least one
+ occurrence of 'tag'.
+
+ Note: Quantifiers are normally "greedy". They always match as much
+ text as they can. For example, \bold{0+} matches the first zero it
+ finds and all the consecutive zeros after the first zero. Applied
+ to '20005', it matches'2\underline{000}5'. Quantifiers can be made
+ non-greedy, see setMinimal().
+
+ \target capturing parentheses
+ \target backreferences
+ \section1 Capturing Text
+
+ Parentheses allow us to group elements together so that we can
+ quantify and capture them. For example if we have the expression
+ \bold{mail|letter|correspondence} that matches a string we know
+ that \e one of the words matched but not which one. Using
+ parentheses allows us to "capture" whatever is matched within
+ their bounds, so if we used \bold{(mail|letter|correspondence)}
+ and matched this regexp against the string "I sent you some email"
+ we can use the cap() or capturedTexts() functions to extract the
+ matched characters, in this case 'mail'.
+
+ We can use captured text within the regexp itself. To refer to the
+ captured text we use \e backreferences which are indexed from 1,
+ the same as for cap(). For example we could search for duplicate
+ words in a string using \bold{\\b(\\w+)\\W+\\1\\b} which means match a
+ word boundary followed by one or more word characters followed by
+ one or more non-word characters followed by the same text as the
+ first parenthesized expression followed by a word boundary.
+
+ If we want to use parentheses purely for grouping and not for
+ capturing we can use the non-capturing syntax, e.g.
+ \bold{(?:green|blue)}. Non-capturing parentheses begin '(?:' and
+ end ')'. In this example we match either 'green' or 'blue' but we
+ do not capture the match so we only know whether or not we matched
+ but not which color we actually found. Using non-capturing
+ parentheses is more efficient than using capturing parentheses
+ since the regexp engine has to do less book-keeping.
+
+ Both capturing and non-capturing parentheses may be nested.
+
+ \target greedy quantifiers
+
+ For historical reasons, quantifiers (e.g. \bold{*}) that apply to
+ capturing parentheses are more "greedy" than other quantifiers.
+ For example, \bold{a*(a)*} will match "aaa" with cap(1) == "aaa".
+ This behavior is different from what other regexp engines do
+ (notably, Perl). To obtain a more intuitive capturing behavior,
+ specify QRegExp::RegExp2 to the QRegExp constructor or call
+ setPatternSyntax(QRegExp::RegExp2).
+
+ \target cap_in_a_loop
+
+ When the number of matches cannot be determined in advance, a
+ common idiom is to use cap() in a loop. For example:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qregexp.cpp 0
+
+ \target assertions
+ \section1 Assertions
+
+ Assertions make some statement about the text at the point where
+ they occur in the regexp but they do not match any characters. In
+ the following list \bold{\e {E}} stands for any expression.
+
+ \table
+ \row \i \bold{^}
+ \i The caret signifies the beginning of the string. If you
+ wish to match a literal \c{^} you must escape it by
+ writing \c{\\^}. For example, \bold{^#include} will only
+ match strings which \e begin with the characters '#include'.
+ (When the caret is the first character of a character set it
+ has a special meaning, see \link #sets-of-characters Sets of
+ Characters \endlink.)
+
+ \row \i \bold{$}
+ \i The dollar signifies the end of the string. For example
+ \bold{\\d\\s*$} will match strings which end with a digit
+ optionally followed by whitespace. If you wish to match a
+ literal \c{$} you must escape it by writing
+ \c{\\$}.
+
+ \row \i \bold{\\b}
+ \i A word boundary. For example the regexp
+ \bold{\\bOK\\b} means match immediately after a word
+ boundary (e.g. start of string or whitespace) the letter 'O'
+ then the letter 'K' immediately before another word boundary
+ (e.g. end of string or whitespace). But note that the
+ assertion does not actually match any whitespace so if we
+ write \bold{(\\bOK\\b)} and we have a match it will only
+ contain 'OK' even if the string is "It's \underline{OK} now".
+
+ \row \i \bold{\\B}
+ \i A non-word boundary. This assertion is true wherever
+ \bold{\\b} is false. For example if we searched for
+ \bold{\\Bon\\B} in "Left on" the match would fail (space
+ and end of string aren't non-word boundaries), but it would
+ match in "t\underline{on}ne".
+
+ \row \i \bold{(?=\e E)}
+ \i Positive lookahead. This assertion is true if the
+ expression matches at this point in the regexp. For example,
+ \bold{const(?=\\s+char)} matches 'const' whenever it is
+ followed by 'char', as in 'static \underline{const} char *'.
+ (Compare with \bold{const\\s+char}, which matches 'static
+ \underline{const char} *'.)
+
+ \row \i \bold{(?!\e E)}
+ \i Negative lookahead. This assertion is true if the
+ expression does not match at this point in the regexp. For
+ example, \bold{const(?!\\s+char)} matches 'const' \e except
+ when it is followed by 'char'.
+ \endtable
+
+ \keyword QRegExp wildcard matching
+ \section1 Wildcard Matching
+
+ Most command shells such as \e bash or \e cmd.exe support "file
+ globbing", the ability to identify a group of files by using
+ wildcards. The setPatternSyntax() function is used to switch
+ between regexp and wildcard mode. Wildcard matching is much
+ simpler than full regexps and has only four features:
+
+ \table
+ \row \i \bold{c}
+ \i Any character represents itself apart from those mentioned
+ below. Thus \bold{c} matches the character \e c.
+ \row \i \bold{?}
+ \i Matches any single character. It is the same as
+ \bold{.} in full regexps.
+ \row \i \bold{*}
+ \i Matches zero or more of any characters. It is the
+ same as \bold{.*} in full regexps.
+ \row \i \bold{[...]}
+ \i Sets of characters can be represented in square brackets,
+ similar to full regexps. Within the character class, like
+ outside, backslash has no special meaning.
+ \endtable
+
+ For example if we are in wildcard mode and have strings which
+ contain filenames we could identify HTML files with \bold{*.html}.
+ This will match zero or more characters followed by a dot followed
+ by 'h', 't', 'm' and 'l'.
+
+ To test a string against a wildcard expression, use exactMatch().
+ For example:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qregexp.cpp 1
+
+ \target perl-users
+ \section1 Notes for Perl Users
+
+ Most of the character class abbreviations supported by Perl are
+ supported by QRegExp, see \link
+ #characters-and-abbreviations-for-sets-of-characters characters
+ and abbreviations for sets of characters \endlink.
+
+ In QRegExp, apart from within character classes, \c{^} always
+ signifies the start of the string, so carets must always be
+ escaped unless used for that purpose. In Perl the meaning of caret
+ varies automagically depending on where it occurs so escaping it
+ is rarely necessary. The same applies to \c{$} which in
+ QRegExp always signifies the end of the string.
+
+ QRegExp's quantifiers are the same as Perl's greedy quantifiers
+ (but see the \l{greedy quantifiers}{note above}). Non-greedy
+ matching cannot be applied to individual quantifiers, but can be
+ applied to all the quantifiers in the pattern. For example, to
+ match the Perl regexp \bold{ro+?m} requires:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qregexp.cpp 2
+
+ The equivalent of Perl's \c{/i} option is
+ setCaseSensitivity(Qt::CaseInsensitive).
+
+ Perl's \c{/g} option can be emulated using a \l{#cap_in_a_loop}{loop}.
+
+ In QRegExp \bold{.} matches any character, therefore all QRegExp
+ regexps have the equivalent of Perl's \c{/s} option. QRegExp
+ does not have an equivalent to Perl's \c{/m} option, but this
+ can be emulated in various ways for example by splitting the input
+ into lines or by looping with a regexp that searches for newlines.
+
+ Because QRegExp is string oriented, there are no \\A, \\Z, or \\z
+ assertions. The \\G assertion is not supported but can be emulated
+ in a loop.
+
+ Perl's $& is cap(0) or capturedTexts()[0]. There are no QRegExp
+ equivalents for $`, $' or $+. Perl's capturing variables, $1, $2,
+ ... correspond to cap(1) or capturedTexts()[1], cap(2) or
+ capturedTexts()[2], etc.
+
+ To substitute a pattern use QString::replace().
+
+ Perl's extended \c{/x} syntax is not supported, nor are
+ directives, e.g. (?i), or regexp comments, e.g. (?#comment). On
+ the other hand, C++'s rules for literal strings can be used to
+ achieve the same:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qregexp.cpp 3
+
+ Both zero-width positive and zero-width negative lookahead
+ assertions (?=pattern) and (?!pattern) are supported with the same
+ syntax as Perl. Perl's lookbehind assertions, "independent"
+ subexpressions and conditional expressions are not supported.
+
+ Non-capturing parentheses are also supported, with the same
+ (?:pattern) syntax.
+
+ See QString::split() and QStringList::join() for equivalents
+ to Perl's split and join functions.
+
+ Note: because C++ transforms \\'s they must be written \e twice in
+ code, e.g. \bold{\\b} must be written \bold{\\\\b}.
+
+ \target code-examples
+ \section1 Code Examples
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qregexp.cpp 4
+
+ The third string matches '\underline{6}'. This is a simple validation
+ regexp for integers in the range 0 to 99.
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qregexp.cpp 5
+
+ The second string matches '\underline{This_is-OK}'. We've used the
+ character set abbreviation '\\S' (non-whitespace) and the anchors
+ to match strings which contain no whitespace.
+
+ In the following example we match strings containing 'mail' or
+ 'letter' or 'correspondence' but only match whole words i.e. not
+ 'email'
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qregexp.cpp 6
+
+ The second string matches "Please write the \underline{letter}". The
+ word 'letter' is also captured (because of the parentheses). We
+ can see what text we've captured like this:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qregexp.cpp 7
+
+ This will capture the text from the first set of capturing
+ parentheses (counting capturing left parentheses from left to
+ right). The parentheses are counted from 1 since cap(0) is the
+ whole matched regexp (equivalent to '&' in most regexp engines).
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qregexp.cpp 8
+
+ Here we've passed the QRegExp to QString's replace() function to
+ replace the matched text with new text.
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qregexp.cpp 9
+
+ We've used the indexIn() function to repeatedly match the regexp in
+ the string. Note that instead of moving forward by one character
+ at a time \c pos++ we could have written \c {pos +=
+ rx.matchedLength()} to skip over the already matched string. The
+ count will equal 3, matching 'One \underline{Eric} another
+ \underline{Eirik}, and an Ericsson. How many Eiriks, \underline{Eric}?'; it
+ doesn't match 'Ericsson' or 'Eiriks' because they are not bounded
+ by non-word boundaries.
+
+ One common use of regexps is to split lines of delimited data into
+ their component fields.
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qregexp.cpp 10
+
+ In this example our input lines have the format company name, web
+ address and country. Unfortunately the regexp is rather long and
+ not very versatile -- the code will break if we add any more
+ fields. A simpler and better solution is to look for the
+ separator, '\\t' in this case, and take the surrounding text. The
+ QString::split() function can take a separator string or regexp
+ as an argument and split a string accordingly.
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qregexp.cpp 11
+
+ Here field[0] is the company, field[1] the web address and so on.
+
+ To imitate the matching of a shell we can use wildcard mode.
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qregexp.cpp 12
+
+ Wildcard matching can be convenient because of its simplicity, but
+ any wildcard regexp can be defined using full regexps, e.g.
+ \bold{.*\.html$}. Notice that we can't match both \c .html and \c
+ .htm files with a wildcard unless we use \bold{*.htm*} which will
+ also match 'test.html.bak'. A full regexp gives us the precision
+ we need, \bold{.*\\.html?$}.
+
+ QRegExp can match case insensitively using setCaseSensitivity(),
+ and can use non-greedy matching, see setMinimal(). By
+ default QRegExp uses full regexps but this can be changed with
+ setWildcard(). Searching can be forward with indexIn() or backward
+ with lastIndexIn(). Captured text can be accessed using
+ capturedTexts() which returns a string list of all captured
+ strings, or using cap() which returns the captured string for the
+ given index. The pos() function takes a match index and returns
+ the position in the string where the match was made (or -1 if
+ there was no match).
+
+ \sa QString, QStringList, QRegExpValidator, QSortFilterProxyModel,
+ {tools/regexp}{Regular Expression Example}
+*/
+
+const int NumBadChars = 64;
+#define BadChar(ch) ((ch).unicode() % NumBadChars)
+
+const int NoOccurrence = INT_MAX;
+const int EmptyCapture = INT_MAX;
+const int InftyLen = INT_MAX;
+const int InftyRep = 1025;
+const int EOS = -1;
+
+static bool isWord(QChar ch)
+{
+ return ch.isLetterOrNumber() || ch.isMark() || ch == QLatin1Char('_');
+}
+
+/*
+ Merges two vectors of ints and puts the result into the first
+ one.
+*/
+static void mergeInto(QVector<int> *a, const QVector<int> &b)
+{
+ int asize = a->size();
+ int bsize = b.size();
+ if (asize == 0) {
+ *a = b;
+#ifndef QT_NO_REGEXP_OPTIM
+ } else if (bsize == 1 && a->at(asize - 1) < b.at(0)) {
+ a->resize(asize + 1);
+ (*a)[asize] = b.at(0);
+#endif
+ } else if (bsize >= 1) {
+ int csize = asize + bsize;
+ QVector<int> c(csize);
+ int i = 0, j = 0, k = 0;
+ while (i < asize) {
+ if (j < bsize) {
+ if (a->at(i) == b.at(j)) {
+ ++i;
+ --csize;
+ } else if (a->at(i) < b.at(j)) {
+ c[k++] = a->at(i++);
+ } else {
+ c[k++] = b.at(j++);
+ }
+ } else {
+ memcpy(c.data() + k, a->constData() + i, (asize - i) * sizeof(int));
+ break;
+ }
+ }
+ c.resize(csize);
+ if (j < bsize)
+ memcpy(c.data() + k, b.constData() + j, (bsize - j) * sizeof(int));
+ *a = c;
+ }
+}
+
+#ifndef QT_NO_REGEXP_WILDCARD
+/*
+ Translates a wildcard pattern to an equivalent regular expression
+ pattern (e.g., *.cpp to .*\.cpp).
+*/
+static QString wc2rx(const QString &wc_str)
+{
+ int wclen = wc_str.length();
+ QString rx;
+ int i = 0;
+ const QChar *wc = wc_str.unicode();
+ while (i < wclen) {
+ QChar c = wc[i++];
+ switch (c.unicode()) {
+ case '*':
+ rx += QLatin1String(".*");
+ break;
+ case '?':
+ rx += QLatin1Char('.');
+ break;
+ case '$':
+ case '(':
+ case ')':
+ case '+':
+ case '.':
+ case '\\':
+ case '^':
+ case '{':
+ case '|':
+ case '}':
+ rx += QLatin1Char('\\');
+ rx += c;
+ break;
+ case '[':
+ rx += c;
+ if (wc[i] == QLatin1Char('^'))
+ rx += wc[i++];
+ if (i < wclen) {
+ if (rx[i] == QLatin1Char(']'))
+ rx += wc[i++];
+ while (i < wclen && wc[i] != QLatin1Char(']')) {
+ if (wc[i] == QLatin1Char('\\'))
+ rx += QLatin1Char('\\');
+ rx += wc[i++];
+ }
+ }
+ break;
+ default:
+ rx += c;
+ }
+ }
+ return rx;
+}
+#endif
+
+static int caretIndex(int offset, QRegExp::CaretMode caretMode)
+{
+ if (caretMode == QRegExp::CaretAtZero) {
+ return 0;
+ } else if (caretMode == QRegExp::CaretAtOffset) {
+ return offset;
+ } else { // QRegExp::CaretWontMatch
+ return -1;
+ }
+}
+
+/*
+ The QRegExpEngineKey struct uniquely identifies an engine.
+*/
+struct QRegExpEngineKey
+{
+ QString pattern;
+ QRegExp::PatternSyntax patternSyntax;
+ Qt::CaseSensitivity cs;
+
+ inline QRegExpEngineKey(const QString &pattern, QRegExp::PatternSyntax patternSyntax,
+ Qt::CaseSensitivity cs)
+ : pattern(pattern), patternSyntax(patternSyntax), cs(cs) {}
+
+ inline void clear() {
+ pattern.clear();
+ patternSyntax = QRegExp::RegExp;
+ cs = Qt::CaseSensitive;
+ }
+};
+
+bool operator==(const QRegExpEngineKey &key1, const QRegExpEngineKey &key2)
+{
+ return key1.pattern == key2.pattern && key1.patternSyntax == key2.patternSyntax
+ && key1.cs == key2.cs;
+}
+
+class QRegExpEngine;
+
+//Q_DECLARE_TYPEINFO(QVector<int>, Q_MOVABLE_TYPE);
+
+/*
+ This is the engine state during matching.
+*/
+struct QRegExpMatchState
+{
+ const QChar *in; // a pointer to the input string data
+ int pos; // the current position in the string
+ int caretPos;
+ int len; // the length of the input string
+ bool minimal; // minimal matching?
+ int *bigArray; // big array holding the data for the next pointers
+ int *inNextStack; // is state is nextStack?
+ int *curStack; // stack of current states
+ int *nextStack; // stack of next states
+ int *curCapBegin; // start of current states' captures
+ int *nextCapBegin; // start of next states' captures
+ int *curCapEnd; // end of current states' captures
+ int *nextCapEnd; // end of next states' captures
+ int *tempCapBegin; // start of temporary captures
+ int *tempCapEnd; // end of temporary captures
+ int *capBegin; // start of captures for a next state
+ int *capEnd; // end of captures for a next state
+ int *slideTab; // bump-along slide table for bad-character heuristic
+ int *captured; // what match() returned last
+ int slideTabSize; // size of slide table
+ int capturedSize;
+#ifndef QT_NO_REGEXP_BACKREF
+ QList<QVector<int> > sleeping; // list of back-reference sleepers
+#endif
+ int matchLen; // length of match
+ int oneTestMatchedLen; // length of partial match
+
+ const QRegExpEngine *eng;
+
+ inline QRegExpMatchState() : bigArray(0), captured(0) {}
+ inline ~QRegExpMatchState() { free(bigArray); }
+
+ void drain() { free(bigArray); bigArray = 0; captured = 0; } // to save memory
+ void prepareForMatch(QRegExpEngine *eng);
+ void match(const QChar *str, int len, int pos, bool minimal,
+ bool oneTest, int caretIndex);
+ bool matchHere();
+ bool testAnchor(int i, int a, const int *capBegin);
+};
+
+/*
+ The struct QRegExpAutomatonState represents one state in a modified NFA. The
+ input characters matched are stored in the state instead of on
+ the transitions, something possible for an automaton
+ constructed from a regular expression.
+*/
+struct QRegExpAutomatonState
+{
+#ifndef QT_NO_REGEXP_CAPTURE
+ int atom; // which atom does this state belong to?
+#endif
+ int match; // what does it match? (see CharClassBit and BackRefBit)
+ QVector<int> outs; // out-transitions
+ QMap<int, int> reenter; // atoms reentered when transiting out
+ QMap<int, int> anchors; // anchors met when transiting out
+
+ inline QRegExpAutomatonState() { }
+#ifndef QT_NO_REGEXP_CAPTURE
+ inline QRegExpAutomatonState(int a, int m)
+ : atom(a), match(m) { }
+#else
+ inline QRegExpAutomatonState(int m)
+ : match(m) { }
+#endif
+};
+
+Q_DECLARE_TYPEINFO(QRegExpAutomatonState, Q_MOVABLE_TYPE);
+
+/*
+ The struct QRegExpCharClassRange represents a range of characters (e.g.,
+ [0-9] denotes range 48 to 57).
+*/
+struct QRegExpCharClassRange
+{
+ ushort from; // 48
+ ushort len; // 10
+};
+
+Q_DECLARE_TYPEINFO(QRegExpCharClassRange, Q_PRIMITIVE_TYPE);
+
+#ifndef QT_NO_REGEXP_CAPTURE
+/*
+ The struct QRegExpAtom represents one node in the hierarchy of regular
+ expression atoms.
+*/
+struct QRegExpAtom
+{
+ enum { NoCapture = -1, OfficialCapture = -2, UnofficialCapture = -3 };
+
+ int parent; // index of parent in array of atoms
+ int capture; // index of capture, from 1 to ncap - 1
+};
+
+Q_DECLARE_TYPEINFO(QRegExpAtom, Q_PRIMITIVE_TYPE);
+#endif
+
+struct QRegExpLookahead;
+
+#ifndef QT_NO_REGEXP_ANCHOR_ALT
+/*
+ The struct QRegExpAnchorAlternation represents a pair of anchors with
+ OR semantics.
+*/
+struct QRegExpAnchorAlternation
+{
+ int a; // this anchor...
+ int b; // ...or this one
+};
+
+Q_DECLARE_TYPEINFO(QRegExpAnchorAlternation, Q_PRIMITIVE_TYPE);
+#endif
+
+#ifndef QT_NO_REGEXP_CCLASS
+/*
+ The class QRegExpCharClass represents a set of characters, such as can
+ be found in regular expressions (e.g., [a-z] denotes the set
+ {a, b, ..., z}).
+*/
+class QRegExpCharClass
+{
+public:
+ QRegExpCharClass();
+ inline QRegExpCharClass(const QRegExpCharClass &cc) { operator=(cc); }
+
+ QRegExpCharClass &operator=(const QRegExpCharClass &cc);
+
+ void clear();
+ bool negative() const { return n; }
+ void setNegative(bool negative);
+ void addCategories(int cats);
+ void addRange(ushort from, ushort to);
+ void addSingleton(ushort ch) { addRange(ch, ch); }
+
+ bool in(QChar ch) const;
+#ifndef QT_NO_REGEXP_OPTIM
+ const QVector<int> &firstOccurrence() const { return occ1; }
+#endif
+
+#if defined(QT_DEBUG)
+ void dump() const;
+#endif
+
+private:
+ int c; // character classes
+ QVector<QRegExpCharClassRange> r; // character ranges
+ bool n; // negative?
+#ifndef QT_NO_REGEXP_OPTIM
+ QVector<int> occ1; // first-occurrence array
+#endif
+};
+#else
+struct QRegExpCharClass
+{
+ int dummy;
+
+#ifndef QT_NO_REGEXP_OPTIM
+ QRegExpCharClass() { occ1.fill(0, NumBadChars); }
+
+ const QVector<int> &firstOccurrence() const { return occ1; }
+ QVector<int> occ1;
+#endif
+};
+#endif
+
+Q_DECLARE_TYPEINFO(QRegExpCharClass, Q_MOVABLE_TYPE);
+
+/*
+ The QRegExpEngine class encapsulates a modified nondeterministic
+ finite automaton (NFA).
+*/
+class QRegExpEngine
+{
+public:
+ QRegExpEngine(Qt::CaseSensitivity cs, bool greedyQuantifiers)
+ : cs(cs), greedyQuantifiers(greedyQuantifiers) { setup(); }
+
+ QRegExpEngine(const QRegExpEngineKey &key);
+ ~QRegExpEngine();
+
+ bool isValid() const { return valid; }
+ const QString &errorString() const { return yyError; }
+ int numCaptures() const { return officialncap; }
+
+ int createState(QChar ch);
+ int createState(const QRegExpCharClass &cc);
+#ifndef QT_NO_REGEXP_BACKREF
+ int createState(int bref);
+#endif
+
+ void addCatTransitions(const QVector<int> &from, const QVector<int> &to);
+#ifndef QT_NO_REGEXP_CAPTURE
+ void addPlusTransitions(const QVector<int> &from, const QVector<int> &to, int atom);
+#endif
+
+#ifndef QT_NO_REGEXP_ANCHOR_ALT
+ int anchorAlternation(int a, int b);
+ int anchorConcatenation(int a, int b);
+#else
+ int anchorAlternation(int a, int b) { return a & b; }
+ int anchorConcatenation(int a, int b) { return a | b; }
+#endif
+ void addAnchors(int from, int to, int a);
+
+#ifndef QT_NO_REGEXP_OPTIM
+ void heuristicallyChooseHeuristic();
+#endif
+
+#if defined(QT_DEBUG)
+ void dump() const;
+#endif
+
+ QAtomicInt ref;
+
+private:
+ enum { CharClassBit = 0x10000, BackRefBit = 0x20000 };
+ enum { InitialState = 0, FinalState = 1 };
+
+ void setup();
+ int setupState(int match);
+
+ /*
+ Let's hope that 13 lookaheads and 14 back-references are
+ enough.
+ */
+ enum { MaxLookaheads = 13, MaxBackRefs = 14 };
+ enum { Anchor_Dollar = 0x00000001, Anchor_Caret = 0x00000002, Anchor_Word = 0x00000004,
+ Anchor_NonWord = 0x00000008, Anchor_FirstLookahead = 0x00000010,
+ Anchor_BackRef1Empty = Anchor_FirstLookahead << MaxLookaheads,
+ Anchor_BackRef0Empty = Anchor_BackRef1Empty >> 1,
+ Anchor_Alternation = unsigned(Anchor_BackRef1Empty) << MaxBackRefs,
+
+ Anchor_LookaheadMask = (Anchor_FirstLookahead - 1) ^
+ ((Anchor_FirstLookahead << MaxLookaheads) - 1) };
+#ifndef QT_NO_REGEXP_CAPTURE
+ int startAtom(bool officialCapture);
+ void finishAtom(int atom, bool needCapture);
+#endif
+
+#ifndef QT_NO_REGEXP_LOOKAHEAD
+ int addLookahead(QRegExpEngine *eng, bool negative);
+#endif
+
+#ifndef QT_NO_REGEXP_OPTIM
+ bool goodStringMatch(QRegExpMatchState &matchState) const;
+ bool badCharMatch(QRegExpMatchState &matchState) const;
+#else
+ bool bruteMatch(QRegExpMatchState &matchState) const;
+#endif
+
+ QVector<QRegExpAutomatonState> s; // array of states
+#ifndef QT_NO_REGEXP_CAPTURE
+ QVector<QRegExpAtom> f; // atom hierarchy
+ int nf; // number of atoms
+ int cf; // current atom
+ QVector<int> captureForOfficialCapture;
+#endif
+ int officialncap; // number of captures, seen from the outside
+ int ncap; // number of captures, seen from the inside
+#ifndef QT_NO_REGEXP_CCLASS
+ QVector<QRegExpCharClass> cl; // array of character classes
+#endif
+#ifndef QT_NO_REGEXP_LOOKAHEAD
+ QVector<QRegExpLookahead *> ahead; // array of lookaheads
+#endif
+#ifndef QT_NO_REGEXP_ANCHOR_ALT
+ QVector<QRegExpAnchorAlternation> aa; // array of (a, b) pairs of anchors
+#endif
+#ifndef QT_NO_REGEXP_OPTIM
+ bool caretAnchored; // does the regexp start with ^?
+ bool trivial; // is the good-string all that needs to match?
+#endif
+ bool valid; // is the regular expression valid?
+ Qt::CaseSensitivity cs; // case sensitive?
+ bool greedyQuantifiers; // RegExp2?
+#ifndef QT_NO_REGEXP_BACKREF
+ int nbrefs; // number of back-references
+#endif
+
+#ifndef QT_NO_REGEXP_OPTIM
+ bool useGoodStringHeuristic; // use goodStringMatch? otherwise badCharMatch
+
+ int goodEarlyStart; // the index where goodStr can first occur in a match
+ int goodLateStart; // the index where goodStr can last occur in a match
+ QString goodStr; // the string that any match has to contain
+
+ int minl; // the minimum length of a match
+ QVector<int> occ1; // first-occurrence array
+#endif
+
+ /*
+ The class Box is an abstraction for a regular expression
+ fragment. It can also be seen as one node in the syntax tree of
+ a regular expression with synthetized attributes.
+
+ Its interface is ugly for performance reasons.
+ */
+ class Box
+ {
+ public:
+ Box(QRegExpEngine *engine);
+ Box(const Box &b) { operator=(b); }
+
+ Box &operator=(const Box &b);
+
+ void clear() { operator=(Box(eng)); }
+ void set(QChar ch);
+ void set(const QRegExpCharClass &cc);
+#ifndef QT_NO_REGEXP_BACKREF
+ void set(int bref);
+#endif
+
+ void cat(const Box &b);
+ void orx(const Box &b);
+ void plus(int atom);
+ void opt();
+ void catAnchor(int a);
+#ifndef QT_NO_REGEXP_OPTIM
+ void setupHeuristics();
+#endif
+
+#if defined(QT_DEBUG)
+ void dump() const;
+#endif
+
+ private:
+ void addAnchorsToEngine(const Box &to) const;
+
+ QRegExpEngine *eng; // the automaton under construction
+ QVector<int> ls; // the left states (firstpos)
+ QVector<int> rs; // the right states (lastpos)
+ QMap<int, int> lanchors; // the left anchors
+ QMap<int, int> ranchors; // the right anchors
+ int skipanchors; // the anchors to match if the box is skipped
+
+#ifndef QT_NO_REGEXP_OPTIM
+ int earlyStart; // the index where str can first occur
+ int lateStart; // the index where str can last occur
+ QString str; // a string that has to occur in any match
+ QString leftStr; // a string occurring at the left of this box
+ QString rightStr; // a string occurring at the right of this box
+ int maxl; // the maximum length of this box (possibly InftyLen)
+#endif
+
+ int minl; // the minimum length of this box
+#ifndef QT_NO_REGEXP_OPTIM
+ QVector<int> occ1; // first-occurrence array
+#endif
+ };
+
+ friend class Box;
+
+ /*
+ This is the lexical analyzer for regular expressions.
+ */
+ enum { Tok_Eos, Tok_Dollar, Tok_LeftParen, Tok_MagicLeftParen, Tok_PosLookahead,
+ Tok_NegLookahead, Tok_RightParen, Tok_CharClass, Tok_Caret, Tok_Quantifier, Tok_Bar,
+ Tok_Word, Tok_NonWord, Tok_Char = 0x10000, Tok_BackRef = 0x20000 };
+ int getChar();
+ int getEscape();
+#ifndef QT_NO_REGEXP_INTERVAL
+ int getRep(int def);
+#endif
+#ifndef QT_NO_REGEXP_LOOKAHEAD
+ void skipChars(int n);
+#endif
+ void error(const char *msg);
+ void startTokenizer(const QChar *rx, int len);
+ int getToken();
+
+ const QChar *yyIn; // a pointer to the input regular expression pattern
+ int yyPos0; // the position of yyTok in the input pattern
+ int yyPos; // the position of the next character to read
+ int yyLen; // the length of yyIn
+ int yyCh; // the last character read
+ QRegExpCharClass *yyCharClass; // attribute for Tok_CharClass tokens
+ int yyMinRep; // attribute for Tok_Quantifier
+ int yyMaxRep; // ditto
+ QString yyError; // syntax error or overflow during parsing?
+
+ /*
+ This is the syntactic analyzer for regular expressions.
+ */
+ int parse(const QChar *rx, int len);
+ void parseAtom(Box *box);
+ void parseFactor(Box *box);
+ void parseTerm(Box *box);
+ void parseExpression(Box *box);
+
+ int yyTok; // the last token read
+ bool yyMayCapture; // set this to false to disable capturing
+
+ friend struct QRegExpMatchState;
+};
+
+#ifndef QT_NO_REGEXP_LOOKAHEAD
+/*
+ The struct QRegExpLookahead represents a lookahead a la Perl (e.g.,
+ (?=foo) and (?!bar)).
+*/
+struct QRegExpLookahead
+{
+ QRegExpEngine *eng; // NFA representing the embedded regular expression
+ bool neg; // negative lookahead?
+
+ inline QRegExpLookahead(QRegExpEngine *eng0, bool neg0)
+ : eng(eng0), neg(neg0) { }
+ inline ~QRegExpLookahead() { delete eng; }
+};
+#endif
+
+QRegExpEngine::QRegExpEngine(const QRegExpEngineKey &key)
+ : cs(key.cs), greedyQuantifiers(key.patternSyntax == QRegExp::RegExp2)
+{
+ setup();
+
+ QString rx;
+
+ switch (key.patternSyntax) {
+ case QRegExp::Wildcard:
+#ifndef QT_NO_REGEXP_WILDCARD
+ rx = wc2rx(key.pattern);
+#endif
+ break;
+ case QRegExp::FixedString:
+ rx = QRegExp::escape(key.pattern);
+ break;
+ default:
+ rx = key.pattern;
+ }
+
+ valid = (parse(rx.unicode(), rx.length()) == rx.length());
+ if (!valid) {
+#ifndef QT_NO_REGEXP_OPTIM
+ trivial = false;
+#endif
+ error(RXERR_LEFTDELIM);
+ }
+}
+
+QRegExpEngine::~QRegExpEngine()
+{
+#ifndef QT_NO_REGEXP_LOOKAHEAD
+ qDeleteAll(ahead);
+#endif
+}
+
+void QRegExpMatchState::prepareForMatch(QRegExpEngine *eng)
+{
+ /*
+ We use one QVector<int> for all the big data used a lot in
+ matchHere() and friends.
+ */
+ int ns = eng->s.size(); // number of states
+ int ncap = eng->ncap;
+#ifndef QT_NO_REGEXP_OPTIM
+ slideTabSize = qMax(eng->minl + 1, 16);
+#else
+ slideTabSize = 0;
+#endif
+ int numCaptures = eng->numCaptures();
+ capturedSize = 2 + 2 * numCaptures;
+ bigArray = (int *)realloc(bigArray, ((3 + 4 * ncap) * ns + 4 * ncap + slideTabSize + capturedSize)*sizeof(int));
+
+ inNextStack = bigArray;
+ memset(inNextStack, -1, ns * sizeof(int));
+ curStack = inNextStack + ns;
+ nextStack = inNextStack + 2 * ns;
+
+ curCapBegin = inNextStack + 3 * ns;
+ nextCapBegin = curCapBegin + ncap * ns;
+ curCapEnd = curCapBegin + 2 * ncap * ns;
+ nextCapEnd = curCapBegin + 3 * ncap * ns;
+
+ tempCapBegin = curCapBegin + 4 * ncap * ns;
+ tempCapEnd = tempCapBegin + ncap;
+ capBegin = tempCapBegin + 2 * ncap;
+ capEnd = tempCapBegin + 3 * ncap;
+
+ slideTab = tempCapBegin + 4 * ncap;
+ captured = slideTab + slideTabSize;
+ memset(captured, -1, capturedSize*sizeof(int));
+ this->eng = eng;
+}
+
+/*
+ Tries to match in str and returns an array of (begin, length) pairs
+ for captured text. If there is no match, all pairs are (-1, -1).
+*/
+void QRegExpMatchState::match(const QChar *str0, int len0, int pos0,
+ bool minimal0, bool oneTest, int caretIndex)
+{
+ bool matched = false;
+ QChar char_null;
+
+#ifndef QT_NO_REGEXP_OPTIM
+ if (eng->trivial && !oneTest) {
+ pos = qFindString(str0, len0, pos0, eng->goodStr.unicode(), eng->goodStr.length(), eng->cs);
+ matchLen = eng->goodStr.length();
+ matched = (pos != -1);
+ } else
+#endif
+ {
+ in = str0;
+ if (in == 0)
+ in = &char_null;
+ pos = pos0;
+ caretPos = caretIndex;
+ len = len0;
+ minimal = minimal0;
+ matchLen = 0;
+ oneTestMatchedLen = 0;
+
+ if (eng->valid && pos >= 0 && pos <= len) {
+#ifndef QT_NO_REGEXP_OPTIM
+ if (oneTest) {
+ matched = matchHere();
+ } else {
+ if (pos <= len - eng->minl) {
+ if (eng->caretAnchored) {
+ matched = matchHere();
+ } else if (eng->useGoodStringHeuristic) {
+ matched = eng->goodStringMatch(*this);
+ } else {
+ matched = eng->badCharMatch(*this);
+ }
+ }
+ }
+#else
+ matched = oneTest ? matchHere() : eng->bruteMatch(*this);
+#endif
+ }
+ }
+
+ if (matched) {
+ int *c = captured;
+ *c++ = pos;
+ *c++ = matchLen;
+
+ int numCaptures = (capturedSize - 2) >> 1;
+#ifndef QT_NO_REGEXP_CAPTURE
+ for (int i = 0; i < numCaptures; ++i) {
+ int j = eng->captureForOfficialCapture.at(i);
+ int len = capEnd[j] - capBegin[j];
+ *c++ = (len > 0) ? pos + capBegin[j] : 0;
+ *c++ = len;
+ }
+#endif
+ } else {
+ // we rely on 2's complement here
+ memset(captured, -1, capturedSize * sizeof(int));
+ }
+}
+
+/*
+ The three following functions add one state to the automaton and
+ return the number of the state.
+*/
+
+int QRegExpEngine::createState(QChar ch)
+{
+ return setupState(ch.unicode());
+}
+
+int QRegExpEngine::createState(const QRegExpCharClass &cc)
+{
+#ifndef QT_NO_REGEXP_CCLASS
+ int n = cl.size();
+ cl += QRegExpCharClass(cc);
+ return setupState(CharClassBit | n);
+#else
+ Q_UNUSED(cc);
+ return setupState(CharClassBit);
+#endif
+}
+
+#ifndef QT_NO_REGEXP_BACKREF
+int QRegExpEngine::createState(int bref)
+{
+ if (bref > nbrefs) {
+ nbrefs = bref;
+ if (nbrefs > MaxBackRefs) {
+ error(RXERR_LIMIT);
+ return 0;
+ }
+ }
+ return setupState(BackRefBit | bref);
+}
+#endif
+
+/*
+ The two following functions add a transition between all pairs of
+ states (i, j) where i is found in from, and j is found in to.
+
+ Cat-transitions are distinguished from plus-transitions for
+ capturing.
+*/
+
+void QRegExpEngine::addCatTransitions(const QVector<int> &from, const QVector<int> &to)
+{
+ for (int i = 0; i < from.size(); i++)
+ mergeInto(&s[from.at(i)].outs, to);
+}
+
+#ifndef QT_NO_REGEXP_CAPTURE
+void QRegExpEngine::addPlusTransitions(const QVector<int> &from, const QVector<int> &to, int atom)
+{
+ for (int i = 0; i < from.size(); i++) {
+ QRegExpAutomatonState &st = s[from.at(i)];
+ const QVector<int> oldOuts = st.outs;
+ mergeInto(&st.outs, to);
+ if (f.at(atom).capture != QRegExpAtom::NoCapture) {
+ for (int j = 0; j < to.size(); j++) {
+ // ### st.reenter.contains(to.at(j)) check looks suspicious
+ if (!st.reenter.contains(to.at(j)) &&
+ qBinaryFind(oldOuts.constBegin(), oldOuts.constEnd(), to.at(j)) == oldOuts.end())
+ st.reenter.insert(to.at(j), atom);
+ }
+ }
+ }
+}
+#endif
+
+#ifndef QT_NO_REGEXP_ANCHOR_ALT
+/*
+ Returns an anchor that means a OR b.
+*/
+int QRegExpEngine::anchorAlternation(int a, int b)
+{
+ if (((a & b) == a || (a & b) == b) && ((a | b) & Anchor_Alternation) == 0)
+ return a & b;
+
+ int n = aa.size();
+#ifndef QT_NO_REGEXP_OPTIM
+ if (n > 0 && aa.at(n - 1).a == a && aa.at(n - 1).b == b)
+ return Anchor_Alternation | (n - 1);
+#endif
+
+ aa.resize(n + 1);
+ aa[n].a = a;
+ aa[n].b = b;
+ return Anchor_Alternation | n;
+}
+
+/*
+ Returns an anchor that means a AND b.
+*/
+int QRegExpEngine::anchorConcatenation(int a, int b)
+{
+ if (((a | b) & Anchor_Alternation) == 0)
+ return a | b;
+ if ((b & Anchor_Alternation) != 0)
+ qSwap(a, b);
+
+ int aprime = anchorConcatenation(aa.at(a ^ Anchor_Alternation).a, b);
+ int bprime = anchorConcatenation(aa.at(a ^ Anchor_Alternation).b, b);
+ return anchorAlternation(aprime, bprime);
+}
+#endif
+
+/*
+ Adds anchor a on a transition caracterised by its from state and
+ its to state.
+*/
+void QRegExpEngine::addAnchors(int from, int to, int a)
+{
+ QRegExpAutomatonState &st = s[from];
+ if (st.anchors.contains(to))
+ a = anchorAlternation(st.anchors.value(to), a);
+ st.anchors.insert(to, a);
+}
+
+#ifndef QT_NO_REGEXP_OPTIM
+/*
+ This function chooses between the good-string and the bad-character
+ heuristics. It computes two scores and chooses the heuristic with
+ the highest score.
+
+ Here are some common-sense constraints on the scores that should be
+ respected if the formulas are ever modified: (1) If goodStr is
+ empty, the good-string heuristic scores 0. (2) If the regular
+ expression is trivial, the good-string heuristic should be used.
+ (3) If the search is case insensitive, the good-string heuristic
+ should be used, unless it scores 0. (Case insensitivity turns all
+ entries of occ1 to 0.) (4) If (goodLateStart - goodEarlyStart) is
+ big, the good-string heuristic should score less.
+*/
+void QRegExpEngine::heuristicallyChooseHeuristic()
+{
+ if (minl == 0) {
+ useGoodStringHeuristic = false;
+ } else if (trivial) {
+ useGoodStringHeuristic = true;
+ } else {
+ /*
+ Magic formula: The good string has to constitute a good
+ proportion of the minimum-length string, and appear at a
+ more-or-less known index.
+ */
+ int goodStringScore = (64 * goodStr.length() / minl) -
+ (goodLateStart - goodEarlyStart);
+ /*
+ Less magic formula: We pick some characters at random, and
+ check whether they are good or bad.
+ */
+ int badCharScore = 0;
+ int step = qMax(1, NumBadChars / 32);
+ for (int i = 1; i < NumBadChars; i += step) {
+ if (occ1.at(i) == NoOccurrence)
+ badCharScore += minl;
+ else
+ badCharScore += occ1.at(i);
+ }
+ badCharScore /= minl;
+ useGoodStringHeuristic = (goodStringScore > badCharScore);
+ }
+}
+#endif
+
+#if defined(QT_DEBUG)
+void QRegExpEngine::dump() const
+{
+ int i, j;
+ qDebug("Case %ssensitive engine", cs ? "" : "in");
+ qDebug(" States");
+ for (i = 0; i < s.size(); i++) {
+ qDebug(" %d%s", i, i == InitialState ? " (initial)" : i == FinalState ? " (final)" : "");
+#ifndef QT_NO_REGEXP_CAPTURE
+ if (nf > 0)
+ qDebug(" in atom %d", s[i].atom);
+#endif
+ int m = s[i].match;
+ if ((m & CharClassBit) != 0) {
+ qDebug(" match character class %d", m ^ CharClassBit);
+#ifndef QT_NO_REGEXP_CCLASS
+ cl[m ^ CharClassBit].dump();
+#else
+ qDebug(" negative character class");
+#endif
+ } else if ((m & BackRefBit) != 0) {
+ qDebug(" match back-reference %d", m ^ BackRefBit);
+ } else if (m >= 0x20 && m <= 0x7e) {
+ qDebug(" match 0x%.4x (%c)", m, m);
+ } else {
+ qDebug(" match 0x%.4x", m);
+ }
+ for (j = 0; j < s[i].outs.size(); j++) {
+ int next = s[i].outs[j];
+ qDebug(" -> %d", next);
+ if (s[i].reenter.contains(next))
+ qDebug(" [reenter %d]", s[i].reenter[next]);
+ if (s[i].anchors.value(next) != 0)
+ qDebug(" [anchors 0x%.8x]", s[i].anchors[next]);
+ }
+ }
+#ifndef QT_NO_REGEXP_CAPTURE
+ if (nf > 0) {
+ qDebug(" Atom Parent Capture");
+ for (i = 0; i < nf; i++) {
+ if (f[i].capture == QRegExpAtom::NoCapture) {
+ qDebug(" %6d %6d nil", i, f[i].parent);
+ } else {
+ int cap = f[i].capture;
+ bool official = captureForOfficialCapture.contains(cap);
+ qDebug(" %6d %6d %6d %s", i, f[i].parent, f[i].capture,
+ official ? "official" : "");
+ }
+ }
+ }
+#endif
+#ifndef QT_NO_REGEXP_ANCHOR_ALT
+ for (i = 0; i < aa.size(); i++)
+ qDebug(" Anchor alternation 0x%.8x: 0x%.8x 0x%.9x", i, aa[i].a, aa[i].b);
+#endif
+}
+#endif
+
+void QRegExpEngine::setup()
+{
+ ref = 1;
+#ifndef QT_NO_REGEXP_CAPTURE
+ f.resize(32);
+ nf = 0;
+ cf = -1;
+#endif
+ officialncap = 0;
+ ncap = 0;
+#ifndef QT_NO_REGEXP_OPTIM
+ caretAnchored = true;
+ trivial = true;
+#endif
+ valid = false;
+#ifndef QT_NO_REGEXP_BACKREF
+ nbrefs = 0;
+#endif
+#ifndef QT_NO_REGEXP_OPTIM
+ useGoodStringHeuristic = true;
+ minl = 0;
+ occ1.fill(0, NumBadChars);
+#endif
+}
+
+int QRegExpEngine::setupState(int match)
+{
+#ifndef QT_NO_REGEXP_CAPTURE
+ s += QRegExpAutomatonState(cf, match);
+#else
+ s += QRegExpAutomatonState(match);
+#endif
+ return s.size() - 1;
+}
+
+#ifndef QT_NO_REGEXP_CAPTURE
+/*
+ Functions startAtom() and finishAtom() should be called to delimit
+ atoms. When a state is created, it is assigned to the current atom.
+ The information is later used for capturing.
+*/
+int QRegExpEngine::startAtom(bool officialCapture)
+{
+ if ((nf & (nf + 1)) == 0 && nf + 1 >= f.size())
+ f.resize((nf + 1) << 1);
+ f[nf].parent = cf;
+ cf = nf++;
+ f[cf].capture = officialCapture ? QRegExpAtom::OfficialCapture : QRegExpAtom::NoCapture;
+ return cf;
+}
+
+void QRegExpEngine::finishAtom(int atom, bool needCapture)
+{
+ if (greedyQuantifiers && needCapture && f[atom].capture == QRegExpAtom::NoCapture)
+ f[atom].capture = QRegExpAtom::UnofficialCapture;
+ cf = f.at(atom).parent;
+}
+#endif
+
+#ifndef QT_NO_REGEXP_LOOKAHEAD
+/*
+ Creates a lookahead anchor.
+*/
+int QRegExpEngine::addLookahead(QRegExpEngine *eng, bool negative)
+{
+ int n = ahead.size();
+ if (n == MaxLookaheads) {
+ error(RXERR_LIMIT);
+ return 0;
+ }
+ ahead += new QRegExpLookahead(eng, negative);
+ return Anchor_FirstLookahead << n;
+}
+#endif
+
+#ifndef QT_NO_REGEXP_CAPTURE
+/*
+ We want the longest leftmost captures.
+*/
+static bool isBetterCapture(int ncap, const int *begin1, const int *end1, const int *begin2,
+ const int *end2)
+{
+ for (int i = 0; i < ncap; i++) {
+ int delta = begin2[i] - begin1[i]; // it has to start early...
+ if (delta == 0)
+ delta = end1[i] - end2[i]; // ...and end late
+
+ if (delta != 0)
+ return delta > 0;
+ }
+ return false;
+}
+#endif
+
+/*
+ Returns true if anchor a matches at position pos + i in the input
+ string, otherwise false.
+*/
+bool QRegExpMatchState::testAnchor(int i, int a, const int *capBegin)
+{
+ int j;
+
+#ifndef QT_NO_REGEXP_ANCHOR_ALT
+ if ((a & QRegExpEngine::Anchor_Alternation) != 0)
+ return testAnchor(i, eng->aa.at(a ^ QRegExpEngine::Anchor_Alternation).a, capBegin)
+ || testAnchor(i, eng->aa.at(a ^ QRegExpEngine::Anchor_Alternation).b, capBegin);
+#endif
+
+ if ((a & QRegExpEngine::Anchor_Caret) != 0) {
+ if (pos + i != caretPos)
+ return false;
+ }
+ if ((a & QRegExpEngine::Anchor_Dollar) != 0) {
+ if (pos + i != len)
+ return false;
+ }
+#ifndef QT_NO_REGEXP_ESCAPE
+ if ((a & (QRegExpEngine::Anchor_Word | QRegExpEngine::Anchor_NonWord)) != 0) {
+ bool before = false;
+ bool after = false;
+ if (pos + i != 0)
+ before = isWord(in[pos + i - 1]);
+ if (pos + i != len)
+ after = isWord(in[pos + i]);
+ if ((a & QRegExpEngine::Anchor_Word) != 0 && (before == after))
+ return false;
+ if ((a & QRegExpEngine::Anchor_NonWord) != 0 && (before != after))
+ return false;
+ }
+#endif
+#ifndef QT_NO_REGEXP_LOOKAHEAD
+ if ((a & QRegExpEngine::Anchor_LookaheadMask) != 0) {
+ const QVector<QRegExpLookahead *> &ahead = eng->ahead;
+ for (j = 0; j < ahead.size(); j++) {
+ if ((a & (QRegExpEngine::Anchor_FirstLookahead << j)) != 0) {
+ QRegExpMatchState matchState;
+ matchState.prepareForMatch(ahead[j]->eng);
+ matchState.match(in + pos + i, len - pos - i, 0,
+ true, true, matchState.caretPos - matchState.pos - i);
+ if ((matchState.captured[0] == 0) == ahead[j]->neg)
+ return false;
+ }
+ }
+ }
+#endif
+#ifndef QT_NO_REGEXP_CAPTURE
+#ifndef QT_NO_REGEXP_BACKREF
+ for (j = 0; j < eng->nbrefs; j++) {
+ if ((a & (QRegExpEngine::Anchor_BackRef1Empty << j)) != 0) {
+ int i = eng->captureForOfficialCapture.at(j);
+ if (capBegin[i] != EmptyCapture)
+ return false;
+ }
+ }
+#endif
+#endif
+ return true;
+}
+
+#ifndef QT_NO_REGEXP_OPTIM
+/*
+ The three following functions are what Jeffrey Friedl would call
+ transmissions (or bump-alongs). Using one or the other should make
+ no difference except in performance.
+*/
+
+bool QRegExpEngine::goodStringMatch(QRegExpMatchState &matchState) const
+{
+ int k = matchState.pos + goodEarlyStart;
+ QStringMatcher matcher(goodStr.unicode(), goodStr.length(), cs);
+ while ((k = matcher.indexIn(matchState.in, matchState.len, k)) != -1) {
+ int from = k - goodLateStart;
+ int to = k - goodEarlyStart;
+ if (from > matchState.pos)
+ matchState.pos = from;
+
+ while (matchState.pos <= to) {
+ if (matchState.matchHere())
+ return true;
+ ++matchState.pos;
+ }
+ ++k;
+ }
+ return false;
+}
+
+bool QRegExpEngine::badCharMatch(QRegExpMatchState &matchState) const
+{
+ int slideHead = 0;
+ int slideNext = 0;
+ int i;
+ int lastPos = matchState.len - minl;
+ memset(matchState.slideTab, 0, matchState.slideTabSize * sizeof(int));
+
+ /*
+ Set up the slide table, used for the bad-character heuristic,
+ using the table of first occurrence of each character.
+ */
+ for (i = 0; i < minl; i++) {
+ int sk = occ1[BadChar(matchState.in[matchState.pos + i])];
+ if (sk == NoOccurrence)
+ sk = i + 1;
+ if (sk > 0) {
+ int k = i + 1 - sk;
+ if (k < 0) {
+ sk = i + 1;
+ k = 0;
+ }
+ if (sk > matchState.slideTab[k])
+ matchState.slideTab[k] = sk;
+ }
+ }
+
+ if (matchState.pos > lastPos)
+ return false;
+
+ for (;;) {
+ if (++slideNext >= matchState.slideTabSize)
+ slideNext = 0;
+ if (matchState.slideTab[slideHead] > 0) {
+ if (matchState.slideTab[slideHead] - 1 > matchState.slideTab[slideNext])
+ matchState.slideTab[slideNext] = matchState.slideTab[slideHead] - 1;
+ matchState.slideTab[slideHead] = 0;
+ } else {
+ if (matchState.matchHere())
+ return true;
+ }
+
+ if (matchState.pos == lastPos)
+ break;
+
+ /*
+ Update the slide table. This code has much in common with
+ the initialization code.
+ */
+ int sk = occ1[BadChar(matchState.in[matchState.pos + minl])];
+ if (sk == NoOccurrence) {
+ matchState.slideTab[slideNext] = minl;
+ } else if (sk > 0) {
+ int k = slideNext + minl - sk;
+ if (k >= matchState.slideTabSize)
+ k -= matchState.slideTabSize;
+ if (sk > matchState.slideTab[k])
+ matchState.slideTab[k] = sk;
+ }
+ slideHead = slideNext;
+ ++matchState.pos;
+ }
+ return false;
+}
+#else
+bool QRegExpEngine::bruteMatch(QRegExpMatchState &matchState) const
+{
+ while (matchState.pos <= matchState.len) {
+ if (matchState.matchHere())
+ return true;
+ ++matchState.pos;
+ }
+ return false;
+}
+#endif
+
+/*
+ Here's the core of the engine. It tries to do a match here and now.
+*/
+bool QRegExpMatchState::matchHere()
+{
+ int ncur = 1, nnext = 0;
+ int i = 0, j, k, m;
+ bool stop = false;
+
+ matchLen = -1;
+ oneTestMatchedLen = -1;
+ curStack[0] = QRegExpEngine::InitialState;
+
+ int ncap = eng->ncap;
+#ifndef QT_NO_REGEXP_CAPTURE
+ if (ncap > 0) {
+ for (j = 0; j < ncap; j++) {
+ curCapBegin[j] = EmptyCapture;
+ curCapEnd[j] = EmptyCapture;
+ }
+ }
+#endif
+
+#ifndef QT_NO_REGEXP_BACKREF
+ while ((ncur > 0 || !sleeping.isEmpty()) && i <= len - pos && !stop)
+#else
+ while (ncur > 0 && i <= len - pos && !stop)
+#endif
+ {
+ int ch = (i < len - pos) ? in[pos + i].unicode() : 0;
+ for (j = 0; j < ncur; j++) {
+ int cur = curStack[j];
+ const QRegExpAutomatonState &scur = eng->s.at(cur);
+ const QVector<int> &outs = scur.outs;
+ for (k = 0; k < outs.size(); k++) {
+ int next = outs.at(k);
+ const QRegExpAutomatonState &snext = eng->s.at(next);
+ bool inside = true;
+#if !defined(QT_NO_REGEXP_BACKREF) && !defined(QT_NO_REGEXP_CAPTURE)
+ int needSomeSleep = 0;
+#endif
+
+ /*
+ First, check if the anchors are anchored properly.
+ */
+ int a = scur.anchors.value(next);
+ if (a != 0 && !testAnchor(i, a, curCapBegin + j * ncap))
+ inside = false;
+
+ /*
+ If indeed they are, check if the input character is
+ correct for this transition.
+ */
+ if (inside) {
+ m = snext.match;
+ if ((m & (QRegExpEngine::CharClassBit | QRegExpEngine::BackRefBit)) == 0) {
+ if (eng->cs)
+ inside = (m == ch);
+ else
+ inside = (QChar(m).toLower() == QChar(ch).toLower());
+ } else if (next == QRegExpEngine::FinalState) {
+ matchLen = i;
+ stop = minimal;
+ inside = true;
+ } else if ((m & QRegExpEngine::CharClassBit) != 0) {
+#ifndef QT_NO_REGEXP_CCLASS
+ const QRegExpCharClass &cc = eng->cl.at(m ^ QRegExpEngine::CharClassBit);
+ if (eng->cs)
+ inside = cc.in(ch);
+ else if (cc.negative())
+ inside = cc.in(QChar(ch).toLower()) &&
+ cc.in(QChar(ch).toUpper());
+ else
+ inside = cc.in(QChar(ch).toLower()) ||
+ cc.in(QChar(ch).toUpper());
+#endif
+#if !defined(QT_NO_REGEXP_BACKREF) && !defined(QT_NO_REGEXP_CAPTURE)
+ } else { /* ((m & QRegExpEngine::BackRefBit) != 0) */
+ int bref = m ^ QRegExpEngine::BackRefBit;
+ int ell = j * ncap + eng->captureForOfficialCapture.at(bref - 1);
+
+ inside = bref <= ncap && curCapBegin[ell] != EmptyCapture;
+ if (inside) {
+ if (eng->cs)
+ inside = (in[pos + curCapBegin[ell]] == QChar(ch));
+ else
+ inside = (in[pos + curCapBegin[ell]].toLower()
+ == QChar(ch).toLower());
+ }
+
+ if (inside) {
+ int delta;
+ if (curCapEnd[ell] == EmptyCapture)
+ delta = i - curCapBegin[ell];
+ else
+ delta = curCapEnd[ell] - curCapBegin[ell];
+
+ inside = (delta <= len - (pos + i));
+ if (inside && delta > 1) {
+ int n = 1;
+ if (eng->cs) {
+ while (n < delta) {
+ if (in[pos + curCapBegin[ell] + n]
+ != in[pos + i + n])
+ break;
+ ++n;
+ }
+ } else {
+ while (n < delta) {
+ QChar a = in[pos + curCapBegin[ell] + n];
+ QChar b = in[pos + i + n];
+ if (a.toLower() != b.toLower())
+ break;
+ ++n;
+ }
+ }
+ inside = (n == delta);
+ if (inside)
+ needSomeSleep = delta - 1;
+ }
+ }
+#endif
+ }
+ }
+
+ /*
+ We must now update our data structures.
+ */
+ if (inside) {
+#ifndef QT_NO_REGEXP_CAPTURE
+ int *capBegin, *capEnd;
+#endif
+ /*
+ If the next state was not encountered yet, all
+ is fine.
+ */
+ if ((m = inNextStack[next]) == -1) {
+ m = nnext++;
+ nextStack[m] = next;
+ inNextStack[next] = m;
+#ifndef QT_NO_REGEXP_CAPTURE
+ capBegin = nextCapBegin + m * ncap;
+ capEnd = nextCapEnd + m * ncap;
+
+ /*
+ Otherwise, we'll first maintain captures in
+ temporary arrays, and decide at the end whether
+ it's best to keep the previous capture zones or
+ the new ones.
+ */
+ } else {
+ capBegin = tempCapBegin;
+ capEnd = tempCapEnd;
+#endif
+ }
+
+#ifndef QT_NO_REGEXP_CAPTURE
+ /*
+ Updating the capture zones is much of a task.
+ */
+ if (ncap > 0) {
+ memcpy(capBegin, curCapBegin + j * ncap, ncap * sizeof(int));
+ memcpy(capEnd, curCapEnd + j * ncap, ncap * sizeof(int));
+ int c = scur.atom, n = snext.atom;
+ int p = -1, q = -1;
+ int cap;
+
+ /*
+ Lemma 1. For any x in the range [0..nf), we
+ have f[x].parent < x.
+
+ Proof. By looking at startAtom(), it is
+ clear that cf < nf holds all the time, and
+ thus that f[nf].parent < nf.
+ */
+
+ /*
+ If we are reentering an atom, we empty all
+ capture zones inside it.
+ */
+ if ((q = scur.reenter.value(next)) != 0) {
+ QBitArray b(eng->nf, false);
+ b.setBit(q, true);
+ for (int ell = q + 1; ell < eng->nf; ell++) {
+ if (b.testBit(eng->f.at(ell).parent)) {
+ b.setBit(ell, true);
+ cap = eng->f.at(ell).capture;
+ if (cap >= 0) {
+ capBegin[cap] = EmptyCapture;
+ capEnd[cap] = EmptyCapture;
+ }
+ }
+ }
+ p = eng->f.at(q).parent;
+
+ /*
+ Otherwise, close the capture zones we are
+ leaving. We are leaving f[c].capture,
+ f[f[c].parent].capture,
+ f[f[f[c].parent].parent].capture, ...,
+ until f[x].capture, with x such that
+ f[x].parent is the youngest common ancestor
+ for c and n.
+
+ We go up along c's and n's ancestry until
+ we find x.
+ */
+ } else {
+ p = c;
+ q = n;
+ while (p != q) {
+ if (p > q) {
+ cap = eng->f.at(p).capture;
+ if (cap >= 0) {
+ if (capBegin[cap] == i) {
+ capBegin[cap] = EmptyCapture;
+ capEnd[cap] = EmptyCapture;
+ } else {
+ capEnd[cap] = i;
+ }
+ }
+ p = eng->f.at(p).parent;
+ } else {
+ q = eng->f.at(q).parent;
+ }
+ }
+ }
+
+ /*
+ In any case, we now open the capture zones
+ we are entering. We work upwards from n
+ until we reach p (the parent of the atom we
+ reenter or the youngest common ancestor).
+ */
+ while (n > p) {
+ cap = eng->f.at(n).capture;
+ if (cap >= 0) {
+ capBegin[cap] = i;
+ capEnd[cap] = EmptyCapture;
+ }
+ n = eng->f.at(n).parent;
+ }
+ /*
+ If the next state was already in
+ nextStack, we must choose carefully which
+ capture zones we want to keep.
+ */
+ if (capBegin == tempCapBegin &&
+ isBetterCapture(ncap, capBegin, capEnd, nextCapBegin + m * ncap,
+ nextCapEnd + m * ncap)) {
+ memcpy(nextCapBegin + m * ncap, capBegin, ncap * sizeof(int));
+ memcpy(nextCapEnd + m * ncap, capEnd, ncap * sizeof(int));
+ }
+ }
+#ifndef QT_NO_REGEXP_BACKREF
+ /*
+ We are done with updating the capture zones.
+ It's now time to put the next state to sleep,
+ if it needs to, and to remove it from
+ nextStack.
+ */
+ if (needSomeSleep > 0) {
+ QVector<int> zzZ(2 + 2 * ncap);
+ zzZ[0] = i + needSomeSleep;
+ zzZ[1] = next;
+ if (ncap > 0) {
+ memcpy(zzZ.data() + 2, capBegin, ncap * sizeof(int));
+ memcpy(zzZ.data() + 2 + ncap, capEnd, ncap * sizeof(int));
+ }
+ inNextStack[nextStack[--nnext]] = -1;
+ sleeping.append(zzZ);
+ }
+#endif
+#endif
+ }
+ }
+ }
+#ifndef QT_NO_REGEXP_CAPTURE
+ /*
+ If we reached the final state, hurray! Copy the captured
+ zone.
+ */
+ if (ncap > 0 && (m = inNextStack[QRegExpEngine::FinalState]) != -1) {
+ memcpy(capBegin, nextCapBegin + m * ncap, ncap * sizeof(int));
+ memcpy(capEnd, nextCapEnd + m * ncap, ncap * sizeof(int));
+ }
+#ifndef QT_NO_REGEXP_BACKREF
+ /*
+ It's time to wake up the sleepers.
+ */
+ j = 0;
+ while (j < sleeping.count()) {
+ if (sleeping.at(j)[0] == i) {
+ const QVector<int> &zzZ = sleeping.at(j);
+ int next = zzZ[1];
+ const int *capBegin = zzZ.data() + 2;
+ const int *capEnd = zzZ.data() + 2 + ncap;
+ bool copyOver = true;
+
+ if ((m = inNextStack[next]) == -1) {
+ m = nnext++;
+ nextStack[m] = next;
+ inNextStack[next] = m;
+ } else {
+ copyOver = isBetterCapture(ncap, nextCapBegin + m * ncap, nextCapEnd + m * ncap,
+ capBegin, capEnd);
+ }
+ if (copyOver) {
+ memcpy(nextCapBegin + m * ncap, capBegin, ncap * sizeof(int));
+ memcpy(nextCapEnd + m * ncap, capEnd, ncap * sizeof(int));
+ }
+
+ sleeping.removeAt(j);
+ } else {
+ ++j;
+ }
+ }
+#endif
+#endif
+ for (j = 0; j < nnext; j++)
+ inNextStack[nextStack[j]] = -1;
+
+ // avoid needless iteration that confuses oneTestMatchedLen
+ if (nnext == 1 && nextStack[0] == QRegExpEngine::FinalState
+#ifndef QT_NO_REGEXP_BACKREF
+ && sleeping.isEmpty()
+#endif
+ )
+ stop = true;
+
+ qSwap(curStack, nextStack);
+#ifndef QT_NO_REGEXP_CAPTURE
+ qSwap(curCapBegin, nextCapBegin);
+ qSwap(curCapEnd, nextCapEnd);
+#endif
+ ncur = nnext;
+ nnext = 0;
+ ++i;
+ }
+
+#ifndef QT_NO_REGEXP_BACKREF
+ /*
+ If minimal matching is enabled, we might have some sleepers
+ left.
+ */
+ if (!sleeping.isEmpty())
+ sleeping.clear();
+#endif
+
+ oneTestMatchedLen = i - 1;
+ return (matchLen >= 0);
+}
+
+#ifndef QT_NO_REGEXP_CCLASS
+
+QRegExpCharClass::QRegExpCharClass()
+ : c(0), n(false)
+{
+#ifndef QT_NO_REGEXP_OPTIM
+ occ1.fill(NoOccurrence, NumBadChars);
+#endif
+}
+
+QRegExpCharClass &QRegExpCharClass::operator=(const QRegExpCharClass &cc)
+{
+ c = cc.c;
+ r = cc.r;
+ n = cc.n;
+#ifndef QT_NO_REGEXP_OPTIM
+ occ1 = cc.occ1;
+#endif
+ return *this;
+}
+
+void QRegExpCharClass::clear()
+{
+ c = 0;
+ r.resize(0);
+ n = false;
+}
+
+void QRegExpCharClass::setNegative(bool negative)
+{
+ n = negative;
+#ifndef QT_NO_REGEXP_OPTIM
+ occ1.fill(0, NumBadChars);
+#endif
+}
+
+void QRegExpCharClass::addCategories(int cats)
+{
+ c |= cats;
+#ifndef QT_NO_REGEXP_OPTIM
+ occ1.fill(0, NumBadChars);
+#endif
+}
+
+void QRegExpCharClass::addRange(ushort from, ushort to)
+{
+ if (from > to)
+ qSwap(from, to);
+ int m = r.size();
+ r.resize(m + 1);
+ r[m].from = from;
+ r[m].len = to - from + 1;
+
+#ifndef QT_NO_REGEXP_OPTIM
+ int i;
+
+ if (to - from < NumBadChars) {
+ if (from % NumBadChars <= to % NumBadChars) {
+ for (i = from % NumBadChars; i <= to % NumBadChars; i++)
+ occ1[i] = 0;
+ } else {
+ for (i = 0; i <= to % NumBadChars; i++)
+ occ1[i] = 0;
+ for (i = from % NumBadChars; i < NumBadChars; i++)
+ occ1[i] = 0;
+ }
+ } else {
+ occ1.fill(0, NumBadChars);
+ }
+#endif
+}
+
+bool QRegExpCharClass::in(QChar ch) const
+{
+#ifndef QT_NO_REGEXP_OPTIM
+ if (occ1.at(BadChar(ch)) == NoOccurrence)
+ return n;
+#endif
+
+ if (c != 0 && (c & (1 << (int)ch.category())) != 0)
+ return !n;
+
+ const int uc = ch.unicode();
+ int size = r.size();
+
+ for (int i = 0; i < size; ++i) {
+ const QRegExpCharClassRange &range = r.at(i);
+ if (uint(uc - range.from) < uint(r.at(i).len))
+ return !n;
+ }
+ return n;
+}
+
+#if defined(QT_DEBUG)
+void QRegExpCharClass::dump() const
+{
+ int i;
+ qDebug(" %stive character class", n ? "nega" : "posi");
+#ifndef QT_NO_REGEXP_CCLASS
+ if (c != 0)
+ qDebug(" categories 0x%.8x", c);
+#endif
+ for (i = 0; i < r.size(); i++)
+ qDebug(" 0x%.4x through 0x%.4x", r[i].from, r[i].from + r[i].len - 1);
+}
+#endif
+#endif
+
+QRegExpEngine::Box::Box(QRegExpEngine *engine)
+ : eng(engine), skipanchors(0)
+#ifndef QT_NO_REGEXP_OPTIM
+ , earlyStart(0), lateStart(0), maxl(0)
+#endif
+{
+#ifndef QT_NO_REGEXP_OPTIM
+ occ1.fill(NoOccurrence, NumBadChars);
+#endif
+ minl = 0;
+}
+
+QRegExpEngine::Box &QRegExpEngine::Box::operator=(const Box &b)
+{
+ eng = b.eng;
+ ls = b.ls;
+ rs = b.rs;
+ lanchors = b.lanchors;
+ ranchors = b.ranchors;
+ skipanchors = b.skipanchors;
+#ifndef QT_NO_REGEXP_OPTIM
+ earlyStart = b.earlyStart;
+ lateStart = b.lateStart;
+ str = b.str;
+ leftStr = b.leftStr;
+ rightStr = b.rightStr;
+ maxl = b.maxl;
+ occ1 = b.occ1;
+#endif
+ minl = b.minl;
+ return *this;
+}
+
+void QRegExpEngine::Box::set(QChar ch)
+{
+ ls.resize(1);
+ ls[0] = eng->createState(ch);
+ rs = ls;
+#ifndef QT_NO_REGEXP_OPTIM
+ str = ch;
+ leftStr = ch;
+ rightStr = ch;
+ maxl = 1;
+ occ1[BadChar(ch)] = 0;
+#endif
+ minl = 1;
+}
+
+void QRegExpEngine::Box::set(const QRegExpCharClass &cc)
+{
+ ls.resize(1);
+ ls[0] = eng->createState(cc);
+ rs = ls;
+#ifndef QT_NO_REGEXP_OPTIM
+ maxl = 1;
+ occ1 = cc.firstOccurrence();
+#endif
+ minl = 1;
+}
+
+#ifndef QT_NO_REGEXP_BACKREF
+void QRegExpEngine::Box::set(int bref)
+{
+ ls.resize(1);
+ ls[0] = eng->createState(bref);
+ rs = ls;
+ if (bref >= 1 && bref <= MaxBackRefs)
+ skipanchors = Anchor_BackRef0Empty << bref;
+#ifndef QT_NO_REGEXP_OPTIM
+ maxl = InftyLen;
+#endif
+ minl = 0;
+}
+#endif
+
+void QRegExpEngine::Box::cat(const Box &b)
+{
+ eng->addCatTransitions(rs, b.ls);
+ addAnchorsToEngine(b);
+ if (minl == 0) {
+ lanchors.unite(b.lanchors);
+ if (skipanchors != 0) {
+ for (int i = 0; i < b.ls.size(); i++) {
+ int a = eng->anchorConcatenation(lanchors.value(b.ls.at(i), 0), skipanchors);
+ lanchors.insert(b.ls.at(i), a);
+ }
+ }
+ mergeInto(&ls, b.ls);
+ }
+ if (b.minl == 0) {
+ ranchors.unite(b.ranchors);
+ if (b.skipanchors != 0) {
+ for (int i = 0; i < rs.size(); i++) {
+ int a = eng->anchorConcatenation(ranchors.value(rs.at(i), 0), b.skipanchors);
+ ranchors.insert(rs.at(i), a);
+ }
+ }
+ mergeInto(&rs, b.rs);
+ } else {
+ ranchors = b.ranchors;
+ rs = b.rs;
+ }
+
+#ifndef QT_NO_REGEXP_OPTIM
+ if (maxl != InftyLen) {
+ if (rightStr.length() + b.leftStr.length() >
+ qMax(str.length(), b.str.length())) {
+ earlyStart = minl - rightStr.length();
+ lateStart = maxl - rightStr.length();
+ str = rightStr + b.leftStr;
+ } else if (b.str.length() > str.length()) {
+ earlyStart = minl + b.earlyStart;
+ lateStart = maxl + b.lateStart;
+ str = b.str;
+ }
+ }
+
+ if (leftStr.length() == maxl)
+ leftStr += b.leftStr;
+
+ if (b.rightStr.length() == b.maxl) {
+ rightStr += b.rightStr;
+ } else {
+ rightStr = b.rightStr;
+ }
+
+ if (maxl == InftyLen || b.maxl == InftyLen) {
+ maxl = InftyLen;
+ } else {
+ maxl += b.maxl;
+ }
+
+ for (int i = 0; i < NumBadChars; i++) {
+ if (b.occ1.at(i) != NoOccurrence && minl + b.occ1.at(i) < occ1.at(i))
+ occ1[i] = minl + b.occ1.at(i);
+ }
+#endif
+
+ minl += b.minl;
+ if (minl == 0)
+ skipanchors = eng->anchorConcatenation(skipanchors, b.skipanchors);
+ else
+ skipanchors = 0;
+}
+
+void QRegExpEngine::Box::orx(const Box &b)
+{
+ mergeInto(&ls, b.ls);
+ lanchors.unite(b.lanchors);
+ mergeInto(&rs, b.rs);
+ ranchors.unite(b.ranchors);
+
+ if (b.minl == 0) {
+ if (minl == 0)
+ skipanchors = eng->anchorAlternation(skipanchors, b.skipanchors);
+ else
+ skipanchors = b.skipanchors;
+ }
+
+#ifndef QT_NO_REGEXP_OPTIM
+ for (int i = 0; i < NumBadChars; i++) {
+ if (occ1.at(i) > b.occ1.at(i))
+ occ1[i] = b.occ1.at(i);
+ }
+ earlyStart = 0;
+ lateStart = 0;
+ str = QString();
+ leftStr = QString();
+ rightStr = QString();
+ if (b.maxl > maxl)
+ maxl = b.maxl;
+#endif
+ if (b.minl < minl)
+ minl = b.minl;
+}
+
+void QRegExpEngine::Box::plus(int atom)
+{
+#ifndef QT_NO_REGEXP_CAPTURE
+ eng->addPlusTransitions(rs, ls, atom);
+#else
+ Q_UNUSED(atom);
+ eng->addCatTransitions(rs, ls);
+#endif
+ addAnchorsToEngine(*this);
+#ifndef QT_NO_REGEXP_OPTIM
+ maxl = InftyLen;
+#endif
+}
+
+void QRegExpEngine::Box::opt()
+{
+#ifndef QT_NO_REGEXP_OPTIM
+ earlyStart = 0;
+ lateStart = 0;
+ str = QString();
+ leftStr = QString();
+ rightStr = QString();
+#endif
+ skipanchors = 0;
+ minl = 0;
+}
+
+void QRegExpEngine::Box::catAnchor(int a)
+{
+ if (a != 0) {
+ for (int i = 0; i < rs.size(); i++) {
+ a = eng->anchorConcatenation(ranchors.value(rs.at(i), 0), a);
+ ranchors.insert(rs.at(i), a);
+ }
+ if (minl == 0)
+ skipanchors = eng->anchorConcatenation(skipanchors, a);
+ }
+}
+
+#ifndef QT_NO_REGEXP_OPTIM
+void QRegExpEngine::Box::setupHeuristics()
+{
+ eng->goodEarlyStart = earlyStart;
+ eng->goodLateStart = lateStart;
+ eng->goodStr = eng->cs ? str : str.toLower();
+
+ eng->minl = minl;
+ if (eng->cs) {
+ /*
+ A regular expression such as 112|1 has occ1['2'] = 2 and minl =
+ 1 at this point. An entry of occ1 has to be at most minl or
+ infinity for the rest of the algorithm to go well.
+
+ We waited until here before normalizing these cases (instead of
+ doing it in Box::orx()) because sometimes things improve by
+ themselves. Consider for example (112|1)34.
+ */
+ for (int i = 0; i < NumBadChars; i++) {
+ if (occ1.at(i) != NoOccurrence && occ1.at(i) >= minl)
+ occ1[i] = minl;
+ }
+ eng->occ1 = occ1;
+ } else {
+ eng->occ1.fill(0, NumBadChars);
+ }
+
+ eng->heuristicallyChooseHeuristic();
+}
+#endif
+
+#if defined(QT_DEBUG)
+void QRegExpEngine::Box::dump() const
+{
+ int i;
+ qDebug("Box of at least %d character%s", minl, minl == 1 ? "" : "s");
+ qDebug(" Left states:");
+ for (i = 0; i < ls.size(); i++) {
+ if (lanchors.value(ls[i], 0) == 0)
+ qDebug(" %d", ls[i]);
+ else
+ qDebug(" %d [anchors 0x%.8x]", ls[i], lanchors[ls[i]]);
+ }
+ qDebug(" Right states:");
+ for (i = 0; i < rs.size(); i++) {
+ if (ranchors.value(rs[i], 0) == 0)
+ qDebug(" %d", rs[i]);
+ else
+ qDebug(" %d [anchors 0x%.8x]", rs[i], ranchors[rs[i]]);
+ }
+ qDebug(" Skip anchors: 0x%.8x", skipanchors);
+}
+#endif
+
+void QRegExpEngine::Box::addAnchorsToEngine(const Box &to) const
+{
+ for (int i = 0; i < to.ls.size(); i++) {
+ for (int j = 0; j < rs.size(); j++) {
+ int a = eng->anchorConcatenation(ranchors.value(rs.at(j), 0),
+ to.lanchors.value(to.ls.at(i), 0));
+ eng->addAnchors(rs[j], to.ls[i], a);
+ }
+ }
+}
+
+int QRegExpEngine::getChar()
+{
+ return (yyPos == yyLen) ? EOS : yyIn[yyPos++].unicode();
+}
+
+int QRegExpEngine::getEscape()
+{
+#ifndef QT_NO_REGEXP_ESCAPE
+ const char tab[] = "afnrtv"; // no b, as \b means word boundary
+ const char backTab[] = "\a\f\n\r\t\v";
+ ushort low;
+ int i;
+#endif
+ ushort val;
+ int prevCh = yyCh;
+
+ if (prevCh == EOS) {
+ error(RXERR_END);
+ return Tok_Char | '\\';
+ }
+ yyCh = getChar();
+#ifndef QT_NO_REGEXP_ESCAPE
+ if ((prevCh & ~0xff) == 0) {
+ const char *p = strchr(tab, prevCh);
+ if (p != 0)
+ return Tok_Char | backTab[p - tab];
+ }
+#endif
+
+ switch (prevCh) {
+#ifndef QT_NO_REGEXP_ESCAPE
+ case '0':
+ val = 0;
+ for (i = 0; i < 3; i++) {
+ if (yyCh >= '0' && yyCh <= '7')
+ val = (val << 3) | (yyCh - '0');
+ else
+ break;
+ yyCh = getChar();
+ }
+ if ((val & ~0377) != 0)
+ error(RXERR_OCTAL);
+ return Tok_Char | val;
+#endif
+#ifndef QT_NO_REGEXP_ESCAPE
+ case 'B':
+ return Tok_NonWord;
+#endif
+#ifndef QT_NO_REGEXP_CCLASS
+ case 'D':
+ // see QChar::isDigit()
+ yyCharClass->addCategories(0x7fffffef);
+ return Tok_CharClass;
+ case 'S':
+ // see QChar::isSpace()
+ yyCharClass->addCategories(0x7ffff87f);
+ yyCharClass->addRange(0x0000, 0x0008);
+ yyCharClass->addRange(0x000e, 0x001f);
+ yyCharClass->addRange(0x007f, 0x009f);
+ return Tok_CharClass;
+ case 'W':
+ // see QChar::isLetterOrNumber() and QChar::isMark()
+ yyCharClass->addCategories(0x7fe07f81);
+ yyCharClass->addRange(0x203f, 0x2040);
+ yyCharClass->addSingleton(0x2040);
+ yyCharClass->addSingleton(0x2054);
+ yyCharClass->addSingleton(0x30fb);
+ yyCharClass->addRange(0xfe33, 0xfe34);
+ yyCharClass->addRange(0xfe4d, 0xfe4f);
+ yyCharClass->addSingleton(0xff3f);
+ yyCharClass->addSingleton(0xff65);
+ return Tok_CharClass;
+#endif
+#ifndef QT_NO_REGEXP_ESCAPE
+ case 'b':
+ return Tok_Word;
+#endif
+#ifndef QT_NO_REGEXP_CCLASS
+ case 'd':
+ // see QChar::isDigit()
+ yyCharClass->addCategories(0x00000010);
+ return Tok_CharClass;
+ case 's':
+ // see QChar::isSpace()
+ yyCharClass->addCategories(0x00000380);
+ yyCharClass->addRange(0x0009, 0x000d);
+ return Tok_CharClass;
+ case 'w':
+ // see QChar::isLetterOrNumber() and QChar::isMark()
+ yyCharClass->addCategories(0x000f807e);
+ yyCharClass->addSingleton(0x005f); // '_'
+ return Tok_CharClass;
+#endif
+#ifndef QT_NO_REGEXP_ESCAPE
+ case 'x':
+ val = 0;
+ for (i = 0; i < 4; i++) {
+ low = QChar(yyCh).toLower().unicode();
+ if (low >= '0' && low <= '9')
+ val = (val << 4) | (low - '0');
+ else if (low >= 'a' && low <= 'f')
+ val = (val << 4) | (low - 'a' + 10);
+ else
+ break;
+ yyCh = getChar();
+ }
+ return Tok_Char | val;
+#endif
+ default:
+ if (prevCh >= '1' && prevCh <= '9') {
+#ifndef QT_NO_REGEXP_BACKREF
+ val = prevCh - '0';
+ while (yyCh >= '0' && yyCh <= '9') {
+ val = (val * 10) + (yyCh - '0');
+ yyCh = getChar();
+ }
+ return Tok_BackRef | val;
+#else
+ error(RXERR_DISABLED);
+#endif
+ }
+ return Tok_Char | prevCh;
+ }
+}
+
+#ifndef QT_NO_REGEXP_INTERVAL
+int QRegExpEngine::getRep(int def)
+{
+ if (yyCh >= '0' && yyCh <= '9') {
+ int rep = 0;
+ do {
+ rep = 10 * rep + yyCh - '0';
+ if (rep >= InftyRep) {
+ error(RXERR_REPETITION);
+ rep = def;
+ }
+ yyCh = getChar();
+ } while (yyCh >= '0' && yyCh <= '9');
+ return rep;
+ } else {
+ return def;
+ }
+}
+#endif
+
+#ifndef QT_NO_REGEXP_LOOKAHEAD
+void QRegExpEngine::skipChars(int n)
+{
+ if (n > 0) {
+ yyPos += n - 1;
+ yyCh = getChar();
+ }
+}
+#endif
+
+void QRegExpEngine::error(const char *msg)
+{
+ if (yyError.isEmpty())
+ yyError = QLatin1String(msg);
+}
+
+void QRegExpEngine::startTokenizer(const QChar *rx, int len)
+{
+ yyIn = rx;
+ yyPos0 = 0;
+ yyPos = 0;
+ yyLen = len;
+ yyCh = getChar();
+ yyCharClass = new QRegExpCharClass;
+ yyMinRep = 0;
+ yyMaxRep = 0;
+ yyError = QString();
+}
+
+int QRegExpEngine::getToken()
+{
+#ifndef QT_NO_REGEXP_CCLASS
+ ushort pendingCh = 0;
+ bool charPending;
+ bool rangePending;
+ int tok;
+#endif
+ int prevCh = yyCh;
+
+ yyPos0 = yyPos - 1;
+#ifndef QT_NO_REGEXP_CCLASS
+ yyCharClass->clear();
+#endif
+ yyMinRep = 0;
+ yyMaxRep = 0;
+ yyCh = getChar();
+
+ switch (prevCh) {
+ case EOS:
+ yyPos0 = yyPos;
+ return Tok_Eos;
+ case '$':
+ return Tok_Dollar;
+ case '(':
+ if (yyCh == '?') {
+ prevCh = getChar();
+ yyCh = getChar();
+ switch (prevCh) {
+#ifndef QT_NO_REGEXP_LOOKAHEAD
+ case '!':
+ return Tok_NegLookahead;
+ case '=':
+ return Tok_PosLookahead;
+#endif
+ case ':':
+ return Tok_MagicLeftParen;
+ default:
+ error(RXERR_LOOKAHEAD);
+ return Tok_MagicLeftParen;
+ }
+ } else {
+ return Tok_LeftParen;
+ }
+ case ')':
+ return Tok_RightParen;
+ case '*':
+ yyMinRep = 0;
+ yyMaxRep = InftyRep;
+ return Tok_Quantifier;
+ case '+':
+ yyMinRep = 1;
+ yyMaxRep = InftyRep;
+ return Tok_Quantifier;
+ case '.':
+#ifndef QT_NO_REGEXP_CCLASS
+ yyCharClass->setNegative(true);
+#endif
+ return Tok_CharClass;
+ case '?':
+ yyMinRep = 0;
+ yyMaxRep = 1;
+ return Tok_Quantifier;
+ case '[':
+#ifndef QT_NO_REGEXP_CCLASS
+ if (yyCh == '^') {
+ yyCharClass->setNegative(true);
+ yyCh = getChar();
+ }
+ charPending = false;
+ rangePending = false;
+ do {
+ if (yyCh == '-' && charPending && !rangePending) {
+ rangePending = true;
+ yyCh = getChar();
+ } else {
+ if (charPending && !rangePending) {
+ yyCharClass->addSingleton(pendingCh);
+ charPending = false;
+ }
+ if (yyCh == '\\') {
+ yyCh = getChar();
+ tok = getEscape();
+ if (tok == Tok_Word)
+ tok = '\b';
+ } else {
+ tok = Tok_Char | yyCh;
+ yyCh = getChar();
+ }
+ if (tok == Tok_CharClass) {
+ if (rangePending) {
+ yyCharClass->addSingleton('-');
+ yyCharClass->addSingleton(pendingCh);
+ charPending = false;
+ rangePending = false;
+ }
+ } else if ((tok & Tok_Char) != 0) {
+ if (rangePending) {
+ yyCharClass->addRange(pendingCh, tok ^ Tok_Char);
+ charPending = false;
+ rangePending = false;
+ } else {
+ pendingCh = tok ^ Tok_Char;
+ charPending = true;
+ }
+ } else {
+ error(RXERR_CHARCLASS);
+ }
+ }
+ } while (yyCh != ']' && yyCh != EOS);
+ if (rangePending)
+ yyCharClass->addSingleton('-');
+ if (charPending)
+ yyCharClass->addSingleton(pendingCh);
+ if (yyCh == EOS)
+ error(RXERR_END);
+ else
+ yyCh = getChar();
+ return Tok_CharClass;
+#else
+ error(RXERR_END);
+ return Tok_Char | '[';
+#endif
+ case '\\':
+ return getEscape();
+ case ']':
+ error(RXERR_LEFTDELIM);
+ return Tok_Char | ']';
+ case '^':
+ return Tok_Caret;
+ case '{':
+#ifndef QT_NO_REGEXP_INTERVAL
+ yyMinRep = getRep(0);
+ yyMaxRep = yyMinRep;
+ if (yyCh == ',') {
+ yyCh = getChar();
+ yyMaxRep = getRep(InftyRep);
+ }
+ if (yyMaxRep < yyMinRep)
+ qSwap(yyMinRep, yyMaxRep);
+ if (yyCh != '}')
+ error(RXERR_REPETITION);
+ yyCh = getChar();
+ return Tok_Quantifier;
+#else
+ error(RXERR_DISABLED);
+ return Tok_Char | '{';
+#endif
+ case '|':
+ return Tok_Bar;
+ case '}':
+ error(RXERR_LEFTDELIM);
+ return Tok_Char | '}';
+ default:
+ return Tok_Char | prevCh;
+ }
+}
+
+int QRegExpEngine::parse(const QChar *pattern, int len)
+{
+ valid = true;
+ startTokenizer(pattern, len);
+ yyTok = getToken();
+#ifndef QT_NO_REGEXP_CAPTURE
+ yyMayCapture = true;
+#else
+ yyMayCapture = false;
+#endif
+
+#ifndef QT_NO_REGEXP_CAPTURE
+ int atom = startAtom(false);
+#endif
+ QRegExpCharClass anything;
+ Box box(this); // create InitialState
+ box.set(anything);
+ Box rightBox(this); // create FinalState
+ rightBox.set(anything);
+
+ Box middleBox(this);
+ parseExpression(&middleBox);
+#ifndef QT_NO_REGEXP_CAPTURE
+ finishAtom(atom, false);
+#endif
+#ifndef QT_NO_REGEXP_OPTIM
+ middleBox.setupHeuristics();
+#endif
+ box.cat(middleBox);
+ box.cat(rightBox);
+ delete yyCharClass;
+ yyCharClass = 0;
+
+#ifndef QT_NO_REGEXP_CAPTURE
+ for (int i = 0; i < nf; ++i) {
+ switch (f[i].capture) {
+ case QRegExpAtom::NoCapture:
+ break;
+ case QRegExpAtom::OfficialCapture:
+ f[i].capture = ncap;
+ captureForOfficialCapture.append(ncap);
+ ++ncap;
+ ++officialncap;
+ break;
+ case QRegExpAtom::UnofficialCapture:
+ f[i].capture = greedyQuantifiers ? ncap++ : QRegExpAtom::NoCapture;
+ }
+ }
+
+#ifndef QT_NO_REGEXP_BACKREF
+#ifndef QT_NO_REGEXP_OPTIM
+ if (officialncap == 0 && nbrefs == 0) {
+ ncap = nf = 0;
+ f.clear();
+ }
+#endif
+ // handle the case where there's a \5 with no corresponding capture
+ // (captureForOfficialCapture.size() != officialncap)
+ for (int i = 0; i < nbrefs - officialncap; ++i) {
+ captureForOfficialCapture.append(ncap);
+ ++ncap;
+ }
+#endif
+#endif
+
+ if (!yyError.isEmpty())
+ return -1;
+
+#ifndef QT_NO_REGEXP_OPTIM
+ const QRegExpAutomatonState &sinit = s.at(InitialState);
+ caretAnchored = !sinit.anchors.isEmpty();
+ if (caretAnchored) {
+ const QMap<int, int> &anchors = sinit.anchors;
+ QMap<int, int>::const_iterator a;
+ for (a = anchors.constBegin(); a != anchors.constEnd(); ++a) {
+ if (
+#ifndef QT_NO_REGEXP_ANCHOR_ALT
+ (*a & Anchor_Alternation) != 0 ||
+#endif
+ (*a & Anchor_Caret) == 0)
+ {
+ caretAnchored = false;
+ break;
+ }
+ }
+ }
+#endif
+
+ // cleanup anchors
+ int numStates = s.count();
+ for (int i = 0; i < numStates; ++i) {
+ QRegExpAutomatonState &state = s[i];
+ if (!state.anchors.isEmpty()) {
+ QMap<int, int>::iterator a = state.anchors.begin();
+ while (a != state.anchors.end()) {
+ if (a.value() == 0)
+ a = state.anchors.erase(a);
+ else
+ ++a;
+ }
+ }
+ }
+
+ return yyPos0;
+}
+
+void QRegExpEngine::parseAtom(Box *box)
+{
+#ifndef QT_NO_REGEXP_LOOKAHEAD
+ QRegExpEngine *eng = 0;
+ bool neg;
+ int len;
+#endif
+
+ if ((yyTok & Tok_Char) != 0) {
+ box->set(QChar(yyTok ^ Tok_Char));
+ } else {
+#ifndef QT_NO_REGEXP_OPTIM
+ trivial = false;
+#endif
+ switch (yyTok) {
+ case Tok_Dollar:
+ box->catAnchor(Anchor_Dollar);
+ break;
+ case Tok_Caret:
+ box->catAnchor(Anchor_Caret);
+ break;
+#ifndef QT_NO_REGEXP_LOOKAHEAD
+ case Tok_PosLookahead:
+ case Tok_NegLookahead:
+ neg = (yyTok == Tok_NegLookahead);
+ eng = new QRegExpEngine(cs, greedyQuantifiers);
+ len = eng->parse(yyIn + yyPos - 1, yyLen - yyPos + 1);
+ if (len >= 0)
+ skipChars(len);
+ else
+ error(RXERR_LOOKAHEAD);
+ box->catAnchor(addLookahead(eng, neg));
+ yyTok = getToken();
+ if (yyTok != Tok_RightParen)
+ error(RXERR_LOOKAHEAD);
+ break;
+#endif
+#ifndef QT_NO_REGEXP_ESCAPE
+ case Tok_Word:
+ box->catAnchor(Anchor_Word);
+ break;
+ case Tok_NonWord:
+ box->catAnchor(Anchor_NonWord);
+ break;
+#endif
+ case Tok_LeftParen:
+ case Tok_MagicLeftParen:
+ yyTok = getToken();
+ parseExpression(box);
+ if (yyTok != Tok_RightParen)
+ error(RXERR_END);
+ break;
+ case Tok_CharClass:
+ box->set(*yyCharClass);
+ break;
+ case Tok_Quantifier:
+ error(RXERR_REPETITION);
+ break;
+ default:
+#ifndef QT_NO_REGEXP_BACKREF
+ if ((yyTok & Tok_BackRef) != 0)
+ box->set(yyTok ^ Tok_BackRef);
+ else
+#endif
+ error(RXERR_DISABLED);
+ }
+ }
+ yyTok = getToken();
+}
+
+void QRegExpEngine::parseFactor(Box *box)
+{
+#ifndef QT_NO_REGEXP_CAPTURE
+ int outerAtom = greedyQuantifiers ? startAtom(false) : -1;
+ int innerAtom = startAtom(yyMayCapture && yyTok == Tok_LeftParen);
+ bool magicLeftParen = (yyTok == Tok_MagicLeftParen);
+#else
+ const int innerAtom = -1;
+#endif
+
+#ifndef QT_NO_REGEXP_INTERVAL
+#define YYREDO() \
+ yyIn = in, yyPos0 = pos0, yyPos = pos, yyLen = len, yyCh = ch, \
+ *yyCharClass = charClass, yyMinRep = 0, yyMaxRep = 0, yyTok = tok
+
+ const QChar *in = yyIn;
+ int pos0 = yyPos0;
+ int pos = yyPos;
+ int len = yyLen;
+ int ch = yyCh;
+ QRegExpCharClass charClass;
+ if (yyTok == Tok_CharClass)
+ charClass = *yyCharClass;
+ int tok = yyTok;
+ bool mayCapture = yyMayCapture;
+#endif
+
+ parseAtom(box);
+#ifndef QT_NO_REGEXP_CAPTURE
+ finishAtom(innerAtom, magicLeftParen);
+#endif
+
+ bool hasQuantifier = (yyTok == Tok_Quantifier);
+ if (hasQuantifier) {
+#ifndef QT_NO_REGEXP_OPTIM
+ trivial = false;
+#endif
+ if (yyMaxRep == InftyRep) {
+ box->plus(innerAtom);
+#ifndef QT_NO_REGEXP_INTERVAL
+ } else if (yyMaxRep == 0) {
+ box->clear();
+#endif
+ }
+ if (yyMinRep == 0)
+ box->opt();
+
+#ifndef QT_NO_REGEXP_INTERVAL
+ yyMayCapture = false;
+ int alpha = (yyMinRep == 0) ? 0 : yyMinRep - 1;
+ int beta = (yyMaxRep == InftyRep) ? 0 : yyMaxRep - (alpha + 1);
+
+ Box rightBox(this);
+ int i;
+
+ for (i = 0; i < beta; i++) {
+ YYREDO();
+ Box leftBox(this);
+ parseAtom(&leftBox);
+ leftBox.cat(rightBox);
+ leftBox.opt();
+ rightBox = leftBox;
+ }
+ for (i = 0; i < alpha; i++) {
+ YYREDO();
+ Box leftBox(this);
+ parseAtom(&leftBox);
+ leftBox.cat(rightBox);
+ rightBox = leftBox;
+ }
+ rightBox.cat(*box);
+ *box = rightBox;
+#endif
+ yyTok = getToken();
+#ifndef QT_NO_REGEXP_INTERVAL
+ yyMayCapture = mayCapture;
+#endif
+ }
+#undef YYREDO
+#ifndef QT_NO_REGEXP_CAPTURE
+ if (greedyQuantifiers)
+ finishAtom(outerAtom, hasQuantifier);
+#endif
+}
+
+void QRegExpEngine::parseTerm(Box *box)
+{
+#ifndef QT_NO_REGEXP_OPTIM
+ if (yyTok != Tok_Eos && yyTok != Tok_RightParen && yyTok != Tok_Bar)
+ parseFactor(box);
+#endif
+ while (yyTok != Tok_Eos && yyTok != Tok_RightParen && yyTok != Tok_Bar) {
+ Box rightBox(this);
+ parseFactor(&rightBox);
+ box->cat(rightBox);
+ }
+}
+
+void QRegExpEngine::parseExpression(Box *box)
+{
+ parseTerm(box);
+ while (yyTok == Tok_Bar) {
+#ifndef QT_NO_REGEXP_OPTIM
+ trivial = false;
+#endif
+ Box rightBox(this);
+ yyTok = getToken();
+ parseTerm(&rightBox);
+ box->orx(rightBox);
+ }
+}
+
+/*
+ The struct QRegExpPrivate contains the private data of a regular
+ expression other than the automaton. It makes it possible for many
+ QRegExp objects to use the same QRegExpEngine object with different
+ QRegExpPrivate objects.
+*/
+struct QRegExpPrivate
+{
+ QRegExpEngine *eng;
+ QRegExpEngineKey engineKey;
+ bool minimal;
+#ifndef QT_NO_REGEXP_CAPTURE
+ QString t; // last string passed to QRegExp::indexIn() or lastIndexIn()
+ QStringList capturedCache; // what QRegExp::capturedTexts() returned last
+#endif
+ QRegExpMatchState matchState;
+
+ inline QRegExpPrivate()
+ : eng(0), engineKey(QString(), QRegExp::RegExp, Qt::CaseSensitive), minimal(false) { }
+ inline QRegExpPrivate(const QRegExpEngineKey &key)
+ : eng(0), engineKey(key), minimal(false) {}
+};
+
+#if !defined(QT_NO_REGEXP_OPTIM)
+uint qHash(const QRegExpEngineKey &key)
+{
+ return qHash(key.pattern);
+}
+
+typedef QCache<QRegExpEngineKey, QRegExpEngine> EngineCache;
+Q_GLOBAL_STATIC(EngineCache, globalEngineCache)
+Q_GLOBAL_STATIC(QMutex, mutex)
+#endif // QT_NO_REGEXP_OPTIM
+
+static void derefEngine(QRegExpEngine *eng, const QRegExpEngineKey &key)
+{
+ if (!eng->ref.deref()) {
+#if !defined(QT_NO_REGEXP_OPTIM)
+ if (globalEngineCache()) {
+ QMutexLocker locker(mutex());
+ globalEngineCache()->insert(key, eng, 4 + key.pattern.length() / 4);
+ }
+ else
+ delete eng;
+#else
+ Q_UNUSED(key);
+ delete eng;
+#endif
+ }
+}
+
+static void prepareEngine_helper(QRegExpPrivate *priv)
+{
+ bool initMatchState = !priv->eng;
+#if !defined(QT_NO_REGEXP_OPTIM)
+ if (!priv->eng) {
+ QMutexLocker locker(mutex());
+ priv->eng = globalEngineCache()->take(priv->engineKey);
+ if (priv->eng != 0)
+ priv->eng->ref.ref();
+ }
+#endif // QT_NO_REGEXP_OPTIM
+
+ if (!priv->eng)
+ priv->eng = new QRegExpEngine(priv->engineKey);
+
+ if (initMatchState)
+ priv->matchState.prepareForMatch(priv->eng);
+}
+
+inline static void prepareEngine(QRegExpPrivate *priv)
+{
+ if (priv->eng)
+ return;
+ prepareEngine_helper(priv);
+}
+
+static void prepareEngineForMatch(QRegExpPrivate *priv, const QString &str)
+{
+ prepareEngine(priv);
+ priv->matchState.prepareForMatch(priv->eng);
+#ifndef QT_NO_REGEXP_CAPTURE
+ priv->t = str;
+ priv->capturedCache.clear();
+#else
+ Q_UNUSED(str);
+#endif
+}
+
+static void invalidateEngine(QRegExpPrivate *priv)
+{
+ if (priv->eng != 0) {
+ derefEngine(priv->eng, priv->engineKey);
+ priv->eng = 0;
+ priv->matchState.drain();
+ }
+}
+
+/*!
+ \enum QRegExp::CaretMode
+
+ The CaretMode enum defines the different meanings of the caret
+ (\bold{^}) in a regular expression. The possible values are:
+
+ \value CaretAtZero
+ The caret corresponds to index 0 in the searched string.
+
+ \value CaretAtOffset
+ The caret corresponds to the start offset of the search.
+
+ \value CaretWontMatch
+ The caret never matches.
+*/
+
+/*!
+ \enum QRegExp::PatternSyntax
+
+ The syntax used to interpret the meaning of the pattern.
+
+ \value RegExp A rich Perl-like pattern matching syntax. This is
+ the default.
+
+ \value RegExp2 Like RegExp, but with \l{greedy quantifiers}. This
+ will be the default in Qt 5. (Introduced in Qt 4.2.)
+
+ \value Wildcard This provides a simple pattern matching syntax
+ similar to that used by shells (command interpreters) for "file
+ globbing". See \l{Wildcard Matching}.
+
+ \value FixedString The pattern is a fixed string. This is
+ equivalent to using the RegExp pattern on a string in
+ which all metacharacters are escaped using escape().
+
+ \sa setPatternSyntax()
+*/
+
+/*!
+ Constructs an empty regexp.
+
+ \sa isValid(), errorString()
+*/
+QRegExp::QRegExp()
+{
+ priv = new QRegExpPrivate;
+}
+
+/*!
+ Constructs a regular expression object for the given \a pattern
+ string. The pattern must be given using wildcard notation if \a
+ syntax is \l Wildcard; the default is \l RegExp. The pattern is
+ case sensitive, unless \a cs is Qt::CaseInsensitive. Matching is
+ greedy (maximal), but can be changed by calling
+ setMinimal().
+
+ \sa setPattern(), setCaseSensitivity(), setPatternSyntax()
+*/
+QRegExp::QRegExp(const QString &pattern, Qt::CaseSensitivity cs, PatternSyntax syntax)
+{
+ priv = new QRegExpPrivate(QRegExpEngineKey(pattern, syntax, cs));
+}
+
+/*!
+ Constructs a regular expression as a copy of \a rx.
+
+ \sa operator=()
+*/
+QRegExp::QRegExp(const QRegExp &rx)
+{
+ priv = new QRegExpPrivate;
+ operator=(rx);
+}
+
+/*!
+ Destroys the regular expression and cleans up its internal data.
+*/
+QRegExp::~QRegExp()
+{
+ invalidateEngine(priv);
+ delete priv;
+}
+
+/*!
+ Copies the regular expression \a rx and returns a reference to the
+ copy. The case sensitivity, wildcard, and minimal matching options
+ are also copied.
+*/
+QRegExp &QRegExp::operator=(const QRegExp &rx)
+{
+ prepareEngine(rx.priv); // to allow sharing
+ QRegExpEngine *otherEng = rx.priv->eng;
+ if (otherEng)
+ otherEng->ref.ref();
+ invalidateEngine(priv);
+ priv->eng = otherEng;
+ priv->engineKey = rx.priv->engineKey;
+ priv->minimal = rx.priv->minimal;
+#ifndef QT_NO_REGEXP_CAPTURE
+ priv->t = rx.priv->t;
+ priv->capturedCache = rx.priv->capturedCache;
+#endif
+ if (priv->eng)
+ priv->matchState.prepareForMatch(priv->eng);
+ priv->matchState.captured = rx.priv->matchState.captured;
+ return *this;
+}
+
+/*!
+ Returns true if this regular expression is equal to \a rx;
+ otherwise returns false.
+
+ Two QRegExp objects are equal if they have the same pattern
+ strings and the same settings for case sensitivity, wildcard and
+ minimal matching.
+*/
+bool QRegExp::operator==(const QRegExp &rx) const
+{
+ return priv->engineKey == rx.priv->engineKey && priv->minimal == rx.priv->minimal;
+}
+
+/*!
+ \fn bool QRegExp::operator!=(const QRegExp &rx) const
+
+ Returns true if this regular expression is not equal to \a rx;
+ otherwise returns false.
+
+ \sa operator==()
+*/
+
+/*!
+ Returns true if the pattern string is empty; otherwise returns
+ false.
+
+ If you call exactMatch() with an empty pattern on an empty string
+ it will return true; otherwise it returns false since it operates
+ over the whole string. If you call indexIn() with an empty pattern
+ on \e any string it will return the start offset (0 by default)
+ because the empty pattern matches the 'emptiness' at the start of
+ the string. In this case the length of the match returned by
+ matchedLength() will be 0.
+
+ See QString::isEmpty().
+*/
+
+bool QRegExp::isEmpty() const
+{
+ return priv->engineKey.pattern.isEmpty();
+}
+
+/*!
+ Returns true if the regular expression is valid; otherwise returns
+ false. An invalid regular expression never matches.
+
+ The pattern \bold{[a-z} is an example of an invalid pattern, since
+ it lacks a closing square bracket.
+
+ Note that the validity of a regexp may also depend on the setting
+ of the wildcard flag, for example \bold{*.html} is a valid
+ wildcard regexp but an invalid full regexp.
+
+ \sa errorString()
+*/
+bool QRegExp::isValid() const
+{
+ if (priv->engineKey.pattern.isEmpty()) {
+ return true;
+ } else {
+ prepareEngine(priv);
+ return priv->eng->isValid();
+ }
+}
+
+/*!
+ Returns the pattern string of the regular expression. The pattern
+ has either regular expression syntax or wildcard syntax, depending
+ on patternSyntax().
+
+ \sa patternSyntax(), caseSensitivity()
+*/
+QString QRegExp::pattern() const
+{
+ return priv->engineKey.pattern;
+}
+
+/*!
+ Sets the pattern string to \a pattern. The case sensitivity,
+ wildcard, and minimal matching options are not changed.
+
+ \sa setPatternSyntax(), setCaseSensitivity()
+*/
+void QRegExp::setPattern(const QString &pattern)
+{
+ if (priv->engineKey.pattern != pattern) {
+ invalidateEngine(priv);
+ priv->engineKey.pattern = pattern;
+ }
+}
+
+/*!
+ Returns Qt::CaseSensitive if the regexp is matched case
+ sensitively; otherwise returns Qt::CaseInsensitive.
+
+ \sa patternSyntax(), pattern(), isMinimal()
+*/
+Qt::CaseSensitivity QRegExp::caseSensitivity() const
+{
+ return priv->engineKey.cs;
+}
+
+/*!
+ Sets case sensitive matching to \a cs.
+
+ If \a cs is Qt::CaseSensitive, \bold{\\.txt$} matches
+ \c{readme.txt} but not \c{README.TXT}.
+
+ \sa setPatternSyntax(), setPattern(), setMinimal()
+*/
+void QRegExp::setCaseSensitivity(Qt::CaseSensitivity cs)
+{
+ if ((bool)cs != (bool)priv->engineKey.cs) {
+ invalidateEngine(priv);
+ priv->engineKey.cs = cs;
+ }
+}
+
+/*!
+ Returns the syntax used by the regular expression. The default is
+ QRegExp::RegExp.
+
+ \sa pattern(), caseSensitivity()
+*/
+QRegExp::PatternSyntax QRegExp::patternSyntax() const
+{
+ return priv->engineKey.patternSyntax;
+}
+
+/*!
+ Sets the syntax mode for the regular expression. The default is
+ QRegExp::RegExp.
+
+ Setting \a syntax to QRegExp::Wildcard enables simple shell-like
+ \l{wildcard matching}. For example, \bold{r*.txt} matches the
+ string \c{readme.txt} in wildcard mode, but does not match
+ \c{readme}.
+
+ Setting \a syntax to QRegExp::FixedString means that the pattern
+ is interpreted as a plain string. Special characters (e.g.,
+ backslash) don't need to be escaped then.
+
+ \sa setPattern(), setCaseSensitivity(), escape()
+*/
+void QRegExp::setPatternSyntax(PatternSyntax syntax)
+{
+ if (syntax != priv->engineKey.patternSyntax) {
+ invalidateEngine(priv);
+ priv->engineKey.patternSyntax = syntax;
+ }
+}
+
+/*!
+ Returns true if minimal (non-greedy) matching is enabled;
+ otherwise returns false.
+
+ \sa caseSensitivity(), setMinimal()
+*/
+bool QRegExp::isMinimal() const
+{
+ return priv->minimal;
+}
+
+/*!
+ Enables or disables minimal matching. If \a minimal is false,
+ matching is greedy (maximal) which is the default.
+
+ For example, suppose we have the input string "We must be
+ <b>bold</b>, very <b>bold</b>!" and the pattern
+ \bold{<b>.*</b>}. With the default greedy (maximal) matching,
+ the match is "We must be \underline{<b>bold</b>, very
+ <b>bold</b>}!". But with minimal (non-greedy) matching, the
+ first match is: "We must be \underline{<b>bold</b>}, very
+ <b>bold</b>!" and the second match is "We must be <b>bold</b>,
+ very \underline{<b>bold</b>}!". In practice we might use the pattern
+ \bold{<b>[^<]*\</b>} instead, although this will still fail for
+ nested tags.
+
+ \sa setCaseSensitivity()
+*/
+void QRegExp::setMinimal(bool minimal)
+{
+ priv->minimal = minimal;
+}
+
+// ### Qt 5: make non-const
+/*!
+ Returns true if \a str is matched exactly by this regular
+ expression; otherwise returns false. You can determine how much of
+ the string was matched by calling matchedLength().
+
+ For a given regexp string R, exactMatch("R") is the equivalent of
+ indexIn("^R$") since exactMatch() effectively encloses the regexp
+ in the start of string and end of string anchors, except that it
+ sets matchedLength() differently.
+
+ For example, if the regular expression is \bold{blue}, then
+ exactMatch() returns true only for input \c blue. For inputs \c
+ bluebell, \c blutak and \c lightblue, exactMatch() returns false
+ and matchedLength() will return 4, 3 and 0 respectively.
+
+ Although const, this function sets matchedLength(),
+ capturedTexts(), and pos().
+
+ \sa indexIn(), lastIndexIn()
+*/
+bool QRegExp::exactMatch(const QString &str) const
+{
+ prepareEngineForMatch(priv, str);
+ priv->matchState.match(str.unicode(), str.length(), 0, priv->minimal, true, 0);
+ if (priv->matchState.captured[1] == str.length()) {
+ return true;
+ } else {
+ priv->matchState.captured[0] = 0;
+ priv->matchState.captured[1] = priv->matchState.oneTestMatchedLen;
+ return false;
+ }
+}
+
+// ### Qt 5: make non-const
+/*!
+ Attempts to find a match in \a str from position \a offset (0 by
+ default). If \a offset is -1, the search starts at the last
+ character; if -2, at the next to last character; etc.
+
+ Returns the position of the first match, or -1 if there was no
+ match.
+
+ The \a caretMode parameter can be used to instruct whether \bold{^}
+ should match at index 0 or at \a offset.
+
+ You might prefer to use QString::indexOf(), QString::contains(),
+ or even QStringList::filter(). To replace matches use
+ QString::replace().
+
+ Example:
+ \snippet doc/src/snippets/code/src_corelib_tools_qregexp.cpp 13
+
+ Although const, this function sets matchedLength(),
+ capturedTexts() and pos().
+
+ If the QRegExp is a wildcard expression (see setPatternSyntax())
+ and want to test a string against the whole wildcard expression,
+ use exactMatch() instead of this function.
+
+ \sa lastIndexIn(), exactMatch()
+*/
+
+int QRegExp::indexIn(const QString &str, int offset, CaretMode caretMode) const
+{
+ prepareEngineForMatch(priv, str);
+ if (offset < 0)
+ offset += str.length();
+ priv->matchState.match(str.unicode(), str.length(), offset,
+ priv->minimal, false, caretIndex(offset, caretMode));
+ return priv->matchState.captured[0];
+}
+
+// ### Qt 5: make non-const
+/*!
+ Attempts to find a match backwards in \a str from position \a
+ offset. If \a offset is -1 (the default), the search starts at the
+ last character; if -2, at the next to last character; etc.
+
+ Returns the position of the first match, or -1 if there was no
+ match.
+
+ The \a caretMode parameter can be used to instruct whether \bold{^}
+ should match at index 0 or at \a offset.
+
+ Although const, this function sets matchedLength(),
+ capturedTexts() and pos().
+
+ \warning Searching backwards is much slower than searching
+ forwards.
+
+ \sa indexIn(), exactMatch()
+*/
+
+int QRegExp::lastIndexIn(const QString &str, int offset, CaretMode caretMode) const
+{
+ prepareEngineForMatch(priv, str);
+ if (offset < 0)
+ offset += str.length();
+ if (offset < 0 || offset > str.length()) {
+ memset(priv->matchState.captured, -1, priv->matchState.capturedSize*sizeof(int));
+ return -1;
+ }
+
+ while (offset >= 0) {
+ priv->matchState.match(str.unicode(), str.length(), offset,
+ priv->minimal, true, caretIndex(offset, caretMode));
+ if (priv->matchState.captured[0] == offset)
+ return offset;
+ --offset;
+ }
+ return -1;
+}
+
+/*!
+ Returns the length of the last matched string, or -1 if there was
+ no match.
+
+ \sa exactMatch(), indexIn(), lastIndexIn()
+*/
+int QRegExp::matchedLength() const
+{
+ return priv->matchState.captured[1];
+}
+
+#ifndef QT_NO_REGEXP_CAPTURE
+/*!
+ Returns the number of captures contained in the regular expression.
+ */
+int QRegExp::numCaptures() const
+{
+ prepareEngine(priv);
+ return priv->eng->numCaptures();
+}
+
+/*!
+ Returns a list of the captured text strings.
+
+ The first string in the list is the entire matched string. Each
+ subsequent list element contains a string that matched a
+ (capturing) subexpression of the regexp.
+
+ For example:
+ \snippet doc/src/snippets/code/src_corelib_tools_qregexp.cpp 14
+
+ The above example also captures elements that may be present but
+ which we have no interest in. This problem can be solved by using
+ non-capturing parentheses:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qregexp.cpp 15
+
+ Note that if you want to iterate over the list, you should iterate
+ over a copy, e.g.
+ \snippet doc/src/snippets/code/src_corelib_tools_qregexp.cpp 16
+
+ Some regexps can match an indeterminate number of times. For
+ example if the input string is "Offsets: 12 14 99 231 7" and the
+ regexp, \c{rx}, is \bold{(\\d+)+}, we would hope to get a list of
+ all the numbers matched. However, after calling
+ \c{rx.indexIn(str)}, capturedTexts() will return the list ("12",
+ "12"), i.e. the entire match was "12" and the first subexpression
+ matched was "12". The correct approach is to use cap() in a
+ \l{QRegExp#cap_in_a_loop}{loop}.
+
+ The order of elements in the string list is as follows. The first
+ element is the entire matching string. Each subsequent element
+ corresponds to the next capturing open left parentheses. Thus
+ capturedTexts()[1] is the text of the first capturing parentheses,
+ capturedTexts()[2] is the text of the second and so on
+ (corresponding to $1, $2, etc., in some other regexp languages).
+
+ \sa cap(), pos()
+*/
+QStringList QRegExp::capturedTexts() const
+{
+ if (priv->capturedCache.isEmpty()) {
+ prepareEngine(priv);
+ const int *captured = priv->matchState.captured;
+ int n = priv->matchState.capturedSize;
+
+ for (int i = 0; i < n; i += 2) {
+ QString m;
+ if (captured[i + 1] == 0)
+ m = QLatin1String(""); // ### Qt 5: don't distinguish between null and empty
+ else if (captured[i] >= 0)
+ m = priv->t.mid(captured[i], captured[i + 1]);
+ priv->capturedCache.append(m);
+ }
+ priv->t.clear();
+ }
+ return priv->capturedCache;
+}
+
+/*!
+ \internal
+*/
+QStringList QRegExp::capturedTexts()
+{
+ return const_cast<const QRegExp *>(this)->capturedTexts();
+}
+
+/*!
+ Returns the text captured by the \a nth subexpression. The entire
+ match has index 0 and the parenthesized subexpressions have
+ indexes starting from 1 (excluding non-capturing parentheses).
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qregexp.cpp 17
+
+ The order of elements matched by cap() is as follows. The first
+ element, cap(0), is the entire matching string. Each subsequent
+ element corresponds to the next capturing open left parentheses.
+ Thus cap(1) is the text of the first capturing parentheses, cap(2)
+ is the text of the second, and so on.
+
+ \sa capturedTexts(), pos()
+*/
+QString QRegExp::cap(int nth) const
+{
+ return capturedTexts().value(nth);
+}
+
+/*!
+ \internal
+*/
+QString QRegExp::cap(int nth)
+{
+ return const_cast<const QRegExp *>(this)->cap(nth);
+}
+
+/*!
+ Returns the position of the \a nth captured text in the searched
+ string. If \a nth is 0 (the default), pos() returns the position
+ of the whole match.
+
+ Example:
+ \snippet doc/src/snippets/code/src_corelib_tools_qregexp.cpp 18
+
+ For zero-length matches, pos() always returns -1. (For example, if
+ cap(4) would return an empty string, pos(4) returns -1.) This is
+ a feature of the implementation.
+
+ \sa cap(), capturedTexts()
+*/
+int QRegExp::pos(int nth) const
+{
+ if (nth < 0 || nth >= priv->matchState.capturedSize / 2)
+ return -1;
+ else
+ return priv->matchState.captured[2 * nth];
+}
+
+/*!
+ \internal
+*/
+int QRegExp::pos(int nth)
+{
+ return const_cast<const QRegExp *>(this)->pos(nth);
+}
+
+/*!
+ Returns a text string that explains why a regexp pattern is
+ invalid the case being; otherwise returns "no error occurred".
+
+ \sa isValid()
+*/
+QString QRegExp::errorString() const
+{
+ if (isValid()) {
+ return QString::fromLatin1(RXERR_OK);
+ } else {
+ return priv->eng->errorString();
+ }
+}
+
+/*!
+ \internal
+*/
+QString QRegExp::errorString()
+{
+ return const_cast<const QRegExp *>(this)->errorString();
+}
+#endif
+
+/*!
+ Returns the string \a str with every regexp special character
+ escaped with a backslash. The special characters are $, (,), *, +,
+ ., ?, [, \,], ^, {, | and }.
+
+ Example:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qregexp.cpp 19
+
+ This function is useful to construct regexp patterns dynamically:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qregexp.cpp 20
+
+ \sa setPatternSyntax()
+*/
+QString QRegExp::escape(const QString &str)
+{
+ QString quoted;
+ const int count = str.count();
+ quoted.reserve(count * 2);
+ const QLatin1Char backslash('\\');
+ for (int i = 0; i < count; i++) {
+ switch (str.at(i).toLatin1()) {
+ case '$':
+ case '(':
+ case ')':
+ case '*':
+ case '+':
+ case '.':
+ case '?':
+ case '[':
+ case '\\':
+ case ']':
+ case '^':
+ case '{':
+ case '|':
+ case '}':
+ quoted.append(backslash);
+ }
+ quoted.append(str.at(i));
+ }
+ return quoted;
+}
+
+/*!
+ \fn bool QRegExp::caseSensitive() const
+
+ Use \l caseSensitivity() instead.
+*/
+
+/*!
+ \fn void QRegExp::setCaseSensitive(bool sensitive)
+
+ Use \l setCaseSensitivity() instead.
+*/
+
+/*!
+ \fn bool QRegExp::wildcard() const
+
+ Use \l patternSyntax() instead.
+
+ \oldcode
+ bool wc = rx.wildcard();
+ \newcode
+ bool wc = (rx.patternSyntax() == QRegExp::Wildcard);
+ \endcode
+*/
+
+/*!
+ \fn void QRegExp::setWildcard(bool wildcard)
+
+ Use \l setPatternSyntax() instead.
+
+ \oldcode
+ rx.setWildcard(wc);
+ \newcode
+ rx.setPatternSyntax(wc ? QRegExp::Wildcard : QRegExp::RegExp);
+ \endcode
+*/
+
+/*!
+ \fn bool QRegExp::minimal() const
+
+ Use \l isMinimal() instead.
+*/
+
+/*!
+ \fn int QRegExp::search(const QString &str, int from = 0,
+ CaretMode caretMode = CaretAtZero) const
+
+ Use \l indexIn() instead.
+*/
+
+/*!
+ \fn int QRegExp::searchRev(const QString &str, int from = -1, \
+ CaretMode caretMode = CaretAtZero) const
+
+ Use \l lastIndexIn() instead.
+*/
+
+/*!
+ \fn QRegExp::QRegExp(const QString &pattern, bool cs, bool wildcard = false)
+
+ Use another constructor instead.
+
+ \oldcode
+ QRegExp rx("*.txt", false, true);
+ \newcode
+ QRegExp rx("*.txt", Qt::CaseInsensitive, QRegExp::Wildcard);
+ \endcode
+*/
+
+#ifndef QT_NO_DATASTREAM
+/*!
+ \relates QRegExp
+
+ Writes the regular expression \a regExp to stream \a out.
+
+ \sa {Format of the QDataStream Operators}
+*/
+QDataStream &operator<<(QDataStream &out, const QRegExp &regExp)
+{
+ return out << regExp.pattern() << (quint8)regExp.caseSensitivity()
+ << (quint8)regExp.patternSyntax()
+ << (quint8)!!regExp.isMinimal();
+}
+
+/*!
+ \relates QRegExp
+
+ Reads a regular expression from stream \a in into \a regExp.
+
+ \sa {Format of the QDataStream Operators}
+*/
+QDataStream &operator>>(QDataStream &in, QRegExp &regExp)
+{
+ QString pattern;
+ quint8 cs;
+ quint8 patternSyntax;
+ quint8 isMinimal;
+
+ in >> pattern >> cs >> patternSyntax >> isMinimal;
+
+ QRegExp newRegExp(pattern, Qt::CaseSensitivity(cs),
+ QRegExp::PatternSyntax(patternSyntax));
+
+ newRegExp.setMinimal(isMinimal);
+ regExp = newRegExp;
+ return in;
+}
+#endif
+
+QT_END_NAMESPACE
diff --git a/src/corelib/tools/qregexp.h b/src/corelib/tools/qregexp.h
new file mode 100644
index 0000000000..b387e23f35
--- /dev/null
+++ b/src/corelib/tools/qregexp.h
@@ -0,0 +1,155 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QREGEXP_H
+#define QREGEXP_H
+
+#ifndef QT_NO_REGEXP
+
+#include <QtCore/qstring.h>
+#ifdef QT3_SUPPORT
+#include <new>
+#endif
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Core)
+
+struct QRegExpPrivate;
+class QStringList;
+
+class Q_CORE_EXPORT QRegExp
+{
+public:
+ enum PatternSyntax { RegExp, Wildcard, FixedString, RegExp2 };
+ enum CaretMode { CaretAtZero, CaretAtOffset, CaretWontMatch };
+
+ QRegExp();
+ explicit QRegExp(const QString &pattern, Qt::CaseSensitivity cs = Qt::CaseSensitive,
+ PatternSyntax syntax = RegExp);
+ QRegExp(const QRegExp &rx);
+ ~QRegExp();
+ QRegExp &operator=(const QRegExp &rx);
+
+ bool operator==(const QRegExp &rx) const;
+ inline bool operator!=(const QRegExp &rx) const { return !operator==(rx); }
+
+ bool isEmpty() const;
+ bool isValid() const;
+ QString pattern() const;
+ void setPattern(const QString &pattern);
+ Qt::CaseSensitivity caseSensitivity() const;
+ void setCaseSensitivity(Qt::CaseSensitivity cs);
+#ifdef QT3_SUPPORT
+ inline QT3_SUPPORT bool caseSensitive() const { return caseSensitivity() == Qt::CaseSensitive; }
+ inline QT3_SUPPORT void setCaseSensitive(bool sensitive)
+ { setCaseSensitivity(sensitive ? Qt::CaseSensitive : Qt::CaseInsensitive); }
+#endif
+ PatternSyntax patternSyntax() const;
+ void setPatternSyntax(PatternSyntax syntax);
+#ifdef QT3_SUPPORT
+ inline QT3_SUPPORT bool wildcard() const { return patternSyntax() == Wildcard; }
+ inline QT3_SUPPORT void setWildcard(bool aWildcard)
+ { setPatternSyntax(aWildcard ? Wildcard : RegExp); }
+#endif
+
+ bool isMinimal() const;
+ void setMinimal(bool minimal);
+#ifdef QT3_SUPPORT
+ inline QT3_SUPPORT bool minimal() const { return isMinimal(); }
+#endif
+
+ bool exactMatch(const QString &str) const;
+
+ int indexIn(const QString &str, int offset = 0, CaretMode caretMode = CaretAtZero) const;
+ int lastIndexIn(const QString &str, int offset = -1, CaretMode caretMode = CaretAtZero) const;
+#ifdef QT3_SUPPORT
+ inline QT3_SUPPORT int search(const QString &str, int from = 0,
+ CaretMode caretMode = CaretAtZero) const
+ { return indexIn(str, from, caretMode); }
+ inline QT3_SUPPORT int searchRev(const QString &str, int from = -1,
+ CaretMode caretMode = CaretAtZero) const
+ { return lastIndexIn(str, from, caretMode); }
+#endif
+ int matchedLength() const;
+#ifndef QT_NO_REGEXP_CAPTURE
+ int numCaptures() const;
+ QStringList capturedTexts() const;
+ QStringList capturedTexts();
+ QString cap(int nth = 0) const;
+ QString cap(int nth = 0);
+ int pos(int nth = 0) const;
+ int pos(int nth = 0);
+ QString errorString() const;
+ QString errorString();
+#endif
+
+ static QString escape(const QString &str);
+
+#ifdef QT3_SUPPORT
+ inline QT3_SUPPORT_CONSTRUCTOR QRegExp(const QString &aPattern, bool cs, bool aWildcard = false)
+ {
+ new (this)
+ QRegExp(aPattern, cs ? Qt::CaseSensitive : Qt::CaseInsensitive,
+ aWildcard ? Wildcard : RegExp);
+ }
+#endif
+
+private:
+ QRegExpPrivate *priv;
+};
+
+Q_DECLARE_TYPEINFO(QRegExp, Q_MOVABLE_TYPE);
+
+#ifndef QT_NO_DATASTREAM
+Q_CORE_EXPORT QDataStream &operator<<(QDataStream &out, const QRegExp &regExp);
+Q_CORE_EXPORT QDataStream &operator>>(QDataStream &in, QRegExp &regExp);
+#endif
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QT_NO_REGEXP
+
+#endif // QREGEXP_H
diff --git a/src/corelib/tools/qringbuffer_p.h b/src/corelib/tools/qringbuffer_p.h
new file mode 100644
index 0000000000..3a0901d62e
--- /dev/null
+++ b/src/corelib/tools/qringbuffer_p.h
@@ -0,0 +1,319 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QRINGBUFFER_P_H
+#define QRINGBUFFER_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of a number of Qt sources files. This header file may change from
+// version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/qbytearray.h>
+#include <QtCore/qlist.h>
+
+QT_BEGIN_NAMESPACE
+
+class Q_CORE_EXPORT QRingBuffer
+{
+public:
+ inline QRingBuffer(int growth = 4096) : basicBlockSize(growth) {
+ buffers << QByteArray();
+ clear();
+ }
+
+ inline int nextDataBlockSize() const {
+ return (tailBuffer == 0 ? tail : buffers.first().size()) - head;
+ }
+
+ inline const char *readPointer() const {
+ return buffers.isEmpty() ? 0 : (buffers.first().constData() + head);
+ }
+
+ inline void free(int bytes) {
+ bufferSize -= bytes;
+ if (bufferSize < 0)
+ bufferSize = 0;
+
+ for (;;) {
+ int nextBlockSize = nextDataBlockSize();
+ if (bytes < nextBlockSize) {
+ head += bytes;
+ if (head == tail && tailBuffer == 0)
+ head = tail = 0;
+ break;
+ }
+
+ bytes -= nextBlockSize;
+ if (buffers.count() == 1) {
+ if (buffers.at(0).size() != basicBlockSize)
+ buffers[0].resize(basicBlockSize);
+ head = tail = 0;
+ tailBuffer = 0;
+ break;
+ }
+
+ buffers.removeAt(0);
+ --tailBuffer;
+ head = 0;
+ }
+ }
+
+ inline char *reserve(int bytes) {
+ bufferSize += bytes;
+
+ // if there is already enough space, simply return.
+ if (tail + bytes <= buffers.at(tailBuffer).size()) {
+ char *writePtr = buffers[tailBuffer].data() + tail;
+ tail += bytes;
+ return writePtr;
+ }
+
+ // if our buffer isn't half full yet, simply resize it.
+ if (tail < buffers.at(tailBuffer).size() / 2) {
+ buffers[tailBuffer].resize(tail + bytes);
+ char *writePtr = buffers[tailBuffer].data() + tail;
+ tail += bytes;
+ return writePtr;
+ }
+
+ // shrink this buffer to its current size
+ buffers[tailBuffer].resize(tail);
+
+ // create a new QByteArray with the right size
+ buffers << QByteArray();
+ ++tailBuffer;
+ buffers[tailBuffer].resize(qMax(basicBlockSize, bytes));
+ tail = bytes;
+ return buffers[tailBuffer].data();
+ }
+
+ inline void truncate(int pos) {
+ if (pos < size())
+ chop(size() - pos);
+ }
+
+ inline void chop(int bytes) {
+ bufferSize -= bytes;
+ if (bufferSize < 0)
+ bufferSize = 0;
+
+ for (;;) {
+ // special case: head and tail are in the same buffer
+ if (tailBuffer == 0) {
+ tail -= bytes;
+ if (tail <= head)
+ tail = head = 0;
+ return;
+ }
+
+ if (bytes <= tail) {
+ tail -= bytes;
+ return;
+ }
+
+ bytes -= tail;
+ buffers.removeAt(tailBuffer);
+
+ --tailBuffer;
+ tail = buffers.at(tailBuffer).size();
+ }
+ }
+
+ inline bool isEmpty() const {
+ return tailBuffer == 0 && tail == 0;
+ }
+
+ inline int getChar() {
+ if (isEmpty())
+ return -1;
+ char c = *readPointer();
+ free(1);
+ return int(uchar(c));
+ }
+
+ inline void putChar(char c) {
+ char *ptr = reserve(1);
+ *ptr = c;
+ }
+
+ inline void ungetChar(char c) {
+ --head;
+ if (head < 0) {
+ buffers.prepend(QByteArray());
+ buffers[0].resize(basicBlockSize);
+ head = basicBlockSize - 1;
+ ++tailBuffer;
+ }
+ buffers[0][head] = c;
+ ++bufferSize;
+ }
+
+ inline int size() const {
+ return bufferSize;
+ }
+
+ inline void clear() {
+ if(!buffers.isEmpty()) {
+ QByteArray tmp = buffers[0];
+ buffers.clear();
+ buffers << tmp;
+ if (buffers.at(0).size() != basicBlockSize)
+ buffers[0].resize(basicBlockSize);
+ }
+ head = tail = 0;
+ tailBuffer = 0;
+ bufferSize = 0;
+ }
+
+ inline int indexOf(char c) const {
+ int index = 0;
+ for (int i = 0; i < buffers.size(); ++i) {
+ int start = 0;
+ int end = buffers.at(i).size();
+
+ if (i == 0)
+ start = head;
+ if (i == tailBuffer)
+ end = tail;
+ const char *ptr = buffers.at(i).data() + start;
+ for (int j = start; j < end; ++j) {
+ if (*ptr++ == c)
+ return index;
+ ++index;
+ }
+ }
+ return -1;
+ }
+
+ inline int read(char *data, int maxLength) {
+ int bytesToRead = qMin(size(), maxLength);
+ int readSoFar = 0;
+ while (readSoFar < bytesToRead) {
+ const char *ptr = readPointer();
+ int bytesToReadFromThisBlock = qMin(bytesToRead - readSoFar, nextDataBlockSize());
+ if (data)
+ memcpy(data + readSoFar, ptr, bytesToReadFromThisBlock);
+ readSoFar += bytesToReadFromThisBlock;
+ free(bytesToReadFromThisBlock);
+ }
+ return readSoFar;
+ }
+
+ inline QByteArray read(int maxLength) {
+ QByteArray tmp;
+ tmp.resize(qMin(maxLength, size()));
+ read(tmp.data(), tmp.size());
+ return tmp;
+ }
+
+ inline QByteArray readAll() {
+ return read(size());
+ }
+
+ inline QByteArray peek(int maxLength) const {
+ int bytesToRead = qMin(size(), maxLength);
+ if(maxLength <= 0)
+ return QByteArray();
+ QByteArray ret;
+ ret.resize(bytesToRead);
+ int readSoFar = 0;
+ for (int i = 0; readSoFar < bytesToRead && i < buffers.size(); ++i) {
+ int start = 0;
+ int end = buffers.at(i).size();
+ if (i == 0)
+ start = head;
+ if (i == tailBuffer)
+ end = tail;
+ const int len = qMin(ret.size()-readSoFar, end-start);
+ memcpy(ret.data()+readSoFar, buffers.at(i).constData()+start, len);
+ readSoFar += len;
+ }
+ Q_ASSERT(readSoFar == ret.size());
+ return ret;
+ }
+
+ inline int skip(int length) {
+ return read(0, length);
+ }
+
+ inline int readLine(char *data, int maxLength) {
+ int index = indexOf('\n');
+ if (index == -1)
+ return read(data, maxLength);
+ if (maxLength <= 0)
+ return -1;
+
+ int readSoFar = 0;
+ while (readSoFar < index + 1 && readSoFar < maxLength - 1) {
+ int bytesToRead = qMin((index + 1) - readSoFar, nextDataBlockSize());
+ bytesToRead = qMin(bytesToRead, (maxLength - 1) - readSoFar);
+ memcpy(data + readSoFar, readPointer(), bytesToRead);
+ readSoFar += bytesToRead;
+ free(bytesToRead);
+ }
+
+ // Terminate it.
+ data[readSoFar] = '\0';
+ return readSoFar;
+ }
+
+ inline bool canReadLine() const {
+ return indexOf('\n') != -1;
+ }
+
+private:
+ QList<QByteArray> buffers;
+ int head, tail;
+ int tailBuffer;
+ int basicBlockSize;
+ int bufferSize;
+};
+
+QT_END_NAMESPACE
+
+#endif // QRINGBUFFER_P_H
diff --git a/src/corelib/tools/qset.h b/src/corelib/tools/qset.h
new file mode 100644
index 0000000000..4b19adc2d2
--- /dev/null
+++ b/src/corelib/tools/qset.h
@@ -0,0 +1,352 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSET_H
+#define QSET_H
+
+#include <QtCore/qhash.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Core)
+
+template <class T>
+class QSet
+{
+ typedef QHash<T, QHashDummyValue> Hash;
+
+public:
+ inline QSet() {}
+ inline QSet(const QSet<T> &other) : q_hash(other.q_hash) {}
+
+ inline QSet<T> &operator=(const QSet<T> &other)
+ { q_hash = other.q_hash; return *this; }
+
+ inline bool operator==(const QSet<T> &other) const
+ { return q_hash == other.q_hash; }
+ inline bool operator!=(const QSet<T> &other) const
+ { return q_hash != other.q_hash; }
+
+ inline int size() const { return q_hash.size(); }
+
+ inline bool isEmpty() const { return q_hash.isEmpty(); }
+
+ inline int capacity() const { return q_hash.capacity(); }
+ inline void reserve(int size);
+ inline void squeeze() { q_hash.squeeze(); }
+
+ inline void detach() { q_hash.detach(); }
+ inline bool isDetached() const { return q_hash.isDetached(); }
+ inline void setSharable(bool sharable) { q_hash.setSharable(sharable); }
+
+ inline void clear() { q_hash.clear(); }
+
+ inline bool remove(const T &value) { return q_hash.remove(value) != 0; }
+
+ inline bool contains(const T &value) const { return q_hash.contains(value); }
+
+ class const_iterator;
+
+ class iterator
+ {
+ typedef QHash<T, QHashDummyValue> Hash;
+ typename Hash::iterator i;
+ friend class const_iterator;
+
+ public:
+ typedef std::bidirectional_iterator_tag iterator_category;
+ typedef ptrdiff_t difference_type;
+ typedef T value_type;
+ typedef const T *pointer;
+ typedef const T &reference;
+
+ inline iterator() {}
+ inline iterator(typename Hash::iterator o) : i(o) {}
+ inline iterator(const iterator &o) : i(o.i) {}
+ inline iterator &operator=(const iterator &o) { i = o.i; return *this; }
+ inline const T &operator*() const { return i.key(); }
+ inline const T *operator->() const { return &i.key(); }
+ inline bool operator==(const iterator &o) const { return i == o.i; }
+ inline bool operator!=(const iterator &o) const { return i != o.i; }
+ inline bool operator==(const const_iterator &o) const
+ { return i == o.i; }
+ inline bool operator!=(const const_iterator &o) const
+ { return i != o.i; }
+ inline iterator &operator++() { ++i; return *this; }
+ inline iterator operator++(int) { iterator r = *this; ++i; return r; }
+ inline iterator &operator--() { --i; return *this; }
+ inline iterator operator--(int) { iterator r = *this; --i; return r; }
+ inline iterator operator+(int j) const { return i + j; }
+ inline iterator operator-(int j) const { return i - j; }
+ inline iterator &operator+=(int j) { i += j; return *this; }
+ inline iterator &operator-=(int j) { i -= j; return *this; }
+ };
+
+ class const_iterator
+ {
+ typedef QHash<T, QHashDummyValue> Hash;
+ typename Hash::const_iterator i;
+ friend class iterator;
+
+ public:
+ typedef std::bidirectional_iterator_tag iterator_category;
+ typedef ptrdiff_t difference_type;
+ typedef T value_type;
+ typedef const T *pointer;
+ typedef const T &reference;
+
+ inline const_iterator() {}
+ inline const_iterator(typename Hash::const_iterator o) : i(o) {}
+ inline const_iterator(const const_iterator &o) : i(o.i) {}
+ inline const_iterator(const iterator &o)
+ : i(o.i) {}
+ inline const_iterator &operator=(const const_iterator &o) { i = o.i; return *this; }
+ inline const T &operator*() const { return i.key(); }
+ inline const T *operator->() const { return &i.key(); }
+ inline bool operator==(const const_iterator &o) const { return i == o.i; }
+ inline bool operator!=(const const_iterator &o) const { return i != o.i; }
+ inline const_iterator &operator++() { ++i; return *this; }
+ inline const_iterator operator++(int) { const_iterator r = *this; ++i; return r; }
+ inline const_iterator &operator--() { --i; return *this; }
+ inline const_iterator operator--(int) { const_iterator r = *this; --i; return r; }
+ inline const_iterator operator+(int j) const { return i + j; }
+ inline const_iterator operator-(int j) const { return i - j; }
+ inline const_iterator &operator+=(int j) { i += j; return *this; }
+ inline const_iterator &operator-=(int j) { i -= j; return *this; }
+ };
+
+ // STL style
+ inline iterator begin() { return q_hash.begin(); }
+ inline const_iterator begin() const { return q_hash.begin(); }
+ inline const_iterator constBegin() const { return q_hash.constBegin(); }
+ inline iterator end() { return q_hash.end(); }
+ inline const_iterator end() const { return q_hash.end(); }
+ inline const_iterator constEnd() const { return q_hash.constEnd(); }
+ iterator erase(iterator i)
+ { return q_hash.erase(reinterpret_cast<typename Hash::iterator &>(i)); }
+
+ // more Qt
+ typedef iterator Iterator;
+ typedef const_iterator ConstIterator;
+ inline int count() const { return q_hash.count(); }
+ inline const_iterator insert(const T &value) // ### Qt 5: should return an 'iterator'
+ { return static_cast<typename Hash::const_iterator>(q_hash.insert(value,
+ QHashDummyValue())); }
+ iterator find(const T &value) { return q_hash.find(value); }
+ const_iterator find(const T &value) const { return q_hash.find(value); }
+ inline const_iterator constFind(const T &value) const { return find(value); }
+ QSet<T> &unite(const QSet<T> &other);
+ QSet<T> &intersect(const QSet<T> &other);
+ QSet<T> &subtract(const QSet<T> &other);
+
+ // STL compatibility
+ typedef T key_type;
+ typedef T value_type;
+ typedef value_type *pointer;
+ typedef const value_type *const_pointer;
+ typedef value_type &reference;
+ typedef const value_type &const_reference;
+ typedef ptrdiff_t difference_type;
+ typedef int size_type;
+
+ inline bool empty() const { return isEmpty(); }
+
+ // comfort
+ inline QSet<T> &operator<<(const T &value) { insert(value); return *this; }
+ inline QSet<T> &operator|=(const QSet<T> &other) { unite(other); return *this; }
+ inline QSet<T> &operator|=(const T &value) { insert(value); return *this; }
+ inline QSet<T> &operator&=(const QSet<T> &other) { intersect(other); return *this; }
+ inline QSet<T> &operator&=(const T &value)
+ { QSet<T> result; if (contains(value)) result.insert(value); return (*this = result); }
+ inline QSet<T> &operator+=(const QSet<T> &other) { unite(other); return *this; }
+ inline QSet<T> &operator+=(const T &value) { insert(value); return *this; }
+ inline QSet<T> &operator-=(const QSet<T> &other) { subtract(other); return *this; }
+ inline QSet<T> &operator-=(const T &value) { remove(value); return *this; }
+ inline QSet<T> operator|(const QSet<T> &other) const
+ { QSet<T> result = *this; result |= other; return result; }
+ inline QSet<T> operator&(const QSet<T> &other) const
+ { QSet<T> result = *this; result &= other; return result; }
+ inline QSet<T> operator+(const QSet<T> &other) const
+ { QSet<T> result = *this; result += other; return result; }
+ inline QSet<T> operator-(const QSet<T> &other) const
+ { QSet<T> result = *this; result -= other; return result; }
+#if QT_VERSION < 0x050000
+ // ### Qt 5: remove
+ inline QSet<T> operator|(const QSet<T> &other)
+ { QSet<T> result = *this; result |= other; return result; }
+ inline QSet<T> operator&(const QSet<T> &other)
+ { QSet<T> result = *this; result &= other; return result; }
+ inline QSet<T> operator+(const QSet<T> &other)
+ { QSet<T> result = *this; result += other; return result; }
+ inline QSet<T> operator-(const QSet<T> &other)
+ { QSet<T> result = *this; result -= other; return result; }
+#endif
+
+ QList<T> toList() const;
+ inline QList<T> values() const { return toList(); }
+
+ static QSet<T> fromList(const QList<T> &list);
+
+private:
+ Hash q_hash;
+};
+
+template <class T>
+Q_INLINE_TEMPLATE void QSet<T>::reserve(int asize) { q_hash.reserve(asize); }
+
+template <class T>
+Q_INLINE_TEMPLATE QSet<T> &QSet<T>::unite(const QSet<T> &other)
+{
+ QSet<T> copy(other);
+ typename QSet<T>::const_iterator i = copy.constEnd();
+ while (i != copy.constBegin()) {
+ --i;
+ insert(*i);
+ }
+ return *this;
+}
+
+template <class T>
+Q_INLINE_TEMPLATE QSet<T> &QSet<T>::intersect(const QSet<T> &other)
+{
+ QSet<T> copy1(*this);
+ QSet<T> copy2(other);
+ typename QSet<T>::const_iterator i = copy1.constEnd();
+ while (i != copy1.constBegin()) {
+ --i;
+ if (!copy2.contains(*i))
+ remove(*i);
+ }
+ return *this;
+}
+
+template <class T>
+Q_INLINE_TEMPLATE QSet<T> &QSet<T>::subtract(const QSet<T> &other)
+{
+ QSet<T> copy1(*this);
+ QSet<T> copy2(other);
+ typename QSet<T>::const_iterator i = copy1.constEnd();
+ while (i != copy1.constBegin()) {
+ --i;
+ if (copy2.contains(*i))
+ remove(*i);
+ }
+ return *this;
+}
+
+template <typename T>
+Q_OUTOFLINE_TEMPLATE QList<T> QSet<T>::toList() const
+{
+ QList<T> result;
+ typename QSet<T>::const_iterator i = constBegin();
+ while (i != constEnd()) {
+ result.append(*i);
+ ++i;
+ }
+ return result;
+}
+
+template <typename T>
+Q_OUTOFLINE_TEMPLATE QSet<T> QList<T>::toSet() const
+{
+ QSet<T> result;
+ result.reserve(size());
+ for (int i = 0; i < size(); ++i)
+ result.insert(at(i));
+ return result;
+}
+
+template <typename T>
+QSet<T> QSet<T>::fromList(const QList<T> &list)
+{
+ return list.toSet();
+}
+
+template <typename T>
+QList<T> QList<T>::fromSet(const QSet<T> &set)
+{
+ return set.toList();
+}
+
+Q_DECLARE_SEQUENTIAL_ITERATOR(Set)
+
+template <typename T>
+class QMutableSetIterator
+{
+ typedef typename QSet<T>::iterator iterator;
+ QSet<T> *c;
+ iterator i, n;
+ inline bool item_exists() const { return n != c->constEnd(); }
+
+public:
+ inline QMutableSetIterator(QSet<T> &container)
+ : c(&container)
+ { c->setSharable(false); i = c->begin(); n = c->end(); }
+ inline ~QMutableSetIterator()
+ { c->setSharable(true); }
+ inline QMutableSetIterator &operator=(QSet<T> &container)
+ { c->setSharable(true); c = &container; c->setSharable(false);
+ i = c->begin(); n = c->end(); return *this; }
+ inline void toFront() { i = c->begin(); n = c->end(); }
+ inline void toBack() { i = c->end(); n = i; }
+ inline bool hasNext() const { return c->constEnd() != i; }
+ inline const T &next() { n = i++; return *n; }
+ inline const T &peekNext() const { return *i; }
+ inline bool hasPrevious() const { return c->constBegin() != i; }
+ inline const T &previous() { n = --i; return *n; }
+ inline const T &peekPrevious() const { iterator p = i; return *--p; }
+ inline void remove()
+ { if (c->constEnd() != n) { i = c->erase(n); n = c->end(); } }
+ inline const T &value() const { Q_ASSERT(item_exists()); return *n; }
+ inline bool findNext(const T &t)
+ { while (c->constEnd() != (n = i)) if (*i++ == t) return true; return false; }
+ inline bool findPrevious(const T &t)
+ { while (c->constBegin() != i) if (*(n = --i) == t) return true;
+ n = c->end(); return false; }
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QSET_H
diff --git a/src/corelib/tools/qshareddata.cpp b/src/corelib/tools/qshareddata.cpp
new file mode 100644
index 0000000000..2b879ea7e4
--- /dev/null
+++ b/src/corelib/tools/qshareddata.cpp
@@ -0,0 +1,550 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qshareddata.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QSharedData
+ \brief The QSharedData class is a base class for shared data objects.
+ \reentrant
+ \ingroup misc
+
+ QSharedData is designed to be used with QSharedDataPointer or
+ QExplicitlySharedDataPointer to implement custom \l{implicitly
+ shared} or \l {explicitly shared} classes. QSharedData provides
+ \l{thread-safe} reference counting.
+
+ See QSharedDataPointer and QExplicitlySharedDataPointer for details.
+*/
+
+/*! \fn QSharedData::QSharedData()
+ Constructs a QSharedData object with a reference count of 0.
+*/
+
+/*! \fn QSharedData::QSharedData(const QSharedData& other)
+ Constructs a QSharedData object with reference count 0.
+ \a other is ignored.
+*/
+
+/*!
+ \class QSharedDataPointer
+ \brief The QSharedDataPointer class represents a pointer to an implicitly shared object.
+ \since 4.0
+ \reentrant
+ \ingroup misc
+ \mainclass
+
+ QSharedDataPointer\<T\> makes writing your own \l {implicitly
+ shared} classes easy. QSharedDataPointer implements \l {thread-safe}
+ reference counting, ensuring that adding QSharedDataPointers to your
+ \l {reentrant} classes won't make them non-reentrant.
+
+ \l {Implicit sharing} is used by many Qt classes to combine the
+ speed and memory efficiency of pointers with the ease of use of
+ classes. See the \l{Shared Classes} page for more information.
+
+ \target Employee example
+ Suppose you want to make an \c Employee class implicitly shared. The
+ procedure is:
+
+ \list
+
+ \o Define the class \c Employee to have a single data member of
+ type \c {QSharedDataPointer<EmployeeData>}.
+
+ \o Define the \c EmployeeData class derived from \l QSharedData to
+ contain all the data members you would normally have put in the
+ \c Employee class.
+
+ \endlist
+
+ To show this in practice, we review the source code for the
+ implicitly shared \c Employee class. In the header file we define the
+ two classes \c Employee and \c EmployeeData.
+
+ \snippet doc/src/snippets/sharedemployee/employee.h 0
+
+ In class \c Employee, note the single data member, a \e {d pointer}
+ of type \c {QSharedDataPointer<EmployeeData>}. All accesses of
+ employee data must go through the \e {d pointer's} \c
+ {operator->()}. For write accesses, \c {operator->()} will
+ automatically call detach(), which creates a copy of the shared data
+ object if the shared data object's reference count is greater than
+ 1. This ensures that writes to one \c Employee object don't affect
+ any other \c Employee objects that share the same \c EmployeeData
+ object.
+
+ Class \c EmployeeData inherits QSharedData, which provides the
+ \e{behind the scenes} reference counter. \c EmployeeData has a default
+ constructor, a copy constructor, and a destructor. Normally, trivial
+ implementations of these are all that is needed in the \e {data}
+ class for an implicitly shared class.
+
+ Implementing the two constructors for class \c Employee is also
+ straightforward. Both create a new instance of \c EmployeeData
+ and assign it to the \e{d pointer} .
+
+ \snippet doc/src/snippets/sharedemployee/employee.h 1
+ \codeline
+ \snippet doc/src/snippets/sharedemployee/employee.h 2
+
+ Note that class \c Employee also has a trivial copy constructor
+ defined, which is not strictly required in this case.
+
+ \snippet doc/src/snippets/sharedemployee/employee.h 7
+
+ The copy constructor is not strictly required here, because class \c
+ EmployeeData is included in the same file as class \c Employee
+ (\c{employee.h}). However, including the private subclass of
+ QSharedData in the same file as the public class containing the
+ QSharedDataPointer is not typical. Normally, the idea is to hide the
+ private subclass of QSharedData from the user by putting it in a
+ separate file which would not be included in the public file. In
+ this case, we would normally put class \c EmployeeData in a separate
+ file, which would \e{not} be included in \c{employee.h}. Instead, we
+ would just predeclare the private subclass \c EmployeeData in \c
+ {employee.h} this way:
+
+ \code
+ class EmployeeData;
+ \endcode
+
+ If we had done it that way here, the copy constructor shown would be
+ required. Since the copy constructor is trivial, you might as well
+ just always include it.
+
+ Behind the scenes, QSharedDataPointer automatically increments the
+ reference count whenever an \c Employee object is copied, assigned,
+ or passed as a parameter. It decrements the reference count whenever
+ an \c Employee object is deleted or goes out of scope. The shared
+ \c EmployeeData object is deleted automatically if and when the
+ reference count reaches 0.
+
+ In a non-const member function of \c Employee, whenever the \e {d
+ pointer} is dereferenced, QSharedDataPointer automatically calls
+ detach() to ensure that the function operates on its own copy of the
+ data.
+
+ \snippet doc/src/snippets/sharedemployee/employee.h 3
+ \codeline
+ \snippet doc/src/snippets/sharedemployee/employee.h 4
+
+ Note that if detach() is called more than once in a member function
+ due to multiple dereferences of the \e {d pointer}, detach() will
+ only create a copy of the shared data the first time it is called,
+ if at all, because on the second and subsequent calls of detach(),
+ the reference count will be 1 again.
+
+ But note that in the second \c Employee constructor, which takes an
+ employee ID and a name, both setId() and setName() are called, but
+ they don't cause \e{copy on write}, because the reference count for
+ the newly constructed \c EmployeeData object has just been set to 1.
+
+ In \c Employee's \e const member functions, dereferencing the \e {d
+ pointer} does \e not cause detach() to be called.
+
+ \snippet doc/src/snippets/sharedemployee/employee.h 5
+ \codeline
+ \snippet doc/src/snippets/sharedemployee/employee.h 6
+
+ Notice that there is no need to implement a copy constructor or an
+ assignment operator for the \c Employee class, because the copy
+ constructor and assignment operator provided by the C++ compiler
+ will do the \e{member by member} shallow copy required. The only
+ member to copy is the \e {d pointer}, which is a QSharedDataPointer,
+ whose \c {operator=()} just increments the reference count of the
+ shared \c EmployeeData object.
+
+ \target Implicit vs Explicit Sharing
+ \section1 Implicit vs Explicit Sharing
+
+ Implicit sharing might not be right for the \c Employee class.
+ Consider a simple example that creates two instances of the
+ implicitly shared \c Employee class.
+
+ \snippet doc/src/snippets/sharedemployee/main.cpp 0
+
+ After the second employee e2 is created and e1 is assigned to it,
+ both \c e1 and \c e2 refer to Albrecht Durer, employee 1001. Both \c
+ Employee objects point to the same instance of \c EmployeeData,
+ which has reference count 2. Then \c {e1.setName("Hans Holbein")} is
+ called to change the employee name, but because the reference count
+ is greater than 1, a \e{copy on write} is performed before the name
+ is changed. Now \c e1 and \c e2 point to different \c EmployeeData
+ objects. They have different names, but both have ID 1001, which is
+ probably not what you want. You can, of course, just continue with
+ \c {e1.setId(1002)}, if you really mean to create a second, unique
+ employee, but if you only want to change the employee's name
+ everywhere, consider using \l {QExplicitlySharedDataPointer}
+ {explicit sharing} in the \c Employee class instead of implicit
+ sharing.
+
+ If you declare the \e {d pointer} in the \c Employee class to be
+ \c {QExplicitlySharedDataPointer<EmployeeData>}, then explicit
+ sharing is used and \e{copy on write} operations are not performed
+ automatically (i.e. detach() is not called in non-const
+ functions). In that case, after \c {e1.setName("Hans Holbein")}, the
+ employee's name has been changed, but both e1 and e2 still refer to
+ the same instance of \c EmployeeData, so there is only one employee
+ with ID 1001.
+
+ In the member function documentation, \e{d pointer} always refers
+ to the internal pointer to the shared data object.
+
+ \sa QSharedData, QExplicitlySharedDataPointer
+*/
+
+/*! \fn T& QSharedDataPointer::operator*()
+ Provides access to the shared data object's members.
+ This function calls detach().
+*/
+
+/*! \fn const T& QSharedDataPointer::operator*() const
+ Provides const access to the shared data object's members.
+ This function does \e not call detach().
+*/
+
+/*! \fn T* QSharedDataPointer::operator->()
+ Provides access to the shared data object's members.
+ This function calls detach().
+*/
+
+/*! \fn const T* QSharedDataPointer::operator->() const
+ Provides const access to the shared data object's members.
+ This function does \e not call detach().
+*/
+
+/*! \fn QSharedDataPointer::operator T*()
+ Returns a pointer to the shared data object.
+ This function calls detach().
+
+ \sa data(), constData()
+*/
+
+/*! \fn QSharedDataPointer::operator const T*() const
+ Returns a pointer to the shared data object.
+ This function does \e not call detach().
+*/
+
+/*! \fn T* QSharedDataPointer::data()
+ Returns a pointer to the shared data object.
+ This function calls detach().
+
+ \sa constData()
+*/
+
+/*! \fn const T* QSharedDataPointer::data() const
+ Returns a pointer to the shared data object.
+ This function does \e not call detach().
+*/
+
+/*! \fn const T* QSharedDataPointer::constData() const
+ Returns a const pointer to the shared data object.
+ This function does \e not call detach().
+
+ \sa data()
+*/
+
+/*! \fn bool QSharedDataPointer::operator==(const QSharedDataPointer<T>& other) const
+ Returns true if \a other and \e this have the same \e{d pointer}.
+ This function does \e not call detach().
+*/
+
+/*! \fn bool QSharedDataPointer::operator!=(const QSharedDataPointer<T>& other) const
+ Returns true if \a other and \e this do \e not have the same
+ \e{d pointer}. This function does \e not call detach().
+*/
+
+/*! \fn QSharedDataPointer::QSharedDataPointer()
+ Constructs a QSharedDataPointer initialized with a null \e{d pointer}.
+*/
+
+/*! \fn QSharedDataPointer::~QSharedDataPointer()
+ Decrements the reference count of the shared data object.
+ If the reference count becomes 0, the shared data object
+ is deleted. \e This is then destroyed.
+*/
+
+/*! \fn QSharedDataPointer::QSharedDataPointer(T* sharedData)
+ Constructs a QSharedDataPointer with \e{d pointer} set to
+ \a sharedData and increments \a{sharedData}'s reference count.
+*/
+
+/*! \fn QSharedDataPointer::QSharedDataPointer(const QSharedDataPointer<T>& other)
+ Sets the \e{d pointer} of \e this to the \e{d pointer} in
+ \a other and increments the reference count of the shared
+ data object.
+*/
+
+/*! \fn QSharedDataPointer<T>& QSharedDataPointer::operator=(const QSharedDataPointer<T>& other)
+ Sets the \e{d pointer} of \e this to the \e{d pointer} of
+ \a other and increments the reference count of the shared
+ data object. The reference count of the old shared data
+ object of \e this is decremented. If the reference count
+ of the old shared data object becomes 0, the old shared
+ data object is deleted.
+*/
+
+/*! \fn QSharedDataPointer& QSharedDataPointer::operator=(T* sharedData)
+ Sets the \e{d pointer} og \e this to \a sharedData and increments
+ \a{sharedData}'s reference count. The reference count of the old
+ shared data object of \e this is decremented. If the reference
+ count of the old shared data object becomes 0, the old shared data
+ object is deleted.
+*/
+
+/*! \fn bool QSharedDataPointer::operator!() const
+ Returns true if the \e{d pointer} of \e this is null.
+*/
+
+/*! \fn void QSharedDataPointer::detach()
+ If the shared data object's reference count is greater than 1, this
+ function creates a deep copy of the shared data object and sets the
+ \e{d pointer} of \e this to the copy.
+
+ This function is called automatically by non-const member
+ functions of QSharedDataPointer if \e{copy on write} is
+ required. You don't need to call it yourself.
+*/
+
+/*! \fn T *QSharedDataPointer::clone()
+ \since 4.5
+
+ Creates and returns a deep copy of the current data. This function
+ is called by detach() when the reference count is greater than 1 in
+ order to create the new copy. This function uses the \e {operator
+ new} and calls the copy constructor of the type T.
+
+ This function is provided so that you may support "virtual copy
+ constructors" for your own types. In order to so, you should declare
+ a template-specialization of this function for your own type, like
+ the example below:
+
+ \code
+ template<>
+ EmployeeData *QSharedDataPointer<EmployeeData>::clone()
+ {
+ return d->clone();
+ }
+ \endcode
+
+ In the example above, the template specialization for the clone()
+ function calls the \e {EmployeeData::clone()} virtual function. A
+ class derived from EmployeeData could override that function and
+ return the proper polymorphic type.
+*/
+
+/*!
+ \class QExplicitlySharedDataPointer
+ \brief The QExplicitlySharedDataPointer class represents a pointer to an explicitly shared object.
+ \since 4.4
+ \reentrant
+ \ingroup misc
+ \mainclass
+
+ QExplicitlySharedDataPointer\<T\> makes writing your own explicitly
+ shared classes easy. QExplicitlySharedDataPointer implements
+ \l {thread-safe} reference counting, ensuring that adding
+ QExplicitlySharedDataPointers to your \l {reentrant} classes won't
+ make them non-reentrant.
+
+ Except for one big difference, QExplicitlySharedDataPointer is just
+ like QSharedDataPointer. The big difference is that member functions
+ of QExplicitlySharedDataPointer \e{do not} do the automatic
+ \e{copy on write} operation (detach()) that non-const members of
+ QSharedDataPointer do before allowing the shared data object to be
+ modified. There is a detach() function available, but if you really
+ want to detach(), you have to call it yourself. This means that
+ QExplicitlySharedDataPointers behave like regular C++ pointers,
+ except that by doing reference counting and not deleting the shared
+ data object until the reference count is 0, they avoid the dangling
+ pointer problem.
+
+ It is instructive to compare QExplicitlySharedDataPointer with
+ QSharedDataPointer by way of an example. Consider the \l {Employee
+ example} in QSharedDataPointer, modified to use explicit sharing as
+ explained in the discussion \l {Implicit vs Explicit Sharing}.
+
+ Note that if you use this class but find you are calling detach() a
+ lot, you probably should be using QSharedDataPointer instead.
+
+ In the member function documentation, \e{d pointer} always refers
+ to the internal pointer to the shared data object.
+
+ \sa QSharedData, QSharedDataPointer
+*/
+
+/*! \fn T& QExplicitlySharedDataPointer::operator*() const
+ Provides access to the shared data object's members.
+*/
+
+/*! \fn T* QExplicitlySharedDataPointer::operator->()
+ Provides access to the shared data object's members.
+*/
+
+/*! \fn const T* QExplicitlySharedDataPointer::operator->() const
+ Provides const access to the shared data object's members.
+*/
+
+/*! \fn T* QExplicitlySharedDataPointer::data() const
+ Returns a pointer to the shared data object.
+*/
+
+/*! \fn const T* QExplicitlySharedDataPointer::constData() const
+ Returns a const pointer to the shared data object.
+
+ \sa data()
+*/
+
+/*! \fn bool QExplicitlySharedDataPointer::operator==(const QExplicitlySharedDataPointer<T>& other) const
+ Returns true if \a other and \e this have the same \e{d pointer}.
+*/
+
+/*! \fn bool QExplicitlySharedDataPointer::operator==(const T* ptr) const
+ Returns true if the \e{d pointer} of \e this is \a ptr.
+ */
+
+/*! \fn bool QExplicitlySharedDataPointer::operator!=(const QExplicitlySharedDataPointer<T>& other) const
+ Returns true if \a other and \e this do \e not have the same
+ \e{d pointer}.
+*/
+
+/*! \fn bool QExplicitlySharedDataPointer::operator!=(const T* ptr) const
+ Returns true if the \e{d pointer} of \e this is \e not \a ptr.
+ */
+
+/*! \fn QExplicitlySharedDataPointer::QExplicitlySharedDataPointer()
+ Constructs a QExplicitlySharedDataPointer initialized with a null
+ \e{d pointer}.
+*/
+
+/*! \fn QExplicitlySharedDataPointer::~QExplicitlySharedDataPointer()
+ Decrements the reference count of the shared data object.
+ If the reference count becomes 0, the shared data object
+ is deleted. \e This is then destroyed.
+*/
+
+/*! \fn QExplicitlySharedDataPointer::QExplicitlySharedDataPointer(T* sharedData)
+ Constructs a QExplicitlySharedDataPointer with \e{d pointer}
+ set to \a sharedData and increments \a{sharedData}'s reference
+ count.
+*/
+
+/*! \fn QExplicitlySharedDataPointer::QExplicitlySharedDataPointer(const QExplicitlySharedDataPointer<T>& other)
+ This standard copy constructor sets the \e {d pointer} of \e this to
+ the \e {d pointer} in \a other and increments the reference count of
+ the shared data object.
+*/
+
+/*! \fn QExplicitlySharedDataPointer::QExplicitlySharedDataPointer(const QExplicitlySharedDataPointer<X>& other)
+ This copy constructor is different in that it allows \a other to be
+ a different type of explicitly shared data pointer but one that has
+ a compatible shared data object. It performs a static cast of the
+ \e{d pointer} in \a other and sets the \e {d pointer} of \e this to
+ the converted \e{d pointer}. It increments the reference count of
+ the shared data object.
+ */
+
+/*! \fn QExplicitlySharedDataPointer<T>& QExplicitlySharedDataPointer::operator=(const QExplicitlySharedDataPointer<T>& other)
+ Sets the \e{d pointer} of \e this to the \e{d pointer} of
+ \a other and increments the reference count of the shared
+ data object. The reference count of the old shared data
+ object of \e this is decremented. If the reference count
+ of the old shared data object becomes 0, the old shared
+ data object is deleted.
+*/
+
+/*! \fn QExplicitlySharedDataPointer& QExplicitlySharedDataPointer::operator=(T* sharedData)
+ Sets the \e{d pointer} of \e this to \a sharedData and
+ increments \a{sharedData}'s reference count. The reference
+ count of the old shared data object of \e this is decremented.
+ If the reference count of the old shared data object becomes
+ 0, the old shared data object is deleted.
+*/
+
+/*! \fn void QExplicitlySharedDataPointer::reset()
+ Resets \e this to be null. i.e., this function sets the
+ \e{d pointer} of \e this to 0, but first it decrements
+ the reference count of the shared data object and deletes
+ the shared data object if the reference count became 0.
+ */
+
+/*! \fn QExplicitlySharedDataPointer::operator bool () const
+ Returns true if the \e{d pointer} of \e this is \e not null.
+ */
+
+/*! \fn bool QExplicitlySharedDataPointer::operator!() const
+ Returns true if the \e{d pointer} of \e this is null.
+*/
+
+/*! \fn void QExplicitlySharedDataPointer::detach()
+ If the shared data object's reference count is greater than 1, this
+ function creates a deep copy of the shared data object and sets the
+ \e{d pointer} of \e this to the copy.
+
+ Because QExplicitlySharedDataPointer does not do the automatic
+ \e{copy on write} operations that members of QSharedDataPointer do,
+ detach() is \e not called automatically anywhere in the member
+ functions of this class. If you find that you are calling detach()
+ everywhere in your code, consider using QSharedDataPointer instead.
+*/
+
+/*! \fn T *QExplicitlySharedDataPointer::clone()
+ \since 4.5
+
+ Creates and returns a deep copy of the current data. This function
+ is called by detach() when the reference count is greater than 1 in
+ order to create the new copy. This function uses the \e {operator
+ new} and calls the copy constructor of the type T.
+
+ See QSharedDataPointer::clone() for an explanation of how to use it.
+*/
+
+/*!
+ \typedef QExplicitlySharedDataPointer::Type
+
+ This is the type of the shared data object. The \e{d pointer}
+ points to an object of this type.
+ */
+
+QT_END_NAMESPACE
diff --git a/src/corelib/tools/qshareddata.h b/src/corelib/tools/qshareddata.h
new file mode 100644
index 0000000000..875560d2f4
--- /dev/null
+++ b/src/corelib/tools/qshareddata.h
@@ -0,0 +1,242 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSHAREDDATA_H
+#define QSHAREDDATA_H
+
+#include <QtCore/qglobal.h>
+#include <QtCore/qatomic.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Core)
+
+template <class T> class QSharedDataPointer;
+
+class Q_CORE_EXPORT QSharedData
+{
+public:
+ mutable QAtomicInt ref;
+
+ inline QSharedData() : ref(0) { }
+ inline QSharedData(const QSharedData &) : ref(0) { }
+
+private:
+ // using the assignment operator would lead to corruption in the ref-counting
+ QSharedData &operator=(const QSharedData &);
+};
+
+template <class T> class QSharedDataPointer
+{
+public:
+ inline void detach() { if (d && d->ref != 1) detach_helper(); }
+ inline T &operator*() { detach(); return *d; }
+ inline const T &operator*() const { return *d; }
+ inline T *operator->() { detach(); return d; }
+ inline const T *operator->() const { return d; }
+ inline operator T *() { detach(); return d; }
+ inline operator const T *() const { return d; }
+ inline T *data() { detach(); return d; }
+ inline const T *data() const { return d; }
+ inline const T *constData() const { return d; }
+
+ inline bool operator==(const QSharedDataPointer<T> &other) const { return d == other.d; }
+ inline bool operator!=(const QSharedDataPointer<T> &other) const { return d != other.d; }
+
+ inline QSharedDataPointer() { d = 0; }
+ inline ~QSharedDataPointer() { if (d && !d->ref.deref()) delete d; }
+
+ explicit QSharedDataPointer(T *data);
+ inline QSharedDataPointer(const QSharedDataPointer<T> &o) : d(o.d) { if (d) d->ref.ref(); }
+ inline QSharedDataPointer<T> & operator=(const QSharedDataPointer<T> &o) {
+ if (o.d != d) {
+ if (o.d)
+ o.d->ref.ref();
+ if (d && !d->ref.deref())
+ delete d;
+ d = o.d;
+ }
+ return *this;
+ }
+ inline QSharedDataPointer &operator=(T *o) {
+ if (o != d) {
+ if (o)
+ o->ref.ref();
+ if (d && !d->ref.deref())
+ delete d;
+ d = o;
+ }
+ return *this;
+ }
+
+ inline bool operator!() const { return !d; }
+
+protected:
+ T *clone();
+
+private:
+ void detach_helper();
+
+ T *d;
+};
+
+template <class T> class QExplicitlySharedDataPointer
+{
+public:
+ typedef T Type;
+
+ inline T &operator*() const { return *d; }
+ inline T *operator->() { return d; }
+ inline T *operator->() const { return d; }
+ inline T *data() const { return d; }
+ inline const T *constData() const { return d; }
+
+ inline void detach() { if (d && d->ref != 1) detach_helper(); }
+
+ inline void reset()
+ {
+ if(d && !d->ref.deref())
+ delete d;
+
+ d = 0;
+ }
+
+ inline operator bool () const { return d != 0; }
+
+ inline bool operator==(const QExplicitlySharedDataPointer<T> &other) const { return d == other.d; }
+ inline bool operator!=(const QExplicitlySharedDataPointer<T> &other) const { return d != other.d; }
+ inline bool operator==(const T *ptr) const { return d == ptr; }
+ inline bool operator!=(const T *ptr) const { return d != ptr; }
+
+ inline QExplicitlySharedDataPointer() { d = 0; }
+ inline ~QExplicitlySharedDataPointer() { if (d && !d->ref.deref()) delete d; }
+
+ explicit QExplicitlySharedDataPointer(T *data);
+ inline QExplicitlySharedDataPointer(const QExplicitlySharedDataPointer<T> &o) : d(o.d) { if (d) d->ref.ref(); }
+
+#ifndef QT_NO_MEMBER_TEMPLATES
+ template<class X>
+ inline QExplicitlySharedDataPointer(const QExplicitlySharedDataPointer<X> &o) : d(static_cast<T *>(o.data()))
+ {
+ if(d)
+ d->ref.ref();
+ }
+#endif
+
+ inline QExplicitlySharedDataPointer<T> & operator=(const QExplicitlySharedDataPointer<T> &o) {
+ if (o.d != d) {
+ if (o.d)
+ o.d->ref.ref();
+ if (d && !d->ref.deref())
+ delete d;
+ d = o.d;
+ }
+ return *this;
+ }
+ inline QExplicitlySharedDataPointer &operator=(T *o) {
+ if (o != d) {
+ if (o)
+ o->ref.ref();
+ if (d && !d->ref.deref())
+ delete d;
+ d = o;
+ }
+ return *this;
+ }
+
+ inline bool operator!() const { return !d; }
+
+protected:
+ T *clone();
+
+private:
+ void detach_helper();
+
+ T *d;
+};
+
+template <class T>
+Q_INLINE_TEMPLATE QSharedDataPointer<T>::QSharedDataPointer(T *adata) : d(adata)
+{ if (d) d->ref.ref(); }
+
+template <class T>
+Q_INLINE_TEMPLATE T *QSharedDataPointer<T>::clone()
+{
+ return new T(*d);
+}
+
+template <class T>
+Q_OUTOFLINE_TEMPLATE void QSharedDataPointer<T>::detach_helper()
+{
+ T *x = clone();
+ x->ref.ref();
+ if (!d->ref.deref())
+ delete d;
+ d = x;
+}
+
+template <class T>
+Q_INLINE_TEMPLATE T *QExplicitlySharedDataPointer<T>::clone()
+{
+ return new T(*d);
+}
+
+template <class T>
+Q_OUTOFLINE_TEMPLATE void QExplicitlySharedDataPointer<T>::detach_helper()
+{
+ T *x = clone();
+ x->ref.ref();
+ if (!d->ref.deref())
+ delete d;
+ d = x;
+}
+
+template <class T>
+Q_INLINE_TEMPLATE QExplicitlySharedDataPointer<T>::QExplicitlySharedDataPointer(T *adata) : d(adata)
+{ if (d) d->ref.ref(); }
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QSHAREDDATA_H
diff --git a/src/corelib/tools/qsharedpointer.cpp b/src/corelib/tools/qsharedpointer.cpp
new file mode 100644
index 0000000000..d8a9923e6d
--- /dev/null
+++ b/src/corelib/tools/qsharedpointer.cpp
@@ -0,0 +1,868 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qsharedpointer.h"
+
+// to be sure we aren't causing a namespace clash:
+#include "qshareddata.h"
+
+/*!
+ \class QSharedPointer
+ \brief The QSharedPointer class holds a strong reference to a shared pointer
+ \since 4.5
+
+ \reentrant
+ \ingroup misc
+
+ The QSharedPointer is an automatic, shared pointer in C++. It
+ behaves exactly like a normal pointer for normal purposes,
+ including respect for constness.
+
+ QSharedPointer will delete the pointer it is holding when it goes
+ out of scope, provided no other QSharedPointer objects are
+ referencing it.
+
+ A QSharedPointer object can be created from a normal pointer,
+ another QSharedPointer object or by promoting a
+ QWeakPointer object to a strong reference.
+
+ \section1 Thread-Safety
+
+ QSharedPointer and QWeakPointer are thread-safe and operate
+ atomically on the pointer value. Different threads can also access
+ the same QSharedPointer or QWeakPointer object at the same time
+ without need for locking mechanisms.
+
+ It should be noted that, while the pointer value can be accessed
+ in this manner, QSharedPointer and QWeakPointer provide no
+ guarantee about the object being pointed to. Thread-safety and
+ reentrancy rules for that object still apply.
+
+ \section1 Other Pointer Classes
+
+ Qt also provides two other pointer wrapper classes: QPointer and
+ QSharedDataPointer. They are incompatible with one another, since
+ each has its very different use case.
+
+ QSharedPointer holds a shared pointer by means of an external
+ reference count (i.e., a reference counter placed outside the
+ object). Like its name indicates, the pointer value is shared
+ among all instances of QSharedPointer and QWeakPointer. The
+ contents of the object pointed to by the pointer should not
+ considered shared, however: there is only one object. For that
+ reason, QSharedPointer does not provide a way to detach or make
+ copies of the pointed object.
+
+ QSharedDataPointer, on the other hand, holds a pointer to shared
+ data (i.e., a class derived from QSharedData). It does so by means
+ of an internal reference count, placed in the QSharedData base
+ class. This class can, therefore, detach based on the type of
+ access made to the data being guarded: if it's a non-const access,
+ it creates a copy atomically for the operation to complete.
+
+ QExplicitlySharedDataPointer behaves like QSharedDataPointer,
+ except that it only detaches if
+ QExplicitlySharedDataPointer::detach() is explicitly called.
+
+ Finally, QPointer holds a pointer to a QObject-derived object, but
+ it does so weakly. QPointer is similar, in that behaviour, to
+ QWeakPointer: it does not allow you to prevent the object from
+ being destroyed. All you can do is query whether it has been
+ destroyed or not.
+
+ \sa QSharedDataPointer, QWeakPointer
+*/
+
+/*!
+ \class QWeakPointer
+ \brief The QWeakPointer class holds a weak reference to a shared pointer
+ \since 4.5
+ \reentrant
+ \ingroup misc
+
+ The QWeakPointer is an automatic weak reference to a
+ pointer in C++. It cannot be used to dereference the pointer
+ directly, but it can be used to verify if the pointer has been
+ deleted or not in another context.
+
+ QWeakPointer objects can only be created by assignment
+ from a QSharedPointer.
+
+ To access the pointer that QWeakPointer is tracking, you
+ must first create a QSharedPointer object and verify if the pointer
+ is null or not.
+
+ \sa QSharedPointer
+*/
+
+/*!
+ \fn QSharedPointer::QSharedPointer()
+
+ Creates a QSharedPointer that points to null (0).
+*/
+
+/*!
+ \fn QSharedPointer::~QSharedPointer()
+
+ Destroys this QSharedPointer object. If it is the last reference to
+ the pointer stored, this will delete the pointer as well.
+*/
+
+/*!
+ \fn QSharedPointer::QSharedPointer(T *ptr)
+
+ Creates a QSharedPointer that points to \a ptr. The pointer \a ptr
+ becomes managed by this QSharedPointer and must not be passed to
+ another QSharedPointer object or deleted outside this object.
+*/
+
+/*!
+ \fn QSharedPointer::QSharedPointer(T *ptr, Deleter deleter)
+
+ Creates a QSharedPointer that points to \a ptr. The pointer \a ptr
+ becomes managed by this QSharedPointer and must not be passed to
+ another QSharedPointer object or deleted outside this object.
+
+ The \a deleter paramter specifies the custom deleter for this
+ object. The custom deleter is called when the strong reference
+ count drops to 0 instead of the operator delete(). This is useful,
+ for instance, for calling deleteLater() in a QObject instead:
+
+ \code
+ static void doDeleteLater(MyObject *obj)
+ {
+ obj->deleteLater();
+ }
+
+ void otherFunction()
+ {
+ QSharedPointer<MyObject> obj =
+ QSharedPointer<MyObject>(new MyObject, doDeleteLater);
+
+ // continue using obj
+ obj.clear(); // calls obj->deleteLater();
+ }
+ \endcode
+
+ It is also possible to specify a member function directly, as in:
+ \code
+ QSharedPointer<MyObject> obj =
+ QSharedPointer<MyObject>(new MyObject, &QObject::deleteLater);
+ \endcode
+
+ \sa clear()
+*/
+
+/*!
+ \fn QSharedPointer::QSharedPointer(const QSharedPointer<T> &other)
+
+ Creates a QSharedPointer object that shares \a other's pointer.
+
+ If \tt T is a derived type of the template parameter of this class,
+ QSharedPointer will perform an automatic cast. Otherwise, you will
+ get a compiler error.
+*/
+
+/*!
+ \fn QSharedPointer::QSharedPointer(const QWeakPointer<T> &other)
+
+ Creates a QSharedPointer by promoting the weak reference \a other
+ to strong reference and sharing its pointer.
+
+ If \tt T is a derived type of the template parameter of this
+ class, QSharedPointer will perform an automatic cast. Otherwise,
+ you will get a compiler error.
+*/
+
+/*!
+ \fn QSharedPointer &QSharedPointer::operator=(const QSharedPointer<T> &other)
+
+ Makes this object share \a other's pointer. The current pointer
+ reference is discarded and, if it was the last, the pointer will
+ be deleted.
+
+ If \tt T is a derived type of the template parameter of this
+ class, QSharedPointer will perform an automatic cast. Otherwise,
+ you will get a compiler error.
+*/
+
+/*!
+ \fn QSharedPointer &QSharedPointer::operator=(const QWeakPointer<T> &other)
+
+ Promotes \a other to a strong reference and makes this object
+ share a reference to the pointer referenced by it. The current pointer
+ reference is discarded and, if it was the last, the pointer will
+ be deleted.
+
+ If \tt T is a derived type of the template parameter of this
+ class, QSharedPointer will perform an automatic cast. Otherwise,
+ you will get a compiler error.
+*/
+
+/*!
+ \fn T *QSharedPointer::data() const
+
+ Returns the value of the pointer referenced by this object.
+
+ Note: do not delete the pointer returned by this function or pass
+ it to another function that could delete it, including creating
+ QSharedPointer or QWeakPointer objects.
+*/
+
+/*!
+ \fn T &QSharedPointer::operator *() const
+
+ Provides access to the shared pointer's members.
+
+ \sa isNull()
+*/
+
+/*!
+ \fn T *QSharedPointer::operator ->() const
+
+ Provides access to the shared pointer's members.
+
+ \sa isNull()
+*/
+
+/*!
+ \fn bool QSharedPointer::isNull() const
+
+ Returns true if this object is holding a reference to a null
+ pointer.
+*/
+
+/*!
+ \fn QSharedPointer::operator bool() const
+
+ Returns true if this object is not null. This function is suitable
+ for use in \tt if-constructs, like:
+
+ \code
+ if (sharedptr) { ... }
+ \endcode
+
+ \sa isNull()
+*/
+
+/*!
+ \fn bool QSharedPointer::operator !() const
+
+ Returns true if this object is null. This function is suitable
+ for use in \tt if-constructs, like:
+
+ \code
+ if (!sharedptr) { ... }
+ \endcode
+
+ \sa isNull()
+*/
+
+/*!
+ \fn QSharedPointer<X> QSharedPointer::staticCast() const
+
+ Performs a static cast from this pointer's type to \tt X and returns
+ a QSharedPointer that shares the reference. This function can be
+ used for up- and for down-casting, but is more useful for
+ up-casting.
+
+ Note: the template type \c X must have the same const and volatile
+ qualifiers as the template of this object, or the cast will
+ fail. Use constCast() if you need to drop those qualifiers.
+
+ \sa dynamicCast(), constCast(), qSharedPointerCast()
+*/
+
+/*!
+ \fn QSharedPointer<X> QSharedPointer::dynamicCast() const
+
+ Performs a dynamic cast from this pointer's type to \tt X and
+ returns a QSharedPointer that shares the reference. If this
+ function is used to up-cast, then QSharedPointer will perform a \tt
+ dynamic_cast, which means that if the object being pointed by this
+ QSharedPointer is not of type \tt X, the returned object will be
+ null.
+
+ Note: the template type \c X must have the same const and volatile
+ qualifiers as the template of this object, or the cast will
+ fail. Use constCast() if you need to drop those qualifiers.
+
+ \sa qSharedPointerDynamicCast()
+*/
+
+/*!
+ \fn QSharedPointer<X> QSharedPointer::constCast() const
+
+ Performs a \tt const_cast from this pointer's type to \tt X and returns
+ a QSharedPointer that shares the reference. This function can be
+ used for up- and for down-casting, but is more useful for
+ up-casting.
+
+ \sa isNull(), qSharedPointerConstCast()
+*/
+
+/*!
+ \fn QWeakPointer<T> QSharedPointer::toWeakRef() const
+
+ Returns a weak reference object that shares the pointer referenced
+ by this object.
+*/
+
+/*!
+ \fn void QSharedPointer::clear()
+
+ Clears this QSharedPointer object, dropping the reference that it
+ may have had to the pointer. If this was the last reference, then
+ the pointer itself will be deleted.
+*/
+
+/*!
+ \fn QWeakPointer::QWeakPointer()
+
+ Creates a QWeakPointer that points to nothing.
+*/
+
+/*!
+ \fn QWeakPointer::~QWeakPointer()
+
+ Destroys this QWeakPointer object. The pointer referenced
+ by this object will not be deleted.
+*/
+
+/*!
+ \fn QWeakPointer::QWeakPointer(const QWeakPointer<T> &other)
+
+ Creates a QWeakPointer that holds a weak reference to the
+ pointer referenced by \a other.
+
+ If \tt T is a derived type of the template parameter of this
+ class, QWeakPointer will perform an automatic cast. Otherwise,
+ you will get a compiler error.
+*/
+
+/*!
+ \fn QWeakPointer::QWeakPointer(const QSharedPointer<T> &other)
+
+ Creates a QWeakPointer that holds a weak reference to the
+ pointer referenced by \a other.
+
+ If \tt T is a derived type of the template parameter of this
+ class, QWeakPointer will perform an automatic cast. Otherwise,
+ you will get a compiler error.
+*/
+
+/*!
+ \fn QWeakPointer &QWeakPointer::operator=(const QWeakPointer<T> &other)
+
+ Makes this object share \a other's pointer. The current pointer
+ reference is discarded but is not deleted.
+
+ If \tt T is a derived type of the template parameter of this
+ class, QWeakPointer will perform an automatic cast. Otherwise,
+ you will get a compiler error.
+*/
+
+/*!
+ \fn QWeakPointer &QWeakPointer::operator=(const QSharedPointer<T> &other)
+
+ Makes this object share \a other's pointer. The current pointer
+ reference is discarded but is not deleted.
+
+ If \tt T is a derived type of the template parameter of this
+ class, QWeakPointer will perform an automatic cast. Otherwise,
+ you will get a compiler error.
+*/
+
+/*!
+ \fn bool QWeakPointer::isNull() const
+
+ Returns true if this object is holding a reference to a null
+ pointer.
+
+ Note that, due to the nature of weak references, the pointer that
+ QWeakPointer references can become null at any moment, so
+ the value returned from this function can change from false to
+ true from one call to the next.
+*/
+
+/*!
+ \fn QWeakPointer::operator bool() const
+
+ Returns true if this object is not null. This function is suitable
+ for use in \tt if-constructs, like:
+
+ \code
+ if (weakref) { ... }
+ \endcode
+
+ Note that, due to the nature of weak references, the pointer that
+ QWeakPointer references can become null at any moment, so
+ the value returned from this function can change from true to
+ false from one call to the next.
+
+ \sa isNull()
+*/
+
+/*!
+ \fn bool QWeakPointer::operator !() const
+
+ Returns true if this object is null. This function is suitable
+ for use in \tt if-constructs, like:
+
+ \code
+ if (!weakref) { ... }
+ \endcode
+
+ Note that, due to the nature of weak references, the pointer that
+ QWeakPointer references can become null at any moment, so
+ the value returned from this function can change from false to
+ true from one call to the next.
+
+ \sa isNull()
+*/
+
+/*!
+ \fn QSharedPointer<T> QWeakPointer::toStrongRef() const
+
+ Promotes this weak reference to a strong one and returns a
+ QSharedPointer object holding that reference.
+*/
+
+/*!
+ \fn void QWeakPointer::clear()
+
+ Clears this QWeakPointer object, dropping the reference that it
+ may have had to the pointer.
+*/
+
+/*!
+ \fn bool operator==(const QSharedPointer<T> &ptr1, const QSharedPointer<X> &ptr2)
+ \relates QSharedPointer
+
+ Returns true if the pointer referenced by \a ptr1 is the
+ same pointer as that referenced by \a ptr2.
+
+ If \a ptr2's template parameter is different from \a ptr1's,
+ QSharedPointer will attempt to perform an automatic \tt static_cast
+ to ensure that the pointers being compared are equal. If \a ptr2's
+ template parameter is not a base or a derived type from
+ \a ptr1's, you will get a compiler error.
+*/
+
+/*!
+ \fn bool operator!=(const QSharedPointer<T> &ptr1, const QSharedPointer<X> &ptr2)
+ \relates QSharedPointer
+
+ Returns true if the pointer referenced by \a ptr1 is not the
+ same pointer as that referenced by \a ptr2.
+
+ If \a ptr2's template parameter is different from \a ptr1's,
+ QSharedPointer will attempt to perform an automatic \tt static_cast
+ to ensure that the pointers being compared are equal. If \a ptr2's
+ template parameter is not a base or a derived type from
+ \a ptr1's, you will get a compiler error.
+*/
+
+/*!
+ \fn bool operator==(const QSharedPointer<T> &ptr1, const X *ptr2)
+ \relates QSharedPointer
+
+ Returns true if the pointer referenced by \a ptr1 is the
+ same pointer as \a ptr2.
+
+ If \a ptr2's type is different from \a ptr1's,
+ QSharedPointer will attempt to perform an automatic \tt static_cast
+ to ensure that the pointers being compared are equal. If \a ptr2's
+ type is not a base or a derived type from this
+ \a ptr1's, you will get a compiler error.
+*/
+
+/*!
+ \fn bool operator!=(const QSharedPointer<T> &ptr1, const X *ptr2)
+ \relates QSharedPointer
+
+ Returns true if the pointer referenced by \a ptr1 is not the
+ same pointer as \a ptr2.
+
+ If \a ptr2's type is different from \a ptr1's,
+ QSharedPointer will attempt to perform an automatic \tt static_cast
+ to ensure that the pointers being compared are equal. If \a ptr2's
+ type is not a base or a derived type from this
+ \a ptr1's, you will get a compiler error.
+*/
+
+/*!
+ \fn bool operator==(const T *ptr1, const QSharedPointer<X> &ptr2)
+ \relates QSharedPointer
+
+ Returns true if the pointer \a ptr1 is the
+ same pointer as that referenced by \a ptr2.
+
+ If \a ptr2's template parameter is different from \a ptr1's type,
+ QSharedPointer will attempt to perform an automatic \tt static_cast
+ to ensure that the pointers being compared are equal. If \a ptr2's
+ template parameter is not a base or a derived type from
+ \a ptr1's type, you will get a compiler error.
+*/
+
+/*!
+ \fn bool operator!=(const T *ptr1, const QSharedPointer<X> &ptr2)
+ \relates QSharedPointer
+
+ Returns true if the pointer \a ptr1 is not the
+ same pointer as that referenced by \a ptr2.
+
+ If \a ptr2's template parameter is different from \a ptr1's type,
+ QSharedPointer will attempt to perform an automatic \tt static_cast
+ to ensure that the pointers being compared are equal. If \a ptr2's
+ template parameter is not a base or a derived type from
+ \a ptr1's type, you will get a compiler error.
+*/
+
+/*!
+ \fn bool operator==(const QSharedPointer<T> &ptr1, const QWeakPointer<X> &ptr2)
+ \relates QWeakPointer
+
+ Returns true if the pointer referenced by \a ptr1 is the
+ same pointer as that referenced by \a ptr2.
+
+ If \a ptr2's template parameter is different from \a ptr1's,
+ QSharedPointer will attempt to perform an automatic \tt static_cast
+ to ensure that the pointers being compared are equal. If \a ptr2's
+ template parameter is not a base or a derived type from
+ \a ptr1's, you will get a compiler error.
+*/
+
+/*!
+ \fn bool operator!=(const QSharedPointer<T> &ptr1, const QWeakPointer<X> &ptr2)
+ \relates QWeakPointer
+
+ Returns true if the pointer referenced by \a ptr1 is not the
+ same pointer as that referenced by \a ptr2.
+
+ If \a ptr2's template parameter is different from \a ptr1's,
+ QSharedPointer will attempt to perform an automatic \tt static_cast
+ to ensure that the pointers being compared are equal. If \a ptr2's
+ template parameter is not a base or a derived type from
+ \a ptr1's, you will get a compiler error.
+*/
+
+/*!
+ \fn bool operator==(const QWeakPointer<T> &ptr1, const QSharedPointer<X> &ptr2)
+ \relates QWeakPointer
+
+ Returns true if the pointer referenced by \a ptr1 is the
+ same pointer as that referenced by \a ptr2.
+
+ If \a ptr2's template parameter is different from \a ptr1's,
+ QSharedPointer will attempt to perform an automatic \tt static_cast
+ to ensure that the pointers being compared are equal. If \a ptr2's
+ template parameter is not a base or a derived type from
+ \a ptr1's, you will get a compiler error.
+*/
+
+/*!
+ \fn bool operator!=(const QWeakPointer<T> &ptr1, const QSharedPointer<X> &ptr2)
+ \relates QWeakPointer
+
+ Returns true if the pointer referenced by \a ptr1 is not the
+ same pointer as that referenced by \a ptr2.
+
+ If \a ptr2's template parameter is different from \a ptr1's,
+ QSharedPointer will attempt to perform an automatic \tt static_cast
+ to ensure that the pointers being compared are equal. If \a ptr2's
+ template parameter is not a base or a derived type from
+ \a ptr1's, you will get a compiler error.
+*/
+
+/*!
+ \fn QSharedPointer<X> qSharedPointerCast(const QSharedPointer<T> &other)
+ \relates QSharedPointer
+
+ Returns a shared pointer to the pointer held by \a other, cast to
+ type \tt X. The types \tt T and \tt X must belong to one
+ hierarchy for the \tt static_cast to succeed.
+
+ Note that \tt X must have the same cv-qualifiers (\tt const and
+ \tt volatile) that \tt T has, or the code will fail to
+ compile. Use qSharedPointerConstCast to cast away the constness.
+
+ \sa QSharedPointer::staticCast(), qSharedPointerDynamicCast(), qSharedPointerConstCast()
+*/
+
+/*!
+ \fn QSharedPointer<X> qSharedPointerCast(const QWeakPointer<T> &other)
+ \relates QSharedPointer
+ \relates QWeakPointer
+
+ Returns a shared pointer to the pointer held by \a other, cast to
+ type \tt X. The types \tt T and \tt X must belong to one
+ hierarchy for the \tt static_cast to succeed.
+
+ The \a other object is converted first to a strong reference. If
+ that conversion fails (because the object it's pointing to has
+ already been deleted), this function returns a null
+ QSharedPointer.
+
+ Note that \tt X must have the same cv-qualifiers (\tt const and
+ \tt volatile) that \tt T has, or the code will fail to
+ compile. Use qSharedPointerConstCast to cast away the constness.
+
+ \sa QWeakPointer::toStrongRef(), qSharedPointerDynamicCast(), qSharedPointerConstCast()
+*/
+
+/*!
+ \fn QSharedPointer<X> qSharedPointerDynamicCast(const QSharedPointer<T> &other)
+ \relates QSharedPointer
+
+ Returns a shared pointer to the pointer held by \a other, using a
+ dynamic cast to type \tt X to obtain an internal pointer of the
+ appropriate type. If the \tt dynamic_cast fails, the object
+ returned will be null.
+
+ Note that \tt X must have the same cv-qualifiers (\tt const and
+ \tt volatile) that \tt T has, or the code will fail to
+ compile. Use qSharedPointerConstCast to cast away the constness.
+
+ \sa QSharedPointer::dynamicCast(), qSharedPointerCast(), qSharedPointerConstCast()
+*/
+
+/*!
+ \fn QSharedPointer<X> qSharedPointerDynamicCast(const QWeakPointer<T> &other)
+ \relates QSharedPointer
+ \relates QWeakPointer
+
+ Returns a shared pointer to the pointer held by \a other, using a
+ dynamic cast to type \tt X to obtain an internal pointer of the
+ appropriate type. If the \tt dynamic_cast fails, the object
+ returned will be null.
+
+ The \a other object is converted first to a strong reference. If
+ that conversion fails (because the object it's pointing to has
+ already been deleted), this function also returns a null
+ QSharedPointer.
+
+ Note that \tt X must have the same cv-qualifiers (\tt const and
+ \tt volatile) that \tt T has, or the code will fail to
+ compile. Use qSharedPointerConstCast to cast away the constness.
+
+ \sa QWeakPointer::toStrongRef(), qSharedPointerCast(), qSharedPointerConstCast()
+*/
+
+/*!
+ \fn QSharedPointer<X> qSharedPointerConstCast(const QSharedPointer<T> &other)
+ \relates QSharedPointer
+
+ Returns a shared pointer to the pointer held by \a other, cast to
+ type \tt X. The types \tt T and \tt X must belong to one
+ hierarchy for the \tt const_cast to succeed. The \tt const and \tt
+ volatile differences between \tt T and \tt X are ignored.
+
+ \sa QSharedPointer::constCast(), qSharedPointerCast(), qSharedPointerDynamicCast()
+*/
+
+/*!
+ \fn QSharedPointer<X> qSharedPointerConstCast(const QWeakPointer<T> &other)
+ \relates QSharedPointer
+ \relates QWeakPointer
+
+ Returns a shared pointer to the pointer held by \a other, cast to
+ type \tt X. The types \tt T and \tt X must belong to one
+ hierarchy for the \tt const_cast to succeed. The \tt const and
+ \tt volatile differences between \tt T and \tt X are ignored.
+
+ The \a other object is converted first to a strong reference. If
+ that conversion fails (because the object it's pointing to has
+ already been deleted), this function returns a null
+ QSharedPointer.
+
+ \sa QWeakPointer::toStrongRef(), qSharedPointerCast(), qSharedPointerDynamicCast()
+*/
+
+/*!
+ \fn QWeakPointer<X> qWeakPointerCast(const QWeakPointer<T> &other)
+ \relates QWeakPointer
+
+ Returns a weak pointer to the pointer held by \a other, cast to
+ type \tt X. The types \tt T and \tt X must belong to one
+ hierarchy for the \tt static_cast to succeed.
+
+ Note that \tt X must have the same cv-qualifiers (\tt const and
+ \tt volatile) that \tt T has, or the code will fail to
+ compile. Use qSharedPointerConstCast to cast away the constness.
+*/
+
+#include <qset.h>
+#include <qmutex.h>
+
+#if !defined(QT_NO_MEMBER_TEMPLATES)
+
+//# define QT_SHARED_POINTER_BACKTRACE_SUPPORT
+# ifdef QT_SHARED_POINTER_BACKTRACE_SUPPORT
+# if defined(__GLIBC__) && (__GLIBC__ >= 2) && !defined(__UCLIBC__) && !defined(QT_LINUXBASE)
+# define BACKTRACE_SUPPORTED
+# elif defined(Q_OS_MACX)
+# define BACKTRACE_SUPPORTED
+# endif
+# endif
+
+# if !defined(BACKTRACE_SUPPORTED)
+// Dummy implementation of the functions.
+// Using QHashDummyValue also means that the QHash below is actually a QSet
+typedef QT_PREPEND_NAMESPACE(QHashDummyValue) Backtrace;
+
+static inline Backtrace saveBacktrace() { return Backtrace(); }
+static inline void printBacktrace(Backtrace) { }
+
+# else
+# include <sys/types.h>
+# include <execinfo.h>
+# include <stdio.h>
+# include <unistd.h>
+# include <sys/wait.h>
+
+typedef QT_PREPEND_NAMESPACE(QByteArray) Backtrace;
+
+static inline Backtrace saveBacktrace() __attribute__((always_inline));
+static inline Backtrace saveBacktrace()
+{
+ static const int maxFrames = 32;
+
+ Backtrace stacktrace;
+ stacktrace.resize(sizeof(void*) * maxFrames);
+ int stack_size = backtrace((void**)stacktrace.data(), maxFrames);
+ stacktrace.resize(sizeof(void*) * stack_size);
+
+ return stacktrace;
+}
+
+static void printBacktrace(Backtrace stacktrace)
+{
+ void *const *stack = (void *const *)stacktrace.constData();
+ int stack_size = stacktrace.size() / sizeof(void*);
+ char **stack_symbols = backtrace_symbols(stack, stack_size);
+
+ int filter[2];
+ pid_t child = -1;
+ if (pipe(filter) != -1)
+ child = fork();
+ if (child == 0) {
+ // child process
+ dup2(fileno(stderr), fileno(stdout));
+ dup2(filter[0], fileno(stdin));
+ close(filter[0]);
+ close(filter[1]);
+ execlp("c++filt", "c++filt", "-n", NULL);
+
+ // execlp failed
+ execl("/bin/cat", "/bin/cat", NULL);
+ _exit(127);
+ }
+
+ // parent process
+ close(filter[0]);
+ FILE *output;
+ if (child == -1) {
+ // failed forking
+ close(filter[1]);
+ output = stderr;
+ } else {
+ output = fdopen(filter[1], "w");
+ }
+
+ fprintf(stderr, "Backtrace of the first creation (most recent frame first):\n");
+ for (int i = 0; i < stack_size; ++i) {
+ if (strlen(stack_symbols[i]))
+ fprintf(output, "#%-2d %s\n", i, stack_symbols[i]);
+ else
+ fprintf(output, "#%-2d %p\n", i, stack[i]);
+ }
+
+ if (child != -1) {
+ fclose(output);
+ waitpid(child, 0, 0);
+ }
+}
+# endif // BACKTRACE_SUPPORTED
+
+namespace {
+ QT_USE_NAMESPACE
+ class KnownPointers
+ {
+ public:
+ QMutex mutex;
+ QHash<void *, Backtrace> values;
+ };
+}
+
+Q_GLOBAL_STATIC(KnownPointers, knownPointers)
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \internal
+*/
+void QtSharedPointer::internalSafetyCheckAdd(const volatile void *ptr)
+{
+ QMutexLocker lock(&knownPointers()->mutex);
+ void *actual = const_cast<void*>(ptr);
+ if (knownPointers()->values.contains(actual)) {
+ printBacktrace(knownPointers()->values.value(actual));
+ qFatal("QSharedPointerData: internal self-check failed: pointer %p was already tracked "
+ "by another QSharedPointerData object", actual);
+ }
+
+ knownPointers()->values.insert(actual, saveBacktrace());
+}
+
+/*!
+ \internal
+*/
+void QtSharedPointer::internalSafetyCheckRemove(const volatile void *ptr)
+{
+ QMutexLocker lock(&knownPointers()->mutex);
+ void *actual = const_cast<void*>(ptr);
+ knownPointers()->values.remove(actual);
+}
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/corelib/tools/qsharedpointer.h b/src/corelib/tools/qsharedpointer.h
new file mode 100644
index 0000000000..0a1efde8b6
--- /dev/null
+++ b/src/corelib/tools/qsharedpointer.h
@@ -0,0 +1,148 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSHAREDPOINTER_H
+#define QSHAREDPOINTER_H
+
+#include <QtCore/qglobal.h>
+#include <QtCore/qatomic.h>
+#include <QtCore/qshareddata.h>
+
+#ifndef Q_QDOC
+# if !defined(QT_NO_MEMBER_TEMPLATES)
+// QSharedPointer requires member template support
+# include <QtCore/qsharedpointer_impl.h>
+# endif
+#else
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Core)
+
+// These classes are here to fool qdoc into generating a better documentation
+
+template <class T>
+class QSharedPointer
+{
+public:
+ // basic accessor functions
+ T *data() const;
+ bool isNull() const;
+ operator bool() const;
+ bool operator!() const;
+ T &operator*() const;
+ T *operator ->() const;
+
+ // constructors
+ QSharedPointer();
+ explicit QSharedPointer(T *ptr);
+ QSharedPointer(T *ptr, Deleter d);
+ QSharedPointer(const QSharedPointer<T> &other);
+ QSharedPointer(const QWeakPointer<T> &other);
+
+ ~QSharedPointer() { }
+
+ QSharedPointer<T> &operator=(const QSharedPointer<T> &other);
+ QSharedPointer<T> &operator=(const QWeakPointer<T> &other);
+
+ QWeakPointer<T> toWeakRef() const;
+
+ void clear();
+
+ // casts:
+ template <class X> QSharedPointer<X> staticCast() const;
+ template <class X> QSharedPointer<X> dynamicCast() const;
+ template <class X> QSharedPointer<X> constCast() const;
+};
+
+template <class T>
+class QWeakPointer
+{
+public:
+ // basic accessor functions
+ bool isNull() const;
+ operator bool() const;
+ bool operator!() const;
+
+ // constructors:
+ QWeakPointer();
+ QWeakPointer(const QWeakPointer<T> &other);
+ QWeakPointer(const QSharedPointer<T> &other);
+
+ ~QWeakPointer();
+
+ QWeakPointer<T> operator=(const QWeakPointer<T> &other);
+ QWeakPointer<T> operator=(const QSharedPointer<T> &other);
+
+ void clear();
+
+ QSharedPointer<T> toStrongRef() const;
+};
+
+template<class T, class X> bool operator==(const QSharedPointer<T> &ptr1, const QSharedPointer<X> &ptr2);
+template<class T, class X> bool operator!=(const QSharedPointer<T> &ptr1, const QSharedPointer<X> &ptr2);
+template<class T, class X> bool operator==(const QSharedPointer<T> &ptr1, const X *ptr2);
+template<class T, class X> bool operator!=(const QSharedPointer<T> &ptr1, const X *ptr2);
+template<class T, class X> bool operator==(const T *ptr1, const QSharedPointer<X> &ptr2);
+template<class T, class X> bool operator!=(const T *ptr1, const QSharedPointer<X> &ptr2);
+template<class T, class X> bool operator==(const QWeakPointer<T> &ptr1, const QSharedPointer<X> &ptr2);
+template<class T, class X> bool operator!=(const QWeakPointer<T> &ptr1, const QSharedPointer<X> &ptr2);
+template<class T, class X> bool operator==(const QSharedPointer<T> &ptr1, const QWeakPointer<X> &ptr2);
+template<class T, class X> bool operator!=(const QSharedPointer<T> &ptr1, const QWeakPointer<X> &ptr2);
+
+template <class X, class T> QSharedPointer<X> qSharedPointerCast(const QSharedPointer<T> &other);
+template <class X, class T> QSharedPointer<X> qSharedPointerCast(const QWeakPointer<T> &other);
+template <class X, class T> QSharedPointer<X> qSharedPointerDynamicCast(const QSharedPointer<T> &src);
+template <class X, class T> QSharedPointer<X> qSharedPointerDynamicCast(const QWeakPointer<T> &src);
+template <class X, class T> QSharedPointer<X> qSharedPointerConstCast(const QSharedPointer<T> &src);
+template <class X, class T> QSharedPointer<X> qSharedPointerConstCast(const QWeakPointer<T> &src);
+
+template <class X, class T> QWeakPointer<X> qWeakPointerCast(const QWeakPointer<T> &src);
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // Q_QDOC
+
+#endif // QSHAREDPOINTER_H
diff --git a/src/corelib/tools/qsharedpointer_impl.h b/src/corelib/tools/qsharedpointer_impl.h
new file mode 100644
index 0000000000..f1b35ee05f
--- /dev/null
+++ b/src/corelib/tools/qsharedpointer_impl.h
@@ -0,0 +1,585 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef Q_QDOC
+
+#ifndef QSHAREDPOINTER_H
+#error Do not include qsharedpointer_impl.h directly
+#endif
+#if 0
+#pragma qt_sync_stop_processing
+#endif
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Core)
+
+// Macro QSHAREDPOINTER_VERIFY_AUTO_CAST
+// generates a compiler error if the following construct isn't valid:
+// T *ptr1;
+// X *ptr2 = ptr1;
+//
+#ifdef QT_NO_DEBUG
+# define QSHAREDPOINTER_VERIFY_AUTO_CAST(T, X) qt_noop()
+#else
+
+template<typename T> inline void qt_sharedpointer_cast_check(T *) { }
+# define QSHAREDPOINTER_VERIFY_AUTO_CAST(T, X) \
+ qt_sharedpointer_cast_check<T>(static_cast<X *>(0))
+#endif
+
+//
+// forward declarations
+//
+template <class T> class QWeakPointer;
+template <class T> class QSharedPointer;
+
+template <class X, class T>
+QSharedPointer<X> qSharedPointerCast(const QSharedPointer<T> &ptr);
+template <class X, class T>
+QSharedPointer<X> qSharedPointerDynamicCast(const QSharedPointer<T> &ptr);
+template <class X, class T>
+QSharedPointer<X> qSharedPointerConstCast(const QSharedPointer<T> &ptr);
+
+namespace QtSharedPointer {
+ template <class T> class InternalRefCount;
+ template <class T> class ExternalRefCount;
+
+ template <class X, class T> QSharedPointer<X> qStrongRefFromWeakHelper(const QWeakPointer<T> &, X*);
+ template <class X, class T> QSharedPointer<X> qSharedPointerCastHelper(const QSharedPointer<T> &src, X *);
+ template <class X, class T> QSharedPointer<X> qSharedPointerConstCastHelper(const QSharedPointer<T> &src, X *);
+
+ // used in debug mode to verify the reuse of pointers
+ Q_CORE_EXPORT void internalSafetyCheckAdd(const volatile void *);
+ Q_CORE_EXPORT void internalSafetyCheckRemove(const volatile void *);
+
+ template <class T, typename Klass, typename RetVal>
+ inline void executeDeleter(T *t, RetVal (Klass:: *memberDeleter)())
+ { (t->*memberDeleter)(); }
+ template <class T, typename Deleter>
+ inline void executeDeleter(T *t, Deleter d)
+ { d(t); }
+
+ //
+ // Depending on its template parameter, QSharedPointer derives from either
+ // QtSharedPointer::InternalRefCount or from QtSharedPointer::ExternalRefCount.
+ // Both of these classes derive from QtSharedPointer::Basic, which provides common
+ // operations,
+ //
+ template <class T>
+ class Basic
+ {
+ typedef T *Basic:: *RestrictedBool;
+ public:
+ typedef T Type;
+
+ inline T *data() const { return value; }
+ inline bool isNull() const { return !data(); }
+ inline operator RestrictedBool() const { return isNull() ? 0 : &Basic::value; }
+ inline bool operator !() const { return isNull(); }
+ inline T &operator*() const { return *data(); }
+ inline T *operator->() const { return data(); }
+
+ protected:
+ inline Basic() : value(0 * sizeof(T)) { }
+ // ~Basic();
+
+ inline void verifyReconstruction(const T *ptr)
+ {
+ Q_ASSERT_X(!ptr || value != ptr, "QSharedPointer",
+ "QSharedPointer violation: you cannot create two QSharedPointer objects "
+ "from the same pointer");
+
+ // make use of the "ptr" variable in the no-op statement below
+ // since this function is in a public header, we don't
+ // want warnings on "unused variables" to show up everywhere
+ ptr = 0;
+ }
+
+ inline void internalConstruct(T *ptr)
+ {
+#ifndef QT_NO_DEBUG
+ if (ptr) internalSafetyCheckAdd(ptr);
+#endif
+ value = ptr;
+ }
+ inline void internalDestroy()
+ {
+#ifndef QT_NO_DEBUG
+ if (value) internalSafetyCheckRemove(value);
+#endif
+ }
+
+#if defined(Q_NO_TEMPLATE_FRIENDS)
+ public:
+#else
+ template <class X> friend class QWeakPointer;
+#endif
+
+ Type *value;
+ };
+
+ struct ExternalRefCountData
+ {
+ QAtomicInt weakref;
+ QAtomicInt strongref;
+
+ inline ExternalRefCountData() : weakref(1), strongref(1) { }
+ virtual inline ~ExternalRefCountData() { Q_ASSERT(!weakref); Q_ASSERT(!strongref); }
+
+ virtual inline bool destroy() { return false; }
+ };
+
+ template <class T, typename Deleter>
+ struct ExternalRefCountWithSpecializedDeleter: public ExternalRefCountData
+ {
+ T *ptr;
+ Deleter deleter;
+
+ inline ExternalRefCountWithSpecializedDeleter(T *p, Deleter d)
+ : ptr(p), deleter(d)
+ { }
+ inline bool destroy() { executeDeleter(ptr, deleter); return true; }
+ };
+
+ template <class T>
+ class ExternalRefCount: public Basic<T>
+ {
+ typedef ExternalRefCountData Data;
+ typedef void (*DeleterFunction)(T *);
+ protected:
+ inline void ref() const { d->weakref.ref(); d->strongref.ref(); }
+ inline bool deref()
+ {
+ if (!d->strongref.deref())
+ this->internalDestroy();
+ return d->weakref.deref();
+ }
+
+ inline void internalConstruct(T *ptr)
+ {
+ Basic<T>::internalConstruct(ptr);
+ Q_ASSERT(!d);
+ if (ptr)
+ d = new Data;
+ }
+
+ template <typename Deleter>
+ inline void internalConstruct(T *ptr, Deleter deleter)
+ {
+ Basic<T>::internalConstruct(ptr);
+ Q_ASSERT(!d);
+ if (ptr)
+ d = new ExternalRefCountWithSpecializedDeleter<T, Deleter>(ptr, deleter);
+ }
+
+ inline ExternalRefCount() : d(0) { }
+ inline ~ExternalRefCount() { if (d && !deref()) delete d; }
+ inline ExternalRefCount(const ExternalRefCount<T> &other) : Basic<T>(other), d(other.d)
+ { if (d) ref(); }
+
+ template <class X>
+ inline void internalCopy(const ExternalRefCount<X> &other)
+ {
+ internalSet(other.d, other.data());
+ }
+
+ inline void internalDestroy()
+ {
+ Basic<T>::internalDestroy();
+ if (!d->destroy())
+ delete this->value;
+ }
+
+ private:
+#if defined(Q_NO_TEMPLATE_FRIENDS)
+ public:
+#else
+ template <class X> friend class ExternalRefCount;
+ template <class X> friend class QWeakPointer;
+ template <class X, class Y> friend QSharedPointer<X> qSharedPointerCastHelper(const QSharedPointer<Y> &src, X *);
+ template <class X, class Y> friend QSharedPointer<X> qSharedPointerConstCastHelper(const QSharedPointer<Y> &src, X *);
+ template <class X, class Y> friend QSharedPointer<X> QtSharedPointer::qStrongRefFromWeakHelper(const QWeakPointer<Y> &src, X *);
+#endif
+
+ inline void internalSet(Data *o, T *actual)
+ {
+ if (d == o) return;
+ if (o && !o->strongref)
+ o = 0;
+ if (o) {
+ verifyReconstruction(actual);
+ o->weakref.ref();
+ o->strongref.ref();
+ }
+ if (d && !deref())
+ delete d;
+ d = o;
+ this->value = d && d->strongref ? actual : 0;
+ }
+
+#if defined(QT_BUILD_INTERNAL)
+ public:
+#endif
+ Data *d;
+
+ private:
+ template<class X> ExternalRefCount(const InternalRefCount<X> &);
+ };
+} // namespace QtSharedPointer
+
+template <class T>
+class QSharedPointer: public QtSharedPointer::ExternalRefCount<T>
+{
+ typedef typename QtSharedPointer::ExternalRefCount<T> BaseClass;
+public:
+ inline QSharedPointer() { }
+ // inline ~QSharedPointer() { }
+
+ inline explicit QSharedPointer(T *ptr) { internalConstruct(ptr); }
+
+ template <typename Deleter>
+ inline QSharedPointer(T *ptr, Deleter d) { internalConstruct(ptr, d); }
+
+ inline QSharedPointer(const QSharedPointer<T> &other) : BaseClass(other) { }
+ inline QSharedPointer<T> &operator=(const QSharedPointer<T> &other)
+ {
+ internalCopy(other);
+ return *this;
+ }
+
+ inline QSharedPointer(const QWeakPointer<T> &other)
+ { *this = QtSharedPointer::qStrongRefFromWeakHelper(other, static_cast<T*>(0)); }
+ inline QSharedPointer<T> &operator=(const QWeakPointer<T> &other)
+ { *this = QtSharedPointer::qStrongRefFromWeakHelper(other, static_cast<T*>(0)); return *this; }
+
+ template <class X>
+ inline QSharedPointer(const QSharedPointer<X> &other) { *this = other; }
+
+ template <class X>
+ inline QSharedPointer<T> &operator=(const QSharedPointer<X> &other)
+ {
+ QSHAREDPOINTER_VERIFY_AUTO_CAST(T, X); // if you get an error in this line, the cast is invalid
+ internalCopy(other);
+ return *this;
+ }
+
+ template <class X>
+ inline QSharedPointer(const QWeakPointer<X> &other)
+ { *this = QtSharedPointer::qStrongRefFromWeakHelper(other, static_cast<T *>(0)); }
+
+ template <class X>
+ inline QSharedPointer<T> &operator=(const QWeakPointer<X> &other)
+ { *this = qStrongRefFromWeakHelper(other, static_cast<T *>(0)); return *this; }
+
+ template <class X>
+ QSharedPointer<X> staticCast() const
+ {
+ return qSharedPointerCast<X, T>(*this);
+ }
+
+ template <class X>
+ QSharedPointer<X> dynamicCast() const
+ {
+ return qSharedPointerDynamicCast<X, T>(*this);
+ }
+
+ template <class X>
+ QSharedPointer<X> constCast() const
+ {
+ return qSharedPointerConstCast<X, T>(*this);
+ }
+
+ inline void clear() { *this = QSharedPointer<T>(); }
+
+ QWeakPointer<T> toWeakRef() const;
+};
+
+template <class T>
+class QWeakPointer
+{
+ typedef T *QWeakPointer:: *RestrictedBool;
+ typedef QtSharedPointer::ExternalRefCountData Data;
+
+public:
+ inline bool isNull() const { return d == 0 || d->strongref == 0 || value == 0; }
+ inline operator RestrictedBool() const { return isNull() ? 0 : &QWeakPointer::value; }
+ inline bool operator !() const { return isNull(); }
+
+ inline QWeakPointer() : d(0), value(0) { }
+ inline ~QWeakPointer() { if (d && !d->weakref.deref()) delete d; }
+ inline QWeakPointer(const QWeakPointer<T> &o) : d(o.d), value(o.value)
+ { if (d) d->weakref.ref(); }
+ inline QWeakPointer<T> &operator=(const QWeakPointer<T> &o)
+ {
+ internalSet(o.d, o.value);
+ return *this;
+ }
+
+ inline QWeakPointer(const QSharedPointer<T> &o) : d(o.d), value(o.data())
+ { if (d) d->weakref.ref();}
+ inline QWeakPointer<T> &operator=(const QSharedPointer<T> &o)
+ {
+ internalSet(o.d, o.value);
+ return *this;
+ }
+
+ template <class X>
+ inline QWeakPointer(const QWeakPointer<X> &o) : d(0), value(0)
+ { *this = o; }
+
+ template <class X>
+ inline QWeakPointer<T> &operator=(const QWeakPointer<X> &o)
+ {
+ // conversion between X and T could require access to the virtual table
+ // so force the operation to go through QSharedPointer
+ *this = o.toStrongRef();
+ return *this;
+ }
+
+ template <class X>
+ inline bool operator==(const QWeakPointer<X> &o) const
+ { return d == o.d && value == static_cast<const T *>(o.value); }
+
+ template <class X>
+ inline bool operator!=(const QWeakPointer<X> &o) const
+ { return !(*this == o); }
+
+ template <class X>
+ inline QWeakPointer(const QSharedPointer<X> &o) : d(0), value(0)
+ { *this = o; }
+
+ template <class X>
+ inline QWeakPointer<T> &operator=(const QSharedPointer<X> &o)
+ {
+ QSHAREDPOINTER_VERIFY_AUTO_CAST(T, X); // if you get an error in this line, the cast is invalid
+ internalSet(o.d, o.data());
+ return *this;
+ }
+
+ template <class X>
+ inline bool operator==(const QSharedPointer<X> &o) const
+ { return d == o.d && value == static_cast<const T *>(o.data()); }
+
+ template <class X>
+ inline bool operator!=(const QSharedPointer<X> &o) const
+ { return !(*this == o); }
+
+ inline void clear() { *this = QWeakPointer<T>(); }
+
+ inline QSharedPointer<T> toStrongRef() const { return QSharedPointer<T>(*this); }
+
+private:
+
+#if defined(Q_NO_TEMPLATE_FRIENDS)
+public:
+#else
+ template <class X, class Y> friend QSharedPointer<X> QtSharedPointer::qStrongRefFromWeakHelper(const QWeakPointer<Y> &src, X *);
+#endif
+
+ inline void internalSet(Data *o, T *actual)
+ {
+ if (d == o) return;
+ if (o)
+ o->weakref.ref();
+ if (d && !d->weakref.deref())
+ delete d;
+ d = o;
+ value = actual;
+ }
+
+ Data *d;
+ T *value;
+};
+
+template <class T, class X>
+bool operator==(const QSharedPointer<T> &ptr1, const QSharedPointer<X> &ptr2)
+{
+ return ptr1.data() == ptr2.data();
+}
+template <class T, class X>
+bool operator!=(const QSharedPointer<T> &ptr1, const QSharedPointer<X> &ptr2)
+{
+ return ptr1.data() != ptr2.data();
+}
+
+template <class T, class X>
+bool operator==(const QSharedPointer<T> &ptr1, const X *ptr2)
+{
+ return ptr1.data() == ptr2;
+}
+template <class T, class X>
+bool operator==(const T *ptr1, const QSharedPointer<X> &ptr2)
+{
+ return ptr1 == ptr2.data();
+}
+
+template <class T, class X>
+bool operator!=(const QSharedPointer<T> &ptr1, const X *ptr2)
+{
+ return !(ptr1 == ptr2);
+}
+template <class T, class X>
+bool operator!=(const T *ptr1, const QSharedPointer<X> &ptr2)
+{
+ return !(ptr2 == ptr1);
+}
+
+template <class T, class X>
+bool operator==(const QSharedPointer<T> &ptr1, const QWeakPointer<X> &ptr2)
+{
+ return ptr2 == ptr1;
+}
+template <class T, class X>
+bool operator!=(const QSharedPointer<T> &ptr1, const QWeakPointer<X> &ptr2)
+{
+ return ptr2 != ptr1;
+}
+
+template <class T>
+Q_INLINE_TEMPLATE QWeakPointer<T> QSharedPointer<T>::toWeakRef() const
+{
+ return QWeakPointer<T>(*this);
+}
+
+namespace QtSharedPointer {
+// helper functions:
+ template <class X, class T>
+ Q_INLINE_TEMPLATE X *qVerifyStaticCast(T *src, X *)
+ {
+ return static_cast<X *>(src); // if you get an error in this line, the cast is invalid
+ }
+ template <class X, class T>
+ Q_INLINE_TEMPLATE X *qVerifyDynamicCast(T *src, X *)
+ {
+ return dynamic_cast<X *>(src); // if you get an error in this line, the cast is invalid
+ }
+ template <class X, class T>
+ Q_INLINE_TEMPLATE X *qVerifyConstCast(T *src, X *)
+ {
+ return const_cast<X *>(src); // if you get an error in this line, the cast is invalid
+ }
+
+ template <class X, class T>
+ Q_INLINE_TEMPLATE QSharedPointer<X> qSharedPointerCastHelper(const QSharedPointer<T> &src, X *)
+ {
+ QSharedPointer<X> result;
+ register T *ptr = src.data();
+ result.internalSet(src.d, static_cast<X *>(ptr));
+ return result;
+ }
+ template <class X, class T>
+ Q_INLINE_TEMPLATE QSharedPointer<X> qSharedPointerConstCastHelper(const QSharedPointer<T> &src, X *)
+ {
+ QSharedPointer<X> result;
+ register T *ptr = src.data();
+ result.internalSet(src.d, const_cast<X *>(ptr));
+ return result;
+ }
+ template <class X, class T>
+ Q_INLINE_TEMPLATE QSharedPointer<X> qStrongRefFromWeakHelper
+ (const QT_PREPEND_NAMESPACE(QWeakPointer<T>) &src, X *)
+ {
+ QSharedPointer<X> result;
+ result.internalSet(src.d, src.value);
+ return result;
+ }
+}
+
+// cast operators
+template <class X, class T>
+Q_INLINE_TEMPLATE QSharedPointer<X> qSharedPointerCast(const QSharedPointer<T> &src)
+{
+ X *x = 0;
+ QtSharedPointer::qVerifyStaticCast(src.data(), x);
+ return QtSharedPointer::qSharedPointerCastHelper(src, x);
+}
+template <class X, class T>
+Q_INLINE_TEMPLATE QSharedPointer<X> qSharedPointerCast(const QWeakPointer<T> &src)
+{
+ return qSharedPointerCast<X, T>(src.toStrongRef());
+}
+
+template <class X, class T>
+Q_INLINE_TEMPLATE QSharedPointer<X> qSharedPointerDynamicCast(const QSharedPointer<T> &src)
+{
+ X *x = 0;
+ if (QtSharedPointer::qVerifyDynamicCast(src.data(), x))
+ return QtSharedPointer::qSharedPointerCastHelper(src, x);
+ return QSharedPointer<X>();
+}
+template <class X, class T>
+Q_INLINE_TEMPLATE QSharedPointer<X> qSharedPointerDynamicCast(const QWeakPointer<T> &src)
+{
+ return qSharedPointerDynamicCast<X, T>(src.toStrongRef());
+}
+
+template <class X, class T>
+Q_INLINE_TEMPLATE QSharedPointer<X> qSharedPointerConstCast(const QSharedPointer<T> &src)
+{
+ X *x = 0;
+ if (QtSharedPointer::qVerifyConstCast(src.data(), x))
+ return QtSharedPointer::qSharedPointerConstCastHelper(src, x);
+ return QSharedPointer<X>();
+}
+template <class X, class T>
+Q_INLINE_TEMPLATE QSharedPointer<X> qSharedPointerConstCast(const QWeakPointer<T> &src)
+{
+ X *x = 0;
+ if (QtSharedPointer::qVerifyConstCast(src.data(), x))
+ return QtSharedPointer::qSharedPointerCastHelper(src, x);
+ return QSharedPointer<X>();
+}
+
+template <class X, class T>
+Q_INLINE_TEMPLATE
+QWeakPointer<X> qWeakPointerCast(const QSharedPointer<T> &src)
+{
+ return qSharedPointerCast<X, T>(src).toWeakRef();
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/corelib/tools/qsize.cpp b/src/corelib/tools/qsize.cpp
new file mode 100644
index 0000000000..76a5484377
--- /dev/null
+++ b/src/corelib/tools/qsize.cpp
@@ -0,0 +1,824 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qsize.h"
+#include "qdatastream.h"
+#include "qdebug.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QSize
+ \ingroup multimedia
+
+ \brief The QSize class defines the size of a two-dimensional
+ object using integer point precision.
+
+ A size is specified by a width() and a height(). It can be set in
+ the constructor and changed using the setWidth(), setHeight(), or
+ scale() functions, or using arithmetic operators. A size can also
+ be manipulated directly by retrieving references to the width and
+ height using the rwidth() and rheight() functions. Finally, the
+ width and height can be swapped using the transpose() function.
+
+ The isValid() function determines if a size is valid (a valid size
+ has both width and height greater than zero). The isEmpty()
+ function returns true if either of the width and height is less
+ than, or equal to, zero, while the isNull() function returns true
+ only if both the width and the height is zero.
+
+ Use the expandedTo() function to retrieve a size which holds the
+ maximum height and width of \e this size and a given
+ size. Similarly, the boundedTo() function returns a size which
+ holds the minimum height and width of \e this size and a given
+ size.
+
+ QSize objects can be streamed as well as compared.
+
+ \sa QSizeF, QPoint, QRect
+*/
+
+
+/*****************************************************************************
+ QSize member functions
+ *****************************************************************************/
+
+/*!
+ \fn QSize::QSize()
+
+ Constructs a size with an invalid width and height (i.e., isValid()
+ returns false).
+
+ \sa isValid()
+*/
+
+/*!
+ \fn QSize::QSize(int width, int height)
+
+ Constructs a size with the given \a width and \a height.
+
+ \sa setWidth(), setHeight()
+*/
+
+/*!
+ \fn bool QSize::isNull() const
+
+ Returns true if both the width and height is 0; otherwise returns
+ false.
+
+ \sa isValid(), isEmpty()
+*/
+
+/*!
+ \fn bool QSize::isEmpty() const
+
+ Returns true if either of the width and height is less than or
+ equal to 0; otherwise returns false.
+
+ \sa isNull(), isValid()
+*/
+
+/*!
+ \fn bool QSize::isValid() const
+
+ Returns true if both the width and height is equal to or greater
+ than 0; otherwise returns false.
+
+ \sa isNull(), isEmpty()
+*/
+
+/*!
+ \fn int QSize::width() const
+
+ Returns the width.
+
+ \sa height(), setWidth()
+*/
+
+/*!
+ \fn int QSize::height() const
+
+ Returns the height.
+
+ \sa width(), setHeight()
+*/
+
+/*!
+ \fn void QSize::setWidth(int width)
+
+ Sets the width to the given \a width.
+
+ \sa rwidth(), width(), setHeight()
+*/
+
+/*!
+ \fn void QSize::setHeight(int height)
+
+ Sets the height to the given \a height.
+
+ \sa rheight(), height(), setWidth()
+*/
+
+/*!
+ Swaps the width and height values.
+
+ \sa setWidth(), setHeight()
+*/
+
+void QSize::transpose()
+{
+ int tmp = wd;
+ wd = ht;
+ ht = tmp;
+}
+
+/*!
+ \fn void QSize::scale(int width, int height, Qt::AspectRatioMode mode)
+
+ Scales the size to a rectangle with the given \a width and \a
+ height, according to the specified \a mode:
+
+ \list
+ \i If \a mode is Qt::IgnoreAspectRatio, the size is set to (\a width, \a height).
+ \i If \a mode is Qt::KeepAspectRatio, the current size is scaled to a rectangle
+ as large as possible inside (\a width, \a height), preserving the aspect ratio.
+ \i If \a mode is Qt::KeepAspectRatioByExpanding, the current size is scaled to a rectangle
+ as small as possible outside (\a width, \a height), preserving the aspect ratio.
+ \endlist
+
+ Example:
+ \snippet doc/src/snippets/code/src_corelib_tools_qsize.cpp 0
+
+ \sa setWidth(), setHeight()
+*/
+
+/*!
+ \fn void QSize::scale(const QSize &size, Qt::AspectRatioMode mode)
+ \overload
+
+ Scales the size to a rectangle with the given \a size, according to
+ the specified \a mode.
+*/
+void QSize::scale(const QSize &s, Qt::AspectRatioMode mode)
+{
+ if (mode == Qt::IgnoreAspectRatio || wd == 0 || ht == 0) {
+ wd = s.wd;
+ ht = s.ht;
+ } else {
+ bool useHeight;
+ qint64 rw = qint64(s.ht) * qint64(wd) / qint64(ht);
+
+ if (mode == Qt::KeepAspectRatio) {
+ useHeight = (rw <= s.wd);
+ } else { // mode == Qt::KeepAspectRatioByExpanding
+ useHeight = (rw >= s.wd);
+ }
+
+ if (useHeight) {
+ wd = rw;
+ ht = s.ht;
+ } else {
+ ht = qint32(qint64(s.wd) * qint64(ht) / qint64(wd));
+ wd = s.wd;
+ }
+ }
+}
+
+/*!
+ \fn int &QSize::rwidth()
+
+ Returns a reference to the width.
+
+ Using a reference makes it possible to manipulate the width
+ directly. For example:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qsize.cpp 1
+
+ \sa rheight(), setWidth()
+*/
+
+/*!
+ \fn int &QSize::rheight()
+
+ Returns a reference to the height.
+
+ Using a reference makes it possible to manipulate the height
+ directly. For example:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qsize.cpp 2
+
+ \sa rwidth(), setHeight()
+*/
+
+/*!
+ \fn QSize &QSize::operator+=(const QSize &size)
+
+ Adds the given \a size to \e this size, and returns a reference to
+ this size. For example:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qsize.cpp 3
+*/
+
+/*!
+ \fn QSize &QSize::operator-=(const QSize &size)
+
+ Subtracts the given \a size from \e this size, and returns a
+ reference to this size. For example:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qsize.cpp 4
+*/
+
+/*!
+ \fn QSize &QSize::operator*=(qreal factor)
+ \overload
+
+ Multiplies both the width and height by the given \a factor, and
+ returns a reference to the size.
+
+ Note that the result is rounded to the nearest integer.
+
+ \sa scale()
+*/
+
+/*!
+ \fn bool operator==(const QSize &s1, const QSize &s2)
+ \relates QSize
+
+ Returns true if \a s1 and \a s2 are equal; otherwise returns false.
+*/
+
+/*!
+ \fn bool operator!=(const QSize &s1, const QSize &s2)
+ \relates QSize
+
+ Returns true if \a s1 and \a s2 are different; otherwise returns false.
+*/
+
+/*!
+ \fn const QSize operator+(const QSize &s1, const QSize &s2)
+ \relates QSize
+
+ Returns the sum of \a s1 and \a s2; each component is added separately.
+*/
+
+/*!
+ \fn const QSize operator-(const QSize &s1, const QSize &s2)
+ \relates QSize
+
+ Returns \a s2 subtracted from \a s1; each component is subtracted
+ separately.
+*/
+
+/*!
+ \fn const QSize operator*(const QSize &size, qreal factor)
+ \relates QSize
+
+ Multiplies the given \a size by the given \a factor, and returns
+ the result rounded to the nearest integer.
+
+ \sa QSize::scale()
+*/
+
+/*!
+ \fn const QSize operator*(qreal factor, const QSize &size)
+ \overload
+ \relates QSize
+
+ Multiplies the given \a size by the given \a factor, and returns
+ the result rounded to the nearest integer.
+*/
+
+/*!
+ \fn QSize &QSize::operator/=(qreal divisor)
+ \overload
+
+ Divides both the width and height by the given \a divisor, and
+ returns a reference to the size.
+
+ Note that the result is rounded to the nearest integer.
+
+ \sa QSize::scale()
+*/
+
+/*!
+ \fn const QSize operator/(const QSize &size, qreal divisor)
+ \relates QSize
+ \overload
+
+ Divides the given \a size by the given \a divisor, and returns the
+ result rounded to the nearest integer.
+
+ \sa QSize::scale()
+*/
+
+/*!
+ \fn QSize QSize::expandedTo(const QSize & otherSize) const
+
+ Returns a size holding the maximum width and height of this size
+ and the given \a otherSize.
+
+ \sa boundedTo(), scale()
+*/
+
+/*!
+ \fn QSize QSize::boundedTo(const QSize & otherSize) const
+
+ Returns a size holding the minimum width and height of this size
+ and the given \a otherSize.
+
+ \sa expandedTo(), scale()
+*/
+
+
+
+/*****************************************************************************
+ QSize stream functions
+ *****************************************************************************/
+#ifndef QT_NO_DATASTREAM
+/*!
+ \fn QDataStream &operator<<(QDataStream &stream, const QSize &size)
+ \relates QSize
+
+ Writes the given \a size to the given \a stream, and returns a
+ reference to the stream.
+
+ \sa {Format of the QDataStream Operators}
+*/
+
+QDataStream &operator<<(QDataStream &s, const QSize &sz)
+{
+ if (s.version() == 1)
+ s << (qint16)sz.width() << (qint16)sz.height();
+ else
+ s << (qint32)sz.width() << (qint32)sz.height();
+ return s;
+}
+
+/*!
+ \fn QDataStream &operator>>(QDataStream &stream, QSize &size)
+ \relates QSize
+
+ Reads a size from the given \a stream into the given \a size, and
+ returns a reference to the stream.
+
+ \sa {Format of the QDataStream Operators}
+*/
+
+QDataStream &operator>>(QDataStream &s, QSize &sz)
+{
+ if (s.version() == 1) {
+ qint16 w, h;
+ s >> w; sz.rwidth() = w;
+ s >> h; sz.rheight() = h;
+ }
+ else {
+ qint32 w, h;
+ s >> w; sz.rwidth() = w;
+ s >> h; sz.rheight() = h;
+ }
+ return s;
+}
+#endif // QT_NO_DATASTREAM
+
+#ifndef QT_NO_DEBUG_STREAM
+QDebug operator<<(QDebug dbg, const QSize &s) {
+ dbg.nospace() << "QSize(" << s.width() << ", " << s.height() << ')';
+ return dbg.space();
+}
+#endif
+
+
+
+/*!
+ \class QSizeF
+ \brief The QSizeF class defines the size of a two-dimensional object
+ using floating point precision.
+
+ \ingroup multimedia
+
+ A size is specified by a width() and a height(). It can be set in
+ the constructor and changed using the setWidth(), setHeight(), or
+ scale() functions, or using arithmetic operators. A size can also
+ be manipulated directly by retrieving references to the width and
+ height using the rwidth() and rheight() functions. Finally, the
+ width and height can be swapped using the transpose() function.
+
+ The isValid() function determines if a size is valid. A valid size
+ has both width and height greater than or equal to zero. The
+ isEmpty() function returns true if either of the width and height
+ is \e less than (or equal to) zero, while the isNull() function
+ returns true only if both the width and the height is zero.
+
+ Use the expandedTo() function to retrieve a size which holds the
+ maximum height and width of this size and a given
+ size. Similarly, the boundedTo() function returns a size which
+ holds the minimum height and width of this size and a given size.
+
+ The QSizeF class also provides the toSize() function returning a
+ QSize copy of this size, constructed by rounding the width and
+ height to the nearest integers.
+
+ QSizeF objects can be streamed as well as compared.
+
+ \sa QSize, QPointF, QRectF
+*/
+
+
+/*****************************************************************************
+ QSizeF member functions
+ *****************************************************************************/
+
+/*!
+ \fn QSizeF::QSizeF()
+
+ Constructs an invalid size.
+
+ \sa isValid()
+*/
+
+/*!
+ \fn QSizeF::QSizeF(const QSize &size)
+
+ Constructs a size with floating point accuracy from the given \a
+ size.
+
+ \sa toSize()
+*/
+
+/*!
+ \fn QSizeF::QSizeF(qreal width, qreal height)
+
+ Constructs a size with the given \a width and \a height.
+*/
+
+/*!
+ \fn bool QSizeF::isNull() const
+
+ Returns true if both the width and height is 0; otherwise returns
+ false.
+
+ \sa isValid(), isEmpty()
+*/
+
+/*!
+ \fn bool QSizeF::isEmpty() const
+
+ Returns true if either of the width and height is less than or
+ equal to 0; otherwise returns false.
+
+ \sa isNull(), isValid()
+*/
+
+/*!
+ \fn bool QSizeF::isValid() const
+
+ Returns true if both the width and height is equal to or greater
+ than 0; otherwise returns false.
+
+ \sa isNull(), isEmpty()
+*/
+
+/*!
+ \fn int QSizeF::width() const
+
+ Returns the width.
+
+ \sa height(), setWidth()
+*/
+
+/*!
+ \fn int QSizeF::height() const
+
+ Returns the height.
+
+ \sa width(), setHeight()
+*/
+
+/*!
+ \fn void QSizeF::setWidth(qreal width)
+
+ Sets the width to the given \a width.
+
+ \sa width(), rwidth(), setHeight()
+*/
+
+/*!
+ \fn void QSizeF::setHeight(qreal height)
+
+ Sets the height to the given \a height.
+
+ \sa height(), rheight(), setWidth()
+*/
+
+/*!
+ \fn QSize QSizeF::toSize() const
+
+ Returns an integer based copy of this size.
+
+ Note that the coordinates in the returned size will be rounded to
+ the nearest integer.
+
+ \sa QSizeF()
+*/
+
+/*!
+ Swaps the width and height values.
+
+ \sa setWidth(), setHeight()
+*/
+
+void QSizeF::transpose()
+{
+ qreal tmp = wd;
+ wd = ht;
+ ht = tmp;
+}
+
+/*!
+ \fn void QSizeF::scale(qreal width, qreal height, Qt::AspectRatioMode mode)
+
+ Scales the size to a rectangle with the given \a width and \a
+ height, according to the specified \a mode.
+
+ \list
+ \i If \a mode is Qt::IgnoreAspectRatio, the size is set to (\a width, \a height).
+ \i If \a mode is Qt::KeepAspectRatio, the current size is scaled to a rectangle
+ as large as possible inside (\a width, \a height), preserving the aspect ratio.
+ \i If \a mode is Qt::KeepAspectRatioByExpanding, the current size is scaled to a rectangle
+ as small as possible outside (\a width, \a height), preserving the aspect ratio.
+ \endlist
+
+ Example:
+ \snippet doc/src/snippets/code/src_corelib_tools_qsize.cpp 5
+
+ \sa setWidth(), setHeight()
+*/
+
+/*!
+ \fn void QSizeF::scale(const QSizeF &size, Qt::AspectRatioMode mode)
+ \overload
+
+ Scales the size to a rectangle with the given \a size, according to
+ the specified \a mode.
+*/
+void QSizeF::scale(const QSizeF &s, Qt::AspectRatioMode mode)
+{
+ if (mode == Qt::IgnoreAspectRatio || qIsNull(wd) || qIsNull(ht)) {
+ wd = s.wd;
+ ht = s.ht;
+ } else {
+ bool useHeight;
+ qreal rw = s.ht * wd / ht;
+
+ if (mode == Qt::KeepAspectRatio) {
+ useHeight = (rw <= s.wd);
+ } else { // mode == Qt::KeepAspectRatioByExpanding
+ useHeight = (rw >= s.wd);
+ }
+
+ if (useHeight) {
+ wd = rw;
+ ht = s.ht;
+ } else {
+ ht = s.wd * ht / wd;
+ wd = s.wd;
+ }
+ }
+}
+
+/*!
+ \fn int &QSizeF::rwidth()
+
+ Returns a reference to the width.
+
+ Using a reference makes it possible to manipulate the width
+ directly. For example:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qsize.cpp 6
+
+ \sa rheight(), setWidth()
+*/
+
+/*!
+ \fn int &QSizeF::rheight()
+
+ Returns a reference to the height.
+
+ Using a reference makes it possible to manipulate the height
+ directly. For example:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qsize.cpp 7
+
+ \sa rwidth(), setHeight()
+*/
+
+/*!
+ \fn QSizeF &QSizeF::operator+=(const QSizeF &size)
+
+ Adds the given \a size to this size and returns a reference to
+ this size. For example:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qsize.cpp 8
+*/
+
+/*!
+ \fn QSizeF &QSizeF::operator-=(const QSizeF &size)
+
+ Subtracts the given \a size from this size and returns a reference
+ to this size. For example:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qsize.cpp 9
+*/
+
+/*!
+ \fn QSizeF &QSizeF::operator*=(qreal factor)
+ \overload
+
+ Multiplies both the width and height by the given \a factor and
+ returns a reference to the size.
+
+ \sa scale()
+*/
+
+/*!
+ \fn bool operator==(const QSizeF &s1, const QSizeF &s2)
+ \relates QSizeF
+
+ Returns true if \a s1 and \a s2 are equal; otherwise returns
+ false.
+*/
+
+/*!
+ \fn bool operator!=(const QSizeF &s1, const QSizeF &s2)
+ \relates QSizeF
+
+ Returns true if \a s1 and \a s2 are different; otherwise returns false.
+*/
+
+/*!
+ \fn const QSizeF operator+(const QSizeF &s1, const QSizeF &s2)
+ \relates QSizeF
+
+ Returns the sum of \a s1 and \a s2; each component is added separately.
+*/
+
+/*!
+ \fn const QSizeF operator-(const QSizeF &s1, const QSizeF &s2)
+ \relates QSizeF
+
+ Returns \a s2 subtracted from \a s1; each component is subtracted
+ separately.
+*/
+
+/*!
+ \fn const QSizeF operator*(const QSizeF &size, qreal factor)
+
+ \overload
+ \relates QSizeF
+
+ Multiplies the given \a size by the given \a factor and returns
+ the result.
+
+ \sa QSizeF::scale()
+*/
+
+/*!
+ \fn const QSizeF operator*(qreal factor, const QSizeF &size)
+
+ \overload
+ \relates QSizeF
+
+ Multiplies the given \a size by the given \a factor and returns
+ the result.
+*/
+
+/*!
+ \fn QSizeF &QSizeF::operator/=(qreal divisor)
+
+ \overload
+
+ Divides both the width and height by the given \a divisor and
+ returns a reference to the size.
+
+ \sa scale()
+*/
+
+/*!
+ \fn const QSizeF operator/(const QSizeF &size, qreal divisor)
+
+ \relates QSizeF
+ \overload
+
+ Divides the given \a size by the given \a divisor and returns the
+ result.
+
+ \sa QSizeF::scale()
+*/
+
+/*!
+ \fn QSizeF QSizeF::expandedTo(const QSizeF & otherSize) const
+
+ Returns a size holding the maximum width and height of this size
+ and the given \a otherSize.
+
+ \sa boundedTo(), scale()
+*/
+
+/*!
+ \fn QSizeF QSizeF::boundedTo(const QSizeF & otherSize) const
+
+ Returns a size holding the minimum width and height of this size
+ and the given \a otherSize.
+
+ \sa expandedTo(), scale()
+*/
+
+
+
+/*****************************************************************************
+ QSizeF stream functions
+ *****************************************************************************/
+#ifndef QT_NO_DATASTREAM
+/*!
+ \fn QDataStream &operator<<(QDataStream &stream, const QSizeF &size)
+ \relates QSizeF
+
+ Writes the the given \a size to the given \a stream and returns a
+ reference to the stream.
+
+ \sa {Format of the QDataStream Operators}
+*/
+
+QDataStream &operator<<(QDataStream &s, const QSizeF &sz)
+{
+ s << double(sz.width()) << double(sz.height());
+ return s;
+}
+
+/*!
+ \fn QDataStream &operator>>(QDataStream &stream, QSizeF &size)
+ \relates QSizeF
+
+ Reads a size from the given \a stream into the given \a size and
+ returns a reference to the stream.
+
+ \sa {Format of the QDataStream Operators}
+*/
+
+QDataStream &operator>>(QDataStream &s, QSizeF &sz)
+{
+ double w, h;
+ s >> w;
+ s >> h;
+ sz.setWidth(qreal(w));
+ sz.setHeight(qreal(h));
+ return s;
+}
+#endif // QT_NO_DATASTREAM
+
+#ifndef QT_NO_DEBUG_STREAM
+QDebug operator<<(QDebug dbg, const QSizeF &s) {
+ dbg.nospace() << "QSizeF(" << s.width() << ", " << s.height() << ')';
+ return dbg.space();
+}
+#endif
+
+QT_END_NAMESPACE
diff --git a/src/corelib/tools/qsize.h b/src/corelib/tools/qsize.h
new file mode 100644
index 0000000000..57c55ca5b7
--- /dev/null
+++ b/src/corelib/tools/qsize.h
@@ -0,0 +1,364 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSIZE_H
+#define QSIZE_H
+
+#include <QtCore/qnamespace.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Core)
+
+class Q_CORE_EXPORT QSize
+{
+public:
+ QSize();
+ QSize(int w, int h);
+
+ bool isNull() const;
+ bool isEmpty() const;
+ bool isValid() const;
+
+ int width() const;
+ int height() const;
+ void setWidth(int w);
+ void setHeight(int h);
+ void transpose();
+
+ void scale(int w, int h, Qt::AspectRatioMode mode);
+ void scale(const QSize &s, Qt::AspectRatioMode mode);
+
+ QSize expandedTo(const QSize &) const;
+ QSize boundedTo(const QSize &) const;
+
+ int &rwidth();
+ int &rheight();
+
+ QSize &operator+=(const QSize &);
+ QSize &operator-=(const QSize &);
+ QSize &operator*=(qreal c);
+ QSize &operator/=(qreal c);
+
+ friend inline bool operator==(const QSize &, const QSize &);
+ friend inline bool operator!=(const QSize &, const QSize &);
+ friend inline const QSize operator+(const QSize &, const QSize &);
+ friend inline const QSize operator-(const QSize &, const QSize &);
+ friend inline const QSize operator*(const QSize &, qreal);
+ friend inline const QSize operator*(qreal, const QSize &);
+ friend inline const QSize operator/(const QSize &, qreal);
+
+private:
+ int wd;
+ int ht;
+};
+Q_DECLARE_TYPEINFO(QSize, Q_MOVABLE_TYPE);
+
+/*****************************************************************************
+ QSize stream functions
+ *****************************************************************************/
+
+Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QSize &);
+Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QSize &);
+
+
+/*****************************************************************************
+ QSize inline functions
+ *****************************************************************************/
+
+inline QSize::QSize()
+{ wd = ht = -1; }
+
+inline QSize::QSize(int w, int h)
+{ wd = w; ht = h; }
+
+inline bool QSize::isNull() const
+{ return wd==0 && ht==0; }
+
+inline bool QSize::isEmpty() const
+{ return wd<1 || ht<1; }
+
+inline bool QSize::isValid() const
+{ return wd>=0 && ht>=0; }
+
+inline int QSize::width() const
+{ return wd; }
+
+inline int QSize::height() const
+{ return ht; }
+
+inline void QSize::setWidth(int w)
+{ wd = w; }
+
+inline void QSize::setHeight(int h)
+{ ht = h; }
+
+inline void QSize::scale(int w, int h, Qt::AspectRatioMode mode)
+{ scale(QSize(w, h), mode); }
+
+inline int &QSize::rwidth()
+{ return wd; }
+
+inline int &QSize::rheight()
+{ return ht; }
+
+inline QSize &QSize::operator+=(const QSize &s)
+{ wd+=s.wd; ht+=s.ht; return *this; }
+
+inline QSize &QSize::operator-=(const QSize &s)
+{ wd-=s.wd; ht-=s.ht; return *this; }
+
+inline QSize &QSize::operator*=(qreal c)
+{ wd = qRound(wd*c); ht = qRound(ht*c); return *this; }
+
+inline bool operator==(const QSize &s1, const QSize &s2)
+{ return s1.wd == s2.wd && s1.ht == s2.ht; }
+
+inline bool operator!=(const QSize &s1, const QSize &s2)
+{ return s1.wd != s2.wd || s1.ht != s2.ht; }
+
+inline const QSize operator+(const QSize & s1, const QSize & s2)
+{ return QSize(s1.wd+s2.wd, s1.ht+s2.ht); }
+
+inline const QSize operator-(const QSize &s1, const QSize &s2)
+{ return QSize(s1.wd-s2.wd, s1.ht-s2.ht); }
+
+inline const QSize operator*(const QSize &s, qreal c)
+{ return QSize(qRound(s.wd*c), qRound(s.ht*c)); }
+
+inline const QSize operator*(qreal c, const QSize &s)
+{ return QSize(qRound(s.wd*c), qRound(s.ht*c)); }
+
+inline QSize &QSize::operator/=(qreal c)
+{
+ Q_ASSERT(!qFuzzyCompare(c + 1, 1));
+ wd = qRound(wd/c); ht = qRound(ht/c);
+ return *this;
+}
+
+inline const QSize operator/(const QSize &s, qreal c)
+{
+ Q_ASSERT(!qFuzzyCompare(c + 1, 1));
+ return QSize(qRound(s.wd/c), qRound(s.ht/c));
+}
+
+inline QSize QSize::expandedTo(const QSize & otherSize) const
+{
+ return QSize(qMax(wd,otherSize.wd), qMax(ht,otherSize.ht));
+}
+
+inline QSize QSize::boundedTo(const QSize & otherSize) const
+{
+ return QSize(qMin(wd,otherSize.wd), qMin(ht,otherSize.ht));
+}
+
+#ifndef QT_NO_DEBUG_STREAM
+Q_CORE_EXPORT QDebug operator<<(QDebug, const QSize &);
+#endif
+
+
+class Q_CORE_EXPORT QSizeF
+{
+public:
+ QSizeF();
+ QSizeF(const QSize &sz);
+ QSizeF(qreal w, qreal h);
+
+ bool isNull() const;
+ bool isEmpty() const;
+ bool isValid() const;
+
+ qreal width() const;
+ qreal height() const;
+ void setWidth(qreal w);
+ void setHeight(qreal h);
+ void transpose();
+
+ void scale(qreal w, qreal h, Qt::AspectRatioMode mode);
+ void scale(const QSizeF &s, Qt::AspectRatioMode mode);
+
+ QSizeF expandedTo(const QSizeF &) const;
+ QSizeF boundedTo(const QSizeF &) const;
+
+ qreal &rwidth();
+ qreal &rheight();
+
+ QSizeF &operator+=(const QSizeF &);
+ QSizeF &operator-=(const QSizeF &);
+ QSizeF &operator*=(qreal c);
+ QSizeF &operator/=(qreal c);
+
+ friend inline bool operator==(const QSizeF &, const QSizeF &);
+ friend inline bool operator!=(const QSizeF &, const QSizeF &);
+ friend inline const QSizeF operator+(const QSizeF &, const QSizeF &);
+ friend inline const QSizeF operator-(const QSizeF &, const QSizeF &);
+ friend inline const QSizeF operator*(const QSizeF &, qreal);
+ friend inline const QSizeF operator*(qreal, const QSizeF &);
+ friend inline const QSizeF operator/(const QSizeF &, qreal);
+
+ inline QSize toSize() const;
+
+private:
+ qreal wd;
+ qreal ht;
+};
+Q_DECLARE_TYPEINFO(QSizeF, Q_MOVABLE_TYPE);
+
+
+/*****************************************************************************
+ QSizeF stream functions
+ *****************************************************************************/
+
+Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QSizeF &);
+Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QSizeF &);
+
+
+/*****************************************************************************
+ QSizeF inline functions
+ *****************************************************************************/
+
+inline QSizeF::QSizeF()
+{ wd = ht = -1.; }
+
+inline QSizeF::QSizeF(const QSize &sz)
+ : wd(sz.width()), ht(sz.height())
+{
+}
+
+inline QSizeF::QSizeF(qreal w, qreal h)
+{ wd = w; ht = h; }
+
+inline bool QSizeF::isNull() const
+{ return qIsNull(wd) && qIsNull(ht); }
+
+inline bool QSizeF::isEmpty() const
+{ return wd <= 0. || ht <= 0.; }
+
+inline bool QSizeF::isValid() const
+{ return wd >= 0. && ht >= 0.; }
+
+inline qreal QSizeF::width() const
+{ return wd; }
+
+inline qreal QSizeF::height() const
+{ return ht; }
+
+inline void QSizeF::setWidth(qreal w)
+{ wd = w; }
+
+inline void QSizeF::setHeight(qreal h)
+{ ht = h; }
+
+inline void QSizeF::scale(qreal w, qreal h, Qt::AspectRatioMode mode)
+{ scale(QSizeF(w, h), mode); }
+
+inline qreal &QSizeF::rwidth()
+{ return wd; }
+
+inline qreal &QSizeF::rheight()
+{ return ht; }
+
+inline QSizeF &QSizeF::operator+=(const QSizeF &s)
+{ wd += s.wd; ht += s.ht; return *this; }
+
+inline QSizeF &QSizeF::operator-=(const QSizeF &s)
+{ wd -= s.wd; ht -= s.ht; return *this; }
+
+inline QSizeF &QSizeF::operator*=(qreal c)
+{ wd *= c; ht *= c; return *this; }
+
+inline bool operator==(const QSizeF &s1, const QSizeF &s2)
+{ return qFuzzyCompare(s1.wd, s2.wd) && qFuzzyCompare(s1.ht, s2.ht); }
+
+inline bool operator!=(const QSizeF &s1, const QSizeF &s2)
+{ return !qFuzzyCompare(s1.wd, s2.wd) || !qFuzzyCompare(s1.ht, s2.ht); }
+
+inline const QSizeF operator+(const QSizeF & s1, const QSizeF & s2)
+{ return QSizeF(s1.wd+s2.wd, s1.ht+s2.ht); }
+
+inline const QSizeF operator-(const QSizeF &s1, const QSizeF &s2)
+{ return QSizeF(s1.wd-s2.wd, s1.ht-s2.ht); }
+
+inline const QSizeF operator*(const QSizeF &s, qreal c)
+{ return QSizeF(s.wd*c, s.ht*c); }
+
+inline const QSizeF operator*(qreal c, const QSizeF &s)
+{ return QSizeF(s.wd*c, s.ht*c); }
+
+inline QSizeF &QSizeF::operator/=(qreal c)
+{
+ Q_ASSERT(!qFuzzyCompare(c + 1, 1));
+ wd = wd/c; ht = ht/c;
+ return *this;
+}
+
+inline const QSizeF operator/(const QSizeF &s, qreal c)
+{
+ Q_ASSERT(!qFuzzyCompare(c + 1, 1));
+ return QSizeF(s.wd/c, s.ht/c);
+}
+
+inline QSizeF QSizeF::expandedTo(const QSizeF & otherSize) const
+{
+ return QSizeF(qMax(wd,otherSize.wd), qMax(ht,otherSize.ht));
+}
+
+inline QSizeF QSizeF::boundedTo(const QSizeF & otherSize) const
+{
+ return QSizeF(qMin(wd,otherSize.wd), qMin(ht,otherSize.ht));
+}
+
+inline QSize QSizeF::toSize() const
+{
+ return QSize(qRound(wd), qRound(ht));
+}
+
+#ifndef QT_NO_DEBUG_STREAM
+Q_CORE_EXPORT QDebug operator<<(QDebug, const QSizeF &);
+#endif
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QSIZE_H
diff --git a/src/corelib/tools/qstack.cpp b/src/corelib/tools/qstack.cpp
new file mode 100644
index 0000000000..9fdaf0ddfa
--- /dev/null
+++ b/src/corelib/tools/qstack.cpp
@@ -0,0 +1,129 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \class QStack
+ \brief The QStack class is a template class that provides a stack.
+
+ \ingroup tools
+ \ingroup shared
+ \mainclass
+ \reentrant
+
+ QStack\<T\> is one of Qt's generic \l{container classes}. It implements
+ a stack data structure for items of a same type.
+
+ A stack is a last in, first out (LIFO) structure. Items are added
+ to the top of the stack using push() and retrieved from the top
+ using pop(). The top() function provides access to the topmost
+ item without removing it.
+
+ Example:
+
+ \snippet doc/src/snippets/qstack/main.cpp 0
+
+ The example will output 3, 2, 1 in that order.
+
+ QStack inherits from QVector. All of QVector's functionality also
+ applies to QStack. For example, you can use isEmpty() to test
+ whether the stack is empty, and you can traverse a QStack using
+ QVector's iterator classes (for example, QVectorIterator). But in
+ addition, QStack provides three convenience functions that make
+ it easy to implement LIFO semantics: push(), pop(), and top().
+
+ QStack's value type must be an \l{assignable data type}. This
+ covers most data types that are commonly used, but the compiler
+ won't let you, for example, store a QWidget as a value; instead,
+ store a QWidget *.
+
+ \sa QVector, QQueue
+*/
+
+/*!
+ \fn QStack::QStack()
+
+ Constructs an empty stack.
+*/
+
+/*!
+ \fn QStack::~QStack()
+
+ Destroys the stack. References to the values in the stack, and all
+ iterators over this stack, become invalid.
+*/
+
+/*!
+ \fn void QStack::push(const T& t)
+
+ Adds element \a t to the top of the stack.
+
+ This is the same as QVector::append().
+
+ \sa pop(), top()
+*/
+
+/*!
+ \fn T& QStack::top()
+
+ Returns a reference to the stack's top item. This function
+ assumes that the stack isn't empty.
+
+ This is the same as QVector::last().
+
+ \sa pop(), push(), isEmpty()
+*/
+
+/*!
+ \fn const T& QStack::top() const
+
+ \overload
+
+ \sa pop(), push()
+*/
+
+/*!
+ \fn T QStack::pop()
+
+ Removes the top item from the stack and returns it. This function
+ assumes that the stack isn't empty.
+
+ \sa top(), push(), isEmpty()
+*/
diff --git a/src/corelib/tools/qstack.h b/src/corelib/tools/qstack.h
new file mode 100644
index 0000000000..f55b53db4d
--- /dev/null
+++ b/src/corelib/tools/qstack.h
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSTACK_H
+#define QSTACK_H
+
+#include <QtCore/qvector.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Core)
+
+template<class T>
+class QStack : public QVector<T>
+{
+public:
+ inline QStack() {}
+ inline ~QStack() {}
+ inline void push(const T &t) { QVector<T>::append(t); }
+ T pop();
+ T &top();
+ const T &top() const;
+};
+
+template<class T>
+inline T QStack<T>::pop()
+{ Q_ASSERT(!this->isEmpty()); T t = this->data()[this->size() -1];
+ this->resize(this->size()-1); return t; }
+
+template<class T>
+inline T &QStack<T>::top()
+{ Q_ASSERT(!this->isEmpty()); this->detach(); return this->data()[this->size()-1]; }
+
+template<class T>
+inline const T &QStack<T>::top() const
+{ Q_ASSERT(!this->isEmpty()); return this->data()[this->size()-1]; }
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QSTACK_H
diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp
new file mode 100644
index 0000000000..1b29adcfd2
--- /dev/null
+++ b/src/corelib/tools/qstring.cpp
@@ -0,0 +1,8083 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qstringlist.h"
+#include "qregexp.h"
+#include "qunicodetables_p.h"
+#ifndef QT_NO_TEXTCODEC
+#include <qtextcodec.h>
+#endif
+#include <qdatastream.h>
+#include <qlist.h>
+#include "qlocale.h"
+#include "qlocale_p.h"
+#include "qstringmatcher.h"
+#include "qvarlengtharray.h"
+#include "qtools_p.h"
+#include "qhash.h"
+#include "qdebug.h"
+
+#ifdef Q_OS_MAC
+#include <private/qcore_mac_p.h>
+#endif
+
+#include <private/qfunctions_p.h>
+
+#if defined(Q_OS_WINCE)
+#include <windows.h>
+#include <winnls.h>
+#endif
+
+#include <limits.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+#ifdef truncate
+#undef truncate
+#endif
+
+#include "qchar.cpp"
+#include "qstringmatcher.cpp"
+
+#ifndef LLONG_MAX
+#define LLONG_MAX qint64_C(9223372036854775807)
+#endif
+#ifndef LLONG_MIN
+#define LLONG_MIN (-LLONG_MAX - qint64_C(1))
+#endif
+#ifndef ULLONG_MAX
+#define ULLONG_MAX quint64_C(18446744073709551615)
+#endif
+
+QT_BEGIN_NAMESPACE
+
+#ifndef QT_NO_TEXTCODEC
+QTextCodec *QString::codecForCStrings;
+#endif
+
+#ifdef QT3_SUPPORT
+static QHash<void *, QByteArray> *asciiCache = 0;
+#endif
+
+// internal
+int qFindString(const QChar *haystack, int haystackLen, int from,
+ const QChar *needle, int needleLen, Qt::CaseSensitivity cs);
+int qFindStringBoyerMoore(const QChar *haystack, int haystackLen, int from,
+ const QChar *needle, int needleLen, Qt::CaseSensitivity cs);
+
+
+// Unicode case-insensitive comparison
+static int ucstricmp(const ushort *a, const ushort *ae, const ushort *b, const ushort *be)
+{
+ if (a == b)
+ return 0;
+ if (a == 0)
+ return 1;
+ if (b == 0)
+ return -1;
+
+ const ushort *e = ae;
+ if (be - b < ae - a)
+ e = a + (be - b);
+
+ uint alast = 0;
+ uint blast = 0;
+ while (a != e) {
+// qDebug() << hex << alast << blast;
+// qDebug() << hex << "*a=" << *a << "alast=" << alast << "folded=" << foldCase (*a, alast);
+// qDebug() << hex << "*b=" << *b << "blast=" << blast << "folded=" << foldCase (*b, blast);
+ int diff = foldCase(*a, alast) - foldCase(*b, blast);
+ if ((diff))
+ return diff;
+ ++a;
+ ++b;
+ }
+ if (a == ae) {
+ if (b == be)
+ return 0;
+ return -1;
+ }
+ return 1;
+}
+
+// Case-insensitive comparison between a Unicode string and a QLatin1String
+static int ucstricmp(const ushort *a, const ushort *ae, const uchar *b)
+{
+ if (a == 0) {
+ if (b == 0)
+ return 0;
+ return 1;
+ }
+ if (b == 0)
+ return -1;
+
+ while (a != ae && *b) {
+ int diff = foldCase(*a) - foldCase(*b);
+ if ((diff))
+ return diff;
+ ++a;
+ ++b;
+ }
+ if (a == ae) {
+ if (!*b)
+ return 0;
+ return -1;
+ }
+ return 1;
+}
+
+// Unicode case-insensitive comparison
+static int ucstrcmp(const QChar *a, int alen, const QChar *b, int blen)
+{
+ if (a == b)
+ return 0;
+ int l = qMin(alen, blen);
+ while (l-- && *a == *b)
+ a++,b++;
+ if (l == -1)
+ return (alen-blen);
+ return a->unicode() - b->unicode();
+}
+
+// Unicode case-sensitive compare two same-sized strings
+static int ucstrncmp(const QChar *a, const QChar *b, int l)
+{
+ while (l-- && *a == *b)
+ a++,b++;
+ if (l==-1)
+ return 0;
+ return a->unicode() - b->unicode();
+}
+
+// Unicode case-insensitive compare two same-sized strings
+static int ucstrnicmp(const ushort *a, const ushort *b, int l)
+{
+ return ucstricmp(a, a + l, b, b + l);
+}
+
+
+/*!
+ \internal
+
+ Returns the index position of the first occurrence of the
+ character \a ch in the string given by \a str and \a len,
+ searching forward from index
+ position \a from. Returns -1 if \a ch could not be found.
+*/
+static int findChar(const QChar *str, int len, QChar ch, int from,
+ Qt::CaseSensitivity cs)
+{
+ const ushort *s = (const ushort *)str;
+ ushort c = ch.unicode();
+ if (from < 0)
+ from = qMax(from + len, 0);
+ if (from < len) {
+ const ushort *n = s + from - 1;
+ const ushort *e = s + len;
+ if (cs == Qt::CaseSensitive) {
+ while (++n != e)
+ if (*n == c)
+ return n - s;
+ } else {
+ c = foldCase(c);
+ while (++n != e)
+ if (foldCase(*n) == c)
+ return n - s;
+ }
+ }
+ return -1;
+}
+
+#define REHASH(a) \
+ if (sl_minus_1 < (int)sizeof(int) * CHAR_BIT) \
+ hashHaystack -= (a) << sl_minus_1; \
+ hashHaystack <<= 1
+
+inline bool qIsUpper(char ch)
+{
+ return ch >= 'A' && ch <= 'Z';
+}
+
+inline bool qIsDigit(char ch)
+{
+ return ch >= '0' && ch <= '9';
+}
+
+inline char qToLower(char ch)
+{
+ if (ch >= 'A' && ch <= 'Z')
+ return ch - 'A' + 'a';
+ else
+ return ch;
+}
+
+#if defined(Q_CC_MSVC) && _MSC_VER <= 1300
+const QString::Null QString::null;
+#else
+const QString::Null QString::null = { };
+#endif
+
+/*!
+ \macro QT_NO_CAST_FROM_ASCII
+ \relates QString
+
+ Disables automatic conversions from 8-bit strings (char *) to unicode QStrings
+
+ \sa QT_NO_CAST_TO_ASCII, QT_NO_CAST_FROM_BYTEARRAY
+*/
+
+/*!
+ \macro QT_NO_CAST_TO_ASCII
+ \relates QString
+
+ disables automatic conversion from QString to ASCII 8-bit strings (char *)
+
+ \sa QT_NO_CAST_FROM_ASCII, QT_NO_CAST_FROM_BYTEARRAY
+*/
+
+/*!
+ \macro QT_ASCII_CAST_WARNINGS
+ \internal
+ \relates QString
+
+ This macro can be defined to force a warning whenever a function is
+ called that automatically converts between unicode and 8-bit encodings.
+
+ Note: This only works for compilers that support warnings for
+ deprecated API.
+
+ \sa QT_NO_CAST_TO_ASCII, QT_NO_CAST_FROM_ASCII
+*/
+
+/*!
+ \class QCharRef
+ \reentrant
+ \brief The QCharRef class is a helper class for QString.
+
+ \internal
+
+ \ingroup text
+
+ When you get an object of type QCharRef, if you can assign to it,
+ the assignment will apply to the character in the string from
+ which you got the reference. That is its whole purpose in life.
+ The QCharRef becomes invalid once modifications are made to the
+ string: if you want to keep the character, copy it into a QChar.
+
+ Most of the QChar member functions also exist in QCharRef.
+ However, they are not explicitly documented here.
+
+ \sa QString::operator[]() QString::at() QChar
+*/
+
+/*!
+ \class QString
+ \reentrant
+
+ \brief The QString class provides a Unicode character string.
+
+ \ingroup tools
+ \ingroup shared
+ \ingroup text
+ \mainclass
+
+ QString stores a string of 16-bit \l{QChar}s, where each QChar
+ corresponds one Unicode 4.0 character. (Unicode characters
+ with code values above 65535 are stored using surrogate pairs,
+ i.e., two consecutive \l{QChar}s.)
+
+ \l{Unicode} is an international standard that supports most of
+ the writing systems in use today. It is a superset of ASCII and
+ Latin-1 (ISO 8859-1), and all the ASCII/Latin-1 characters are
+ available at the same code positions.
+
+ Behind the scenes, QString uses \l{implicit sharing}
+ (copy-on-write) to reduce memory usage and to avoid the needless
+ copying of data. This also helps reduce the inherent overhead of
+ storing 16-bit characters instead of 8-bit characters.
+
+ In addition to QString, Qt also provides the QByteArray class to
+ store raw bytes and traditional 8-bit '\\0'-terminated strings.
+ For most purposes, QString is the class you want to use. It is
+ used throughout the Qt API, and the Unicode support ensures that
+ your applications will be easy to translate if you want to expand
+ your application's market at some point. 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
+ \l{Qt for Embedded Linux}).
+
+ \tableofcontents
+
+ \section1 Initializing a String
+
+ One way to initialize a QString is simply to pass a \c{const char
+ *} to its constructor. For example, the following code creates a
+ QString of size 5 containing the data "Hello":
+
+ \snippet doc/src/snippets/qstring/main.cpp 0
+
+ QString converts the \c{const char *} data into Unicode using the
+ fromAscii() function. By default, fromAscii() treats character
+ above 128 as Latin-1 characters, but this can be changed by
+ calling QTextCodec::setCodecForCStrings().
+
+ In all of the QString functions that take \c{const char *}
+ parameters, the \c{const char *} is interpreted as a classic
+ C-style '\\0'-terminated string. It is legal for the \c{const char
+ *} parameter to be 0.
+
+ You can also provide string data as an array of \l{QChar}s:
+
+ \snippet doc/src/snippets/qstring/main.cpp 1
+
+ QString makes a deep copy of the QChar 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 QString::fromRawData() instead.)
+
+ Another approach is to set the size of the string using resize()
+ and to initialize the data character per character. QString uses
+ 0-based indexes, just like C++ arrays. To access the character at
+ a particular index position, you can use \l operator[](). On
+ non-const strings, \l operator[]() returns a reference to a
+ character that can be used on the left side of an assignment. For
+ example:
+
+ \snippet doc/src/snippets/qstring/main.cpp 2
+
+ For read-only access, an alternative syntax is to use the at()
+ function:
+
+ \snippet doc/src/snippets/qstring/main.cpp 3
+
+ The at() function can be faster than \l operator[](), because it
+ never causes a \l{deep copy} to occur. Alternatively, use the
+ left(), right(), or mid() functions to extract several characters
+ at a time.
+
+ A QString can embed '\\0' characters (QChar::Null). The size()
+ function always returns the size of the whole string, including
+ embedded '\\0' characters.
+
+ After a call to the resize() function, newly allocated characters
+ have undefined values. To set all the characters in the string to
+ a particular value, use the fill() function.
+
+ QString provides dozens of overloads designed to simplify string
+ usage. For example, if you want to compare a QString with a string
+ literal, you can write code like this and it will work as expected:
+
+ \snippet doc/src/snippets/qstring/main.cpp 4
+
+ You can also pass string literals to functions that take QStrings
+ as arguments, invoking the QString(const char *)
+ constructor. Similarly, you can pass a QString to a function that
+ takes a \c{const char *} argument using the \l qPrintable() macro
+ which returns the given QString as a \c{const char *}. This is
+ equivalent to calling <QString>.toLocal8Bit().constData().
+
+ \section1 Manipulating String Data
+
+ QString provides the following basic functions for modifying the
+ character data: append(), prepend(), insert(), replace(), and
+ remove(). For example:
+
+ \snippet doc/src/snippets/qstring/main.cpp 5
+
+ If you are building a QString gradually and know in advance
+ approximately how many characters the QString will contain, you
+ can call reserve(), asking QString to preallocate a certain amount
+ of memory. You can also call capacity() to find out how much
+ memory QString actually allocated.
+
+ The replace() and remove() functions' first two arguments are the
+ position from which to start erasing and the number of characters
+ that should be erased. If you want to replace all occurrences of
+ a particular substring with another, use one of the two-parameter
+ replace() overloads.
+
+ A frequent requirement is to remove whitespace characters from a
+ string ('\\n', '\\t', ' ', etc.). If you want to remove whitespace
+ from both ends of a QString, use the trimmed() function. If you
+ want to remove whitespace from both ends and replace multiple
+ consecutive whitespaces with a single space character within the
+ string, use simplified().
+
+ If you want to find all occurrences of a particular character or
+ substring in a QString, use the indexOf() or lastIndexOf()
+ functions. 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 doc/src/snippets/qstring/main.cpp 6
+
+ QString provides many functions for converting numbers into
+ strings and strings into numbers. See the arg() functions, the
+ setNum() functions, the number() static functions, and the
+ toInt(), toDouble(), and similar functions.
+
+ To get an upper- or lowercase version of a string use toUpper() or
+ toLower().
+
+ Lists of strings are handled by the QStringList class. You can
+ split a string into a list of strings using the split() function,
+ and join a list of strings into a single string with an optional
+ separator using QStringList::join(). You can obtain a list of
+ strings from a string list that contain a particular substring or
+ that match a particular QRegExp using the QStringList::find()
+ function.
+:
+ \section1 Querying String Data
+
+ If you want to see if a QString starts or ends with a particular
+ substring use startsWith() or endsWith(). If you simply want to
+ check whether a QString contains a particular character or
+ substring, use the contains() function. If you want to find out
+ how many times a particular character or substring occurs in the
+ string, use count().
+
+ QStrings can be compared using overloaded operators such as \l
+ operator<(), \l operator<=(), \l operator==(), \l operator>=(),
+ and so on. Note that the comparison is based exclusively on the
+ numeric Unicode values of the characters. It is very fast, but is
+ not what a human would expect; the QString::localeAwareCompare()
+ function is a better choice for sorting user-interface strings.
+
+ To obtain a pointer to the actual character data, call data() or
+ constData(). These functions return a pointer to the beginning of
+ the QChar data. The pointer is guaranteed to remain valid until a
+ non-const function is called on the QString.
+
+ \section1 Converting Between 8-Bit Strings and Unicode Strings
+
+ QString provides the following four functions that return a
+ \c{const char *} version of the string as QByteArray: toAscii(),
+ toLatin1(), toUtf8(), and toLocal8Bit().
+
+ \list
+ \o toAscii() returns an ASCII encoded 8-bit string.
+ \o toLatin1() returns a Latin-1 (ISO 8859-1) encoded 8-bit string.
+ \o toUtf8() returns a UTF-8 encoded 8-bit string. UTF-8 is a
+ superset of ASCII that supports the entire Unicode character
+ set through multibyte sequences.
+ \o toLocal8Bit() returns an 8-bit string using the system's local
+ encoding.
+ \endlist
+
+ To convert from one of these encodings, QString provides
+ fromAscii(), fromLatin1(), fromUtf8(), and fromLocal8Bit(). Other
+ encodings are supported through the QTextCodec class.
+
+ As mentioned above, QString provides a lot of functions and
+ operators that make it easy to interoperate with \c{const char *}
+ strings. But this functionality is a double-edged sword: It makes
+ QString more convenient to use if all strings are ASCII or
+ Latin-1, but there is always the risk that an implicit conversion
+ from or to \c{const char *} is done using the wrong 8-bit
+ encoding. To minimize these risks, you can turn off these implicit
+ conversions by defining the following two preprocessor symbols:
+
+ \list
+ \o \c QT_NO_CAST_FROM_ASCII disables automatic conversions from
+ ASCII to Unicode.
+ \o \c QT_NO_CAST_TO_ASCII disables automatic conversion from QString
+ to ASCII.
+ \endlist
+
+ One way to define these preprocessor symbols globally for your
+ application is to add the following entry to your
+ \l{qmake Project Files}{qmake project file}:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qstring.cpp 0
+
+ You then need to explicitly call fromAscii(), fromLatin1(),
+ fromUtf8(), or fromLocal8Bit() to construct a QString from an
+ 8-bit string, or use the lightweight QLatin1String class, for
+ example:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qstring.cpp 1
+
+ Similarly, you must call toAscii(), toLatin1(), toUtf8(), or
+ toLocal8Bit() explicitly to convert the QString to an 8-bit
+ string. (Other encodings are supported through the QTextCodec
+ class.)
+
+ \table 100 %
+ \row
+ \o
+ \section1 Note for C Programmers
+
+ Due to C++'s type system and the fact that QString is
+ \l{implicitly shared}, QStrings may be treated like \c{int}s or
+ other basic types. For example:
+
+ \snippet doc/src/snippets/qstring/main.cpp 7
+
+ The \c result variable, is a normal variable allocated on the
+ stack. When \c return is called, and because we're returning by
+ value, the copy constructor is called and a copy of the string is
+ returned. No actual copying takes place thanks to the implicit
+ sharing.
+
+ \endtable
+
+ \section1 Distinction Between Null and Empty Strings
+
+ For historical reasons, QString distinguishes between a null
+ string and an empty string. A \e null string is a string that is
+ initialized using QString's default constructor or by passing
+ (const char *)0 to the constructor. An \e empty string is any
+ string with size 0. A null string is always empty, but an empty
+ string isn't necessarily null:
+
+ \snippet doc/src/snippets/qstring/main.cpp 8
+
+ All functions except isNull() treat null strings the same as empty
+ strings. For example, toAscii().constData() returns a pointer to a
+ '\\0' character for a null string (\e not a null pointer), and
+ QString() compares equal to QString(""). We recommend that you
+ always use the isEmpty() function and avoid isNull().
+
+ \section1 Argument Formats
+
+ In member functions where an argument \e format can be specified
+ (e.g., arg(), number()), the argument \e format can be one of the
+ following:
+
+ \table
+ \header \o Format \o Meaning
+ \row \o \c e \o format as [-]9.9e[+|-]999
+ \row \o \c E \o format as [-]9.9E[+|-]999
+ \row \o \c f \o format as [-]9.9
+ \row \o \c g \o use \c e or \c f format, whichever is the most concise
+ \row \o \c G \o use \c E or \c f format, whichever is the most concise
+ \endtable
+
+ A \e precision is also specified with the argument \e format. For
+ the 'e', 'E', and 'f' formats, the \e precision represents the
+ number of digits \e after the decimal point. For the 'g' and 'G'
+ formats, the \e precision represents the maximum number of
+ significant digits (trailing zeroes are omitted).
+
+ \sa fromRawData(), QChar, QLatin1String, QByteArray, QStringRef
+*/
+
+/*!
+ \enum QString::SplitBehavior
+
+ This enum specifies how the split() function should behave with
+ respect to empty strings.
+
+ \value KeepEmptyParts If a field is empty, keep it in the result.
+ \value SkipEmptyParts If a field is empty, don't include it in the result.
+
+ \sa split()
+*/
+
+QString::Data QString::shared_null = { Q_BASIC_ATOMIC_INITIALIZER(1),
+ 0, 0, shared_null.array, 0, 0, 0, 0, 0, 0, {0} };
+QString::Data QString::shared_empty = { Q_BASIC_ATOMIC_INITIALIZER(1),
+ 0, 0, shared_empty.array, 0, 0, 0, 0, 0, 0, {0} };
+
+int QString::grow(int size)
+{
+ return qAllocMore(size * sizeof(QChar), sizeof(Data)) / sizeof(QChar);
+}
+
+/*! \typedef QString::ConstIterator
+
+ Qt-style synonym for QString::const_iterator.
+*/
+
+/*! \typedef QString::Iterator
+
+ Qt-style synonym for QString::iterator.
+*/
+
+/*! \typedef QString::const_iterator
+
+ The QString::const_iterator typedef provides an STL-style const
+ iterator for QString.
+
+ \sa QString::iterator
+*/
+
+/*! \typedef QString::iterator
+
+ The QString::iterator typedef provides an STL-style non-const
+ iterator for QString.
+
+ \sa QString::const_iterator
+*/
+
+/*! \fn QString::iterator QString::begin()
+
+ Returns an \l{STL-style iterator} pointing to the first character in
+ the string.
+
+ \sa constBegin(), end()
+*/
+
+/*! \fn QString::const_iterator QString::begin() const
+
+ \overload begin()
+*/
+
+/*! \fn QString::const_iterator QString::constBegin() const
+
+ Returns a const \l{STL-style iterator} pointing to the first character
+ in the string.
+
+ \sa begin(), constEnd()
+*/
+
+/*! \fn QString::iterator QString::end()
+
+ Returns an \l{STL-style iterator} pointing to the imaginary character
+ after the last character in the string.
+
+ \sa begin(), constEnd()
+*/
+
+/*! \fn QString::const_iterator QString::end() const
+
+ \overload end()
+*/
+
+/*! \fn QString::const_iterator QString::constEnd() const
+
+ Returns a const \l{STL-style iterator} pointing to the imaginary
+ item after the last item in the list.
+
+ \sa constBegin(), end()
+*/
+
+/*!
+ \fn QString::QString()
+
+ Constructs a null string. Null strings are also empty.
+
+ \sa isEmpty()
+*/
+
+/*! \fn QString::QString(const char *str)
+
+ Constructs a string initialized with the ASCII string \a str. The
+ given const char pointer is converted to Unicode using the
+ fromAscii() function.
+
+ You can disable this constructor by defining \c
+ QT_NO_CAST_FROM_ASCII when you compile your applications. This
+ can be useful if you want to ensure that all user-visible strings
+ go through QObject::tr(), for example.
+
+ \sa fromAscii(), fromLatin1(), fromLocal8Bit(), fromUtf8()
+*/
+
+/*! \fn QString QString::fromStdString(const std::string &str)
+
+ Returns a copy of the \a str string. The given string is converted
+ to Unicode using the fromAscii() function.
+
+ This constructor is only available if Qt is configured with STL
+ compatibility enabled.
+
+ \sa fromAscii(), fromLatin1(), fromLocal8Bit(), fromUtf8()
+*/
+
+/*! \fn QString QString::fromStdWString(const std::wstring &str)
+
+ Returns a copy of the \a str string. The given string is assumed
+ to be encoded in utf16 if the size of wchar_t is 2 bytes (e.g. on
+ windows) and ucs4 if the size of wchar_t is 4 bytes (most Unix
+ systems).
+
+ This method is only available if Qt is configured with STL
+ compatibility enabled.
+
+ \sa fromUtf16(), fromLatin1(), fromLocal8Bit(), fromUtf8(), fromUcs4()
+*/
+
+/*!
+ \since 4.2
+
+ Returns a copy of the \a string string encoded in ucs4.
+
+ If \a size is -1 (default), the \a string has to be 0 terminated.
+
+ \sa fromUtf16(), fromLatin1(), fromLocal8Bit(), fromUtf8(), fromUcs4(), fromStdWString()
+*/
+QString QString::fromWCharArray(const wchar_t *string, int size)
+{
+ if (sizeof(wchar_t) == sizeof(QChar)) {
+ return fromUtf16((ushort *)string, size);
+ } else {
+ return fromUcs4((uint *)string, size);
+ }
+}
+
+/*! \fn std::wstring QString::toStdWString() const
+
+ Returns a std::wstring object with the data contained in this
+ QString. The std::wstring is encoded in utf16 on platforms where
+ wchar_t is 2 bytes wide (e.g. windows) and in ucs4 on platforms
+ where wchar_t is 4 bytes wide (most Unix systems).
+
+ This operator is mostly useful to pass a QString to a function
+ that accepts a std::wstring object.
+
+ This operator is only available if Qt is configured with STL
+ compatibility enabled.
+
+ \sa utf16(), toAscii(), toLatin1(), toUtf8(), toLocal8Bit()
+*/
+
+/*!
+ \since 4.2
+
+ Fills the \a array with the data contained in this QString object.
+ The array is encoded in utf16 on platforms where
+ wchar_t is 2 bytes wide (e.g. windows) and in ucs4 on platforms
+ where wchar_t is 4 bytes wide (most Unix systems).
+
+ \a array has to be allocated by the caller and contain enough space to
+ hold the complete string (allocating the array with the same length as the
+ string is always sufficient).
+
+ returns the actual length of the string in \a array.
+
+ \note This function does not append a null character to the array.
+
+ \sa utf16(), toUcs4(), toAscii(), toLatin1(), toUtf8(), toLocal8Bit(), toStdWString()
+*/
+int QString::toWCharArray(wchar_t *array) const
+{
+ if (sizeof(wchar_t) == sizeof(QChar)) {
+ memcpy(array, utf16(), sizeof(wchar_t)*length());
+ return length();
+ } else {
+ wchar_t *a = array;
+ const unsigned short *uc = utf16();
+ for (int i = 0; i < length(); ++i) {
+ uint u = uc[i];
+ if (u >= 0xd800 && u < 0xdc00 && i < length()-1) {
+ ushort low = uc[i+1];
+ if (low >= 0xdc00 && low < 0xe000) {
+ ++i;
+ u = (u - 0xd800)*0x400 + (low - 0xdc00) + 0x10000;
+ }
+ }
+ *a = wchar_t(u);
+ ++a;
+ }
+ return a - array;
+ }
+}
+
+/*! \fn QString::QString(const QString &other)
+
+ Constructs a copy of \a other.
+
+ This operation takes \l{constant time}, because QString is
+ \l{implicitly shared}. This makes returning a QString from a
+ function very fast. If a shared instance is modified, it will be
+ copied (copy-on-write), and that takes \l{linear time}.
+
+ \sa operator=()
+*/
+
+/*!
+ Constructs a string initialized with the first \a size characters
+ of the QChar array \a unicode.
+
+ QString makes a deep copy of the string data.
+*/
+QString::QString(const QChar *unicode, int size)
+{
+ if (!unicode) {
+ d = &shared_null;
+ d->ref.ref();
+ } else if (size <= 0) {
+ d = &shared_empty;
+ d->ref.ref();
+ } else {
+ d = (Data*) qMalloc(sizeof(Data)+size*sizeof(QChar));
+ d->ref = 1;
+ d->alloc = d->size = size;
+ d->clean = d->asciiCache = d->simpletext = d->righttoleft = d->capacity = 0;
+ d->data = d->array;
+ memcpy(d->array, unicode, size * sizeof(QChar));
+ d->array[size] = '\0';
+ }
+}
+
+
+/*!
+ Constructs a string of the given \a size with every character set
+ to \a ch.
+
+ \sa fill()
+*/
+QString::QString(int size, QChar ch)
+{
+ if (size <= 0) {
+ d = &shared_empty;
+ d->ref.ref();
+ } else {
+ d = (Data*) qMalloc(sizeof(Data)+size*sizeof(QChar));
+ d->ref = 1;
+ d->alloc = d->size = size;
+ d->clean = d->asciiCache = d->simpletext = d->righttoleft = d->capacity = 0;
+ d->data = d->array;
+ d->array[size] = '\0';
+ ushort *i = d->array + size;
+ ushort *b = d->array;
+ const ushort value = ch.unicode();
+ while (i != b)
+ *--i = value;
+ }
+}
+
+/*! \fn QString::QString(const QLatin1String &str)
+
+ Constructs a copy of the Latin-1 string \a str.
+
+ \sa fromLatin1()
+*/
+
+/*!
+ Constructs a string of size 1 containing the character \a ch.
+*/
+QString::QString(QChar ch)
+{
+ d = (Data *)qMalloc(sizeof(Data) + sizeof(QChar));
+ d->ref = 1;
+ d->alloc = d->size = 1;
+ d->clean = d->asciiCache = d->simpletext = d->righttoleft = d->capacity = 0;
+ d->data = d->array;
+ d->array[0] = ch.unicode();
+ d->array[1] = '\0';
+}
+
+/*! \fn QString::QString(const QByteArray &ba)
+
+ Constructs a string initialized with the byte array \a ba. The
+ given byte array is converted to Unicode using fromAscii(). Stops
+ copying at the first 0 character, otherwise copies the entire byte
+ array.
+
+ You can disable this constructor by defining \c
+ QT_NO_CAST_FROM_ASCII when you compile your applications. This
+ can be useful if you want to ensure that all user-visible strings
+ go through QObject::tr(), for example.
+
+ \sa fromAscii(), fromLatin1(), fromLocal8Bit(), fromUtf8()
+*/
+
+/*! \fn QString::QString(const Null &)
+ \internal
+*/
+
+/*! \fn QString &QString::operator=(const Null &)
+ \internal
+*/
+
+/*!
+ \fn QString::~QString()
+
+ Destroys the string.
+*/
+
+
+/*! \fn void QString::detach()
+
+ \internal
+*/
+
+/*! \fn void QString::isDetached() const
+
+ \internal
+*/
+
+// ### Qt 5: rename freeData() to avoid confusion. See task 197625.
+void QString::free(Data *d)
+{
+#ifdef QT3_SUPPORT
+ if (d->asciiCache) {
+ Q_ASSERT(asciiCache);
+ asciiCache->remove(d);
+ }
+#endif
+ qFree(d);
+}
+
+/*!
+ Sets the size of the string to \a size characters.
+
+ If \a size is greater than the current size, the string is
+ extended to make it \a size characters long with the extra
+ characters added to the end. The new characters are uninitialized.
+
+ If \a size is less than the current size, characters are removed
+ from the end.
+
+ Example:
+
+ \snippet doc/src/snippets/qstring/main.cpp 45
+
+ If you want to append a certain number of identical characters to
+ the string, use \l operator+=() as follows rather than resize():
+
+ \snippet doc/src/snippets/qstring/main.cpp 46
+
+ If you want to expand the string so that it reaches a certain
+ width and fill the new positions with a particular character, use
+ the leftJustified() function:
+
+ If \a size is negative, it is equivalent to passing zero.
+
+ \snippet doc/src/snippets/qstring/main.cpp 47
+
+ \sa truncate(), reserve()
+*/
+
+void QString::resize(int size)
+{
+ if (size < 0)
+ size = 0;
+
+ if (size == 0 && !d->capacity) {
+ Data *x = &shared_empty;
+ x->ref.ref();
+ if (!d->ref.deref())
+ QString::free(d);
+ d = x;
+ } else {
+ if (d->ref != 1 || size > d->alloc ||
+ (!d->capacity && size < d->size && size < d->alloc >> 1))
+ realloc(grow(size));
+ if (d->alloc >= size) {
+ d->size = size;
+ if (d->data == d->array) {
+ d->array[size] = '\0';
+ }
+ }
+ }
+}
+
+/*! \fn int QString::capacity() const
+
+ Returns the maximum number of characters that can be stored in
+ the string without forcing a reallocation.
+
+ The sole purpose of this function is to provide a means of fine
+ tuning QString's memory usage. In general, you will rarely ever
+ need to call this function. If you want to know how many
+ characters are in the string, call size().
+
+ \sa reserve(), squeeze()
+*/
+
+/*!
+ \fn void QString::reserve(int size)
+
+ Attempts to allocate memory for at least \a size characters. If
+ you know in advance how large the string will be, you can call
+ this function, and if you resize the string often you are likely
+ to get better performance. If \a size is an underestimate, the
+ worst that will happen is that the QString will be a bit slower.
+
+ The sole purpose of this function is to provide a means of fine
+ tuning QString's memory usage. In general, you will rarely ever
+ need to call this function. If you want to change the size of the
+ string, call resize().
+
+ This function is useful for code that needs to build up a long
+ string and wants to avoid repeated reallocation. In this example,
+ we want to add to the string until some condition is true, and
+ we're fairly sure that size is large enough to make a call to
+ reserve() worthwhile:
+
+ \snippet doc/src/snippets/qstring/main.cpp 44
+
+ \sa squeeze(), capacity()
+*/
+
+/*!
+ \fn void QString::squeeze()
+
+ Releases any memory not required to store the character data.
+
+ The sole purpose of this function is to provide a means of fine
+ tuning QString's memory usage. In general, you will rarely ever
+ need to call this function.
+
+ \sa reserve(), capacity()
+*/
+
+// ### Qt 5: rename reallocData() to avoid confusion. 197625
+void QString::realloc(int alloc)
+{
+ if (d->ref != 1 || d->data != d->array) {
+ Data *x = static_cast<Data *>(qMalloc(sizeof(Data) + alloc * sizeof(QChar)));
+ if (!x)
+ return;
+ x->size = qMin(alloc, d->size);
+ ::memcpy(x->array, d->data, x->size * sizeof(QChar));
+ x->array[x->size] = 0;
+ x->asciiCache = 0;
+ x->ref = 1;
+ x->alloc = alloc;
+ x->clean = d->clean;
+ x->simpletext = d->simpletext;
+ x->righttoleft = d->righttoleft;
+ x->capacity = d->capacity;
+ x->data = x->array;
+ if (!d->ref.deref())
+ QString::free(d);
+ d = x;
+ } else {
+#ifdef QT3_SUPPORT
+ if (d->asciiCache) {
+ Q_ASSERT(asciiCache);
+ asciiCache->remove(d);
+ }
+#endif
+ Data *x = static_cast<Data *>(qRealloc(d, sizeof(Data) + alloc * sizeof(QChar)));
+ if (!x)
+ return;
+ x->alloc = alloc;
+ x->data = x->array;
+ d = x;
+ }
+}
+
+void QString::realloc()
+{
+ realloc(d->size);
+}
+
+void QString::expand(int i)
+{
+ int sz = d->size;
+ resize(qMax(i + 1, sz));
+ if (d->size - 1 > sz) {
+ ushort *n = d->data + d->size - 1;
+ ushort *e = d->data + sz;
+ while (n != e)
+ * --n = ' ';
+ }
+}
+
+/*! \fn void QString::clear()
+
+ Clears the contents of the string and makes it empty.
+
+ \sa resize(), isEmpty()
+*/
+
+/*! \fn QString &QString::operator=(const QString &other)
+
+ Assigns \a other to this string and returns a reference to this
+ string.
+*/
+
+QString &QString::operator=(const QString &other)
+{
+ other.d->ref.ref();
+ if (!d->ref.deref())
+ QString::free(d);
+ d = other.d;
+ return *this;
+}
+
+
+/*! \fn QString &QString::operator=(const QLatin1String &str)
+
+ \overload operator=()
+
+ Assigns the Latin-1 string \a str to this string.
+*/
+
+/*! \fn QString &QString::operator=(const QByteArray &ba)
+
+ \overload operator=()
+
+ Assigns \a ba to this string. The byte array is converted to
+ Unicode using the fromAscii() function.
+
+ You can disable this operator by defining \c
+ QT_NO_CAST_FROM_ASCII when you compile your applications. This
+ can be useful if you want to ensure that all user-visible strings
+ go through QObject::tr(), for example.
+*/
+
+/*! \fn QString &QString::operator=(const char *str)
+
+ \overload operator=()
+
+ Assigns \a str to this string. The const char pointer is converted
+ to Unicode using the fromAscii() function.
+
+ You can disable this operator by defining \c
+ QT_NO_CAST_FROM_ASCII when you compile your applications. This
+ can be useful if you want to ensure that all user-visible strings
+ go through QObject::tr(), for example.
+*/
+
+/*! \fn QString &QString::operator=(char ch)
+
+ \overload operator=()
+
+ Assigns character \a ch to this string. The character is converted
+ to Unicode using the fromAscii() function.
+
+ You can disable this operator by defining \c
+ QT_NO_CAST_FROM_ASCII when you compile your applications. This
+ can be useful if you want to ensure that all user-visible strings
+ go through QObject::tr(), for example.
+*/
+
+/*!
+ \overload operator=()
+
+ Sets the string to contain the single character \a ch.
+*/
+QString &QString::operator=(QChar ch)
+{
+ return operator=(QString(ch));
+}
+
+/*!
+ \fn QString& QString::insert(int position, const QString &str)
+
+ Inserts the string \a str at the given index \a position and
+ returns a reference to this string.
+
+ Example:
+
+ \snippet doc/src/snippets/qstring/main.cpp 26
+
+ If the given \a position is greater than size(), the array is
+ first extended using resize().
+
+ \sa append(), prepend(), replace(), remove()
+*/
+
+
+/*!
+ \fn QString &QString::insert(int position, const QLatin1String &str)
+ \overload insert()
+
+ Inserts the Latin-1 string \a str at the given index \a position.
+*/
+QString &QString::insert(int i, const QLatin1String &str)
+{
+ const uchar *s = (const uchar *)str.latin1();
+ if (i < 0 || !s || !(*s))
+ return *this;
+
+ int len = qstrlen(str.latin1());
+ expand(qMax(d->size, i) + len - 1);
+
+ ::memmove(d->data + i + len, d->data + i, (d->size - i - len) * sizeof(QChar));
+ for (int j = 0; j < len; ++j)
+ d->data[i + j] = s[j];
+ return *this;
+}
+
+/*!
+ \fn QString& QString::insert(int position, const QChar *unicode, int size)
+ \overload insert()
+
+ Inserts the first \a size characters of the QChar array \a unicode
+ at the given index \a position in the string.
+*/
+QString& QString::insert(int i, const QChar *unicode, int size)
+{
+ if (i < 0 || size <= 0)
+ return *this;
+
+ const ushort *s = (const ushort *)unicode;
+ if (s >= d->data && s < d->data + d->alloc) {
+ // Part of me - take a copy
+ ushort *tmp = static_cast<ushort *>(qMalloc(size * sizeof(QChar)));
+ memcpy(tmp, s, size * sizeof(QChar));
+ insert(i, reinterpret_cast<const QChar *>(tmp), size);
+ qFree(tmp);
+ return *this;
+ }
+
+ expand(qMax(d->size, i) + size - 1);
+
+ ::memmove(d->data + i + size, d->data + i, (d->size - i - size) * sizeof(QChar));
+ memcpy(d->data + i, s, size * sizeof(QChar));
+ return *this;
+}
+
+/*!
+ \fn QString& QString::insert(int position, QChar ch)
+ \overload insert()
+
+ Inserts \a ch at the given index \a position in the string.
+*/
+
+QString& QString::insert(int i, QChar ch)
+{
+ if (i < 0)
+ i += d->size;
+ if (i < 0)
+ return *this;
+ expand(qMax(i, d->size));
+ ::memmove(d->data + i + 1, d->data + i, (d->size - i) * sizeof(QChar));
+ d->data[i] = ch.unicode();
+ return *this;
+}
+
+/*!
+ Appends the string \a str onto the end of this string.
+
+ Example:
+
+ \snippet doc/src/snippets/qstring/main.cpp 9
+
+ This is the same as using the insert() function:
+
+ \snippet doc/src/snippets/qstring/main.cpp 10
+
+ The append() function is typically very fast (\l{constant time}),
+ because QString preallocates extra space at the end of the string
+ data so it can grow without reallocating the entire string each
+ time.
+
+ \sa operator+=(), prepend(), insert()
+*/
+QString &QString::append(const QString &str)
+{
+ if (str.d != &shared_null) {
+ if (d == &shared_null) {
+ operator=(str);
+ } else {
+ if (d->ref != 1 || d->size + str.d->size > d->alloc)
+ realloc(grow(d->size + str.d->size));
+ memcpy(d->data + d->size, str.d->data, str.d->size * sizeof(QChar));
+ d->size += str.d->size;
+ d->data[d->size] = '\0';
+ }
+ }
+ return *this;
+}
+
+/*!
+ \overload append()
+
+ Appends the Latin-1 string \a str to this string.
+*/
+QString &QString::append(const QLatin1String &str)
+{
+ const uchar *s = (const uchar *)str.latin1();
+ if (s) {
+ int len = qstrlen((char *)s);
+ if (d->ref != 1 || d->size + len > d->alloc)
+ realloc(grow(d->size + len));
+ ushort *i = d->data + d->size;
+ while ((*i++ = *s++))
+ ;
+ d->size += len;
+ }
+ return *this;
+}
+
+/*! \fn QString &QString::append(const QByteArray &ba)
+
+ \overload append()
+
+ Appends the byte array \a ba to this string. The given byte array
+ is converted to Unicode using the fromAscii() function.
+
+ You can disable this function by defining \c QT_NO_CAST_FROM_ASCII
+ when you compile your applications. This can be useful if you want
+ to ensure that all user-visible strings go through QObject::tr(),
+ for example.
+*/
+
+/*! \fn QString &QString::append(const char *str)
+
+ \overload append()
+
+ Appends the string \a str to this string. The given const char
+ pointer is converted to Unicode using the fromAscii() function.
+
+ You can disable this function by defining \c QT_NO_CAST_FROM_ASCII
+ when you compile your applications. This can be useful if you want
+ to ensure that all user-visible strings go through QObject::tr(),
+ for example.
+*/
+
+/*!
+ \overload append()
+
+ Appends the character \a ch to this string.
+*/
+QString &QString::append(QChar ch)
+{
+ if (d->ref != 1 || d->size + 1 > d->alloc)
+ realloc(grow(d->size + 1));
+ d->data[d->size++] = ch.unicode();
+ d->data[d->size] = '\0';
+ return *this;
+}
+
+/*! \fn QString &QString::prepend(const QString &str)
+
+ Prepends the string \a str to the beginning of this string and
+ returns a reference to this string.
+
+ Example:
+
+ \snippet doc/src/snippets/qstring/main.cpp 36
+
+ \sa append(), insert()
+*/
+
+/*! \fn QString &QString::prepend(const QLatin1String &str)
+
+ \overload prepend()
+
+ Prepends the Latin-1 string \a str to this string.
+*/
+
+/*! \fn QString &QString::prepend(const QByteArray &ba)
+
+ \overload prepend()
+
+ Prepends the byte array \a ba to this string. The byte array is
+ converted to Unicode using the fromAscii() function.
+
+ You can disable this function by defining \c
+ QT_NO_CAST_FROM_ASCII when you compile your applications. This
+ can be useful if you want to ensure that all user-visible strings
+ go through QObject::tr(), for example.
+*/
+
+/*! \fn QString &QString::prepend(const char *str)
+
+ \overload prepend()
+
+ Prepends the string \a str to this string. The const char pointer
+ is converted to Unicode using the fromAscii() function.
+
+ You can disable this function by defining \c
+ QT_NO_CAST_FROM_ASCII when you compile your applications. This
+ can be useful if you want to ensure that all user-visible strings
+ go through QObject::tr(), for example.
+*/
+
+/*! \fn QString &QString::prepend(QChar ch)
+
+ \overload prepend()
+
+ Prepends the character \a ch to this string.
+*/
+
+/*!
+ \fn QString &QString::remove(int position, int n)
+
+ Removes \a n characters from the string, starting at the given \a
+ position index, and returns a reference to the string.
+
+ If the specified \a position index is within the string, but \a
+ position + \a n is beyond the end of the string, the string is
+ truncated at the specified \a position.
+
+ \snippet doc/src/snippets/qstring/main.cpp 37
+
+ \sa insert(), replace()
+*/
+QString &QString::remove(int pos, int len)
+{
+ if (pos < 0)
+ pos += d->size;
+ if (pos < 0 || pos >= d->size) {
+ // range problems
+ } else if (pos + len >= d->size) { // pos ok
+ resize(pos);
+ } else if (len > 0) {
+ detach();
+ memmove(d->data + pos, d->data + pos + len,
+ (d->size - pos - len + 1) * sizeof(ushort));
+ d->size -= len;
+ }
+ return *this;
+}
+
+/*!
+ Removes every occurrence of the given \a str string in this
+ string, and returns a reference to this string.
+
+ If \a cs is Qt::CaseSensitive (default), the search is
+ case sensitive; otherwise the search is case insensitive.
+
+ This is the same as \c replace(str, "", cs).
+
+ \sa replace()
+*/
+QString &QString::remove(const QString &str, Qt::CaseSensitivity cs)
+{
+ if (str.d->size) {
+ int i = 0;
+ while ((i = indexOf(str, i, cs)) != -1)
+ remove(i, str.d->size);
+ }
+ return *this;
+}
+
+/*!
+ Removes every occurrence of the character \a ch in this string, and
+ returns a reference to this string.
+
+ If \a cs is Qt::CaseSensitive (default), the search is case
+ sensitive; otherwise the search is case insensitive.
+
+ Example:
+
+ \snippet doc/src/snippets/qstring/main.cpp 38
+
+ This is the same as \c replace(ch, "", cs).
+
+ \sa replace()
+*/
+QString &QString::remove(QChar ch, Qt::CaseSensitivity cs)
+{
+ int i = 0;
+ ushort c = ch.unicode();
+ if (cs == Qt::CaseSensitive) {
+ while (i < d->size)
+ if (d->data[i] == ch)
+ remove(i, 1);
+ else
+ i++;
+ } else {
+ c = foldCase(c);
+ while (i < d->size)
+ if (foldCase(d->data[i]) == c)
+ remove(i, 1);
+ else
+ i++;
+ }
+ return *this;
+}
+
+/*!
+ \fn QString &QString::remove(const QRegExp &rx)
+
+ Removes every occurrence of the regular expression \a rx in the
+ string, and returns a reference to the string. For example:
+
+ \snippet doc/src/snippets/qstring/main.cpp 39
+
+ \sa indexOf(), lastIndexOf(), replace()
+*/
+
+/*!
+ \fn QString &QString::replace(int position, int n, const QString &after)
+
+ Replaces \a n characters beginning at index \a position with
+ the string \a after and returns a reference to this string.
+
+ Example:
+
+ \snippet doc/src/snippets/qstring/main.cpp 40
+
+ \sa insert(), remove()
+*/
+QString &QString::replace(int pos, int len, const QString &after)
+{
+ QString copy = after;
+ return replace(pos, len, copy.constData(), copy.length());
+}
+
+/*!
+ \fn QString &QString::replace(int position, int n, const QChar *unicode, int size)
+ \overload replace()
+ Replaces \a n characters beginning at index \a position with the
+ first \a size characters of the QChar array \a unicode and returns a
+ reference to this string.
+*/
+QString &QString::replace(int pos, int len, const QChar *unicode, int size)
+{
+ if (pos < 0 || pos > d->size)
+ return *this;
+ if (pos + len > d->size)
+ len = d->size - pos;
+
+ uint index = pos;
+ replace_helper(&index, 1, len, unicode, size);
+ return *this;
+}
+
+/*!
+ \fn QString &QString::replace(int position, int n, QChar after)
+ \overload replace()
+
+ Replaces \a n characters beginning at index \a position with the
+ character \a after and returns a reference to this string.
+*/
+QString &QString::replace(int pos, int len, QChar after)
+{
+ uint index = pos;
+ replace_helper(&index, 1, len, &after, 1);
+ return *this;
+}
+
+/*!
+ \overload replace()
+ Replaces every occurrence of the string \a before with the string \a
+ after and returns a reference to this string.
+
+ If \a cs is Qt::CaseSensitive (default), the search is case
+ sensitive; otherwise the search is case insensitive.
+
+ Example:
+
+ \snippet doc/src/snippets/qstring/main.cpp 41
+
+ \note The replacement text is not rescanned after it is inserted.
+
+ Example:
+
+ \snippet doc/src/snippets/qstring/main.cpp 86
+*/
+QString &QString::replace(const QString &before, const QString &after, Qt::CaseSensitivity cs)
+{
+ return replace(before.constData(), before.size(), after.constData(), after.size(), cs);
+}
+
+/*!
+ \internal
+ */
+void QString::replace_helper(uint *indices, int nIndices, int blen, const QChar *after, int alen)
+{
+ if (blen == alen) {
+ detach();
+ for (int i = 0; i < nIndices; ++i)
+ memcpy(d->data + indices[i], after, alen * sizeof(QChar));
+ } else if (alen < blen) {
+ detach();
+ uint to = indices[0];
+ if (alen)
+ memcpy(d->data+to, after, alen*sizeof(QChar));
+ to += alen;
+ uint movestart = indices[0] + blen;
+ for (int i = 1; i < nIndices; ++i) {
+ int msize = indices[i] - movestart;
+ if (msize > 0) {
+ memmove(d->data + to, d->data + movestart, msize * sizeof(QChar));
+ to += msize;
+ }
+ if (alen) {
+ memcpy(d->data + to, after, alen*sizeof(QChar));
+ to += alen;
+ }
+ movestart = indices[i] + blen;
+ }
+ int msize = d->size - movestart;
+ if (msize > 0)
+ memmove(d->data + to, d->data + movestart, msize * sizeof(QChar));
+ resize(d->size - nIndices*(blen-alen));
+ } else {
+ // we have a table of replacement positions, use them for fast replacing
+ int adjust = nIndices*(alen-blen);
+ int newLen = d->size + adjust;
+ int moveend = d->size;
+ resize(newLen);
+
+ while (nIndices) {
+ --nIndices;
+ int movestart = indices[nIndices] + blen;
+ int insertstart = indices[nIndices] + nIndices*(alen-blen);
+ int moveto = insertstart + alen;
+ memmove(d->data + moveto, d->data + movestart,
+ (moveend - movestart)*sizeof(QChar));
+ memcpy(d->data + insertstart, after, alen*sizeof(QChar));
+ moveend = movestart-blen;
+ }
+ }
+}
+
+/*!
+ \since 4.5
+ \overload replace()
+
+ Replaces each occurrence in this string of the first \a blen
+ characters of \a before with the first \a alen characters of \a
+ after and returns a reference to this string.
+
+ If \a cs is Qt::CaseSensitive (default), the search is case
+ sensitive; otherwise the search is case insensitive.
+*/
+QString &QString::replace(const QChar *before, int blen,
+ const QChar *after, int alen,
+ Qt::CaseSensitivity cs)
+{
+ if (d->size == 0) {
+ if (blen)
+ return *this;
+ } else {
+ if (cs == Qt::CaseSensitive && before == after && blen == alen)
+ return *this;
+ }
+ if (alen == 0 && blen == 0)
+ return *this;
+
+ // protect against before or after being part of this
+ const QChar *a = after;
+ const QChar *b = before;
+ if (after >= (const QChar *)d->data && after < (const QChar *)d->data + d->size) {
+ QChar *copy = (QChar *)malloc(alen*sizeof(QChar));
+ memcpy(copy, after, alen*sizeof(QChar));
+ a = copy;
+ }
+ if (before >= (const QChar *)d->data && before < (const QChar *)d->data + d->size) {
+ QChar *copy = (QChar *)malloc(blen*sizeof(QChar));
+ memcpy(copy, before, blen*sizeof(QChar));
+ b = copy;
+ }
+
+ QStringMatcher matcher(b, blen, cs);
+
+ int index = 0;
+ while (1) {
+ uint indices[1024];
+ uint pos = 0;
+ while (pos < 1023) {
+ index = matcher.indexIn(*this, index);
+ if (index == -1)
+ break;
+ indices[pos++] = index;
+ index += blen;
+ // avoid infinite loop
+ if (!blen)
+ index++;
+ }
+ if (!pos)
+ break;
+
+ replace_helper(indices, pos, blen, a, alen);
+
+ if (index == -1)
+ break;
+ // index has to be adjusted in case we get back into the loop above.
+ index += pos*(alen-blen);
+ }
+
+ if (a != after)
+ ::free((QChar *)a);
+ if (b != before)
+ ::free((QChar *)b);
+
+ return *this;
+}
+
+/*!
+ \overload replace()
+ Replaces every occurrence of the character \a ch in the string with
+ \a after and returns a reference to this string.
+
+ If \a cs is Qt::CaseSensitive (default), the search is case
+ sensitive; otherwise the search is case insensitive.
+*/
+QString& QString::replace(QChar ch, const QString &after, Qt::CaseSensitivity cs)
+{
+ if (after.d->size == 0)
+ return remove(ch, cs);
+
+ if (after.d->size == 1)
+ return replace(ch, after.d->data[0], cs);
+
+ if (d->size == 0)
+ return *this;
+
+ ushort cc = (cs == Qt::CaseSensitive ? ch.unicode() : ch.toCaseFolded().unicode());
+
+ int index = 0;
+ while (1) {
+ uint indices[1024];
+ uint pos = 0;
+ if (cs == Qt::CaseSensitive) {
+ while (pos < 1023 && index < d->size) {
+ if (d->data[index] == cc)
+ indices[pos++] = index;
+ index++;
+ }
+ } else {
+ while (pos < 1023 && index < d->size) {
+ if (QChar::toCaseFolded(d->data[index]) == cc)
+ indices[pos++] = index;
+ index++;
+ }
+ }
+ if (!pos)
+ break;
+
+ replace_helper(indices, pos, 1, after.constData(), after.d->size);
+
+ if (index == -1)
+ break;
+ // index has to be adjusted in case we get back into the loop above.
+ index += pos*(after.d->size - 1);
+ }
+ return *this;
+}
+
+/*!
+ \overload replace()
+ Replaces every occurrence of the character \a before with the
+ character \a after and returns a reference to this string.
+
+ If \a cs is Qt::CaseSensitive (default), the search is case
+ sensitive; otherwise the search is case insensitive.
+*/
+QString& QString::replace(QChar before, QChar after, Qt::CaseSensitivity cs)
+{
+ ushort a = after.unicode();
+ ushort b = before.unicode();
+ if (d->size) {
+ detach();
+ ushort *i = d->data;
+ const ushort *e = i + d->size;
+ if (cs == Qt::CaseSensitive) {
+ for (; i != e; ++i)
+ if (*i == b)
+ *i = a;
+ } else {
+ b = foldCase(b);
+ for (; i != e; ++i)
+ if (foldCase(*i) == b)
+ *i = a;
+ }
+ }
+ return *this;
+}
+
+/*!
+ \since 4.5
+ \overload replace()
+
+ Replaces every occurrence of the string \a before with the string \a
+ after and returns a reference to this string.
+
+ If \a cs is Qt::CaseSensitive (default), the search is case
+ sensitive; otherwise the search is case insensitive.
+
+ \note The text is not rescanned after a replacement.
+*/
+QString &QString::replace(const QLatin1String &before,
+ const QLatin1String &after,
+ Qt::CaseSensitivity cs)
+{
+ int alen = qstrlen(after.latin1());
+ QVarLengthArray<ushort> a(alen);
+ for (int i = 0; i < alen; ++i)
+ a[i] = (uchar)after.latin1()[i];
+ int blen = qstrlen(before.latin1());
+ QVarLengthArray<ushort> b(blen);
+ for (int i = 0; i < blen; ++i)
+ b[i] = (uchar)before.latin1()[i];
+ return replace((const QChar *)b.data(), blen, (const QChar *)a.data(), alen, cs);
+}
+
+/*!
+ \since 4.5
+ \overload replace()
+
+ Replaces every occurrence of the string \a before with the string \a
+ after and returns a reference to this string.
+
+ If \a cs is Qt::CaseSensitive (default), the search is case
+ sensitive; otherwise the search is case insensitive.
+
+ \note The text is not rescanned after a replacement.
+*/
+QString &QString::replace(const QLatin1String &before,
+ const QString &after,
+ Qt::CaseSensitivity cs)
+{
+ int blen = qstrlen(before.latin1());
+ QVarLengthArray<ushort> b(blen);
+ for (int i = 0; i < blen; ++i)
+ b[i] = (uchar)before.latin1()[i];
+ return replace((const QChar *)b.data(), blen, after.constData(), after.d->size, cs);
+}
+
+/*!
+ \since 4.5
+ \overload replace()
+
+ Replaces every occurrence of the string \a before with the string \a
+ after and returns a reference to this string.
+
+ If \a cs is Qt::CaseSensitive (default), the search is case
+ sensitive; otherwise the search is case insensitive.
+
+ \note The text is not rescanned after a replacement.
+*/
+QString &QString::replace(const QString &before,
+ const QLatin1String &after,
+ Qt::CaseSensitivity cs)
+{
+ int alen = qstrlen(after.latin1());
+ QVarLengthArray<ushort> a(alen);
+ for (int i = 0; i < alen; ++i)
+ a[i] = (uchar)after.latin1()[i];
+ return replace(before.constData(), before.d->size, (const QChar *)a.data(), alen, cs);
+}
+
+/*!
+ \since 4.5
+ \overload replace()
+
+ Replaces every occurrence of the character \a c with the string \a
+ after and returns a reference to this string.
+
+ If \a cs is Qt::CaseSensitive (default), the search is case
+ sensitive; otherwise the search is case insensitive.
+
+ \note The text is not rescanned after a replacement.
+*/
+QString &QString::replace(QChar c, const QLatin1String &after, Qt::CaseSensitivity cs)
+{
+ int alen = qstrlen(after.latin1());
+ QVarLengthArray<ushort> a(alen);
+ for (int i = 0; i < alen; ++i)
+ a[i] = (uchar)after.latin1()[i];
+ return replace(&c, 1, (const QChar *)a.data(), alen, cs);
+}
+
+
+/*!
+ Returns true if string \a other is equal to this string; otherwise
+ returns false.
+
+ The comparison is based exclusively on the numeric Unicode values of
+ the characters and is very fast, but is not what a human would
+ expect. Consider sorting user-interface strings with
+ localeAwareCompare().
+*/
+bool QString::operator==(const QString &other) const
+{
+ return (size() == other.size()) &&
+ (memcmp((char*)unicode(),(char*)other.unicode(), size()*sizeof(QChar))==0);
+}
+
+/*!
+ \overload operator==()
+*/
+bool QString::operator==(const QLatin1String &other) const
+{
+ const ushort *uc = d->data;
+ const ushort *e = uc + d->size;
+ const uchar *c = (uchar *)other.latin1();
+
+ if (!c)
+ return isEmpty();
+
+ while (*c) {
+ if (uc == e || *uc != *c)
+ return false;
+ ++uc;
+ ++c;
+ }
+ return (uc == e);
+}
+
+/*! \fn bool QString::operator==(const QByteArray &other) const
+
+ \overload operator==()
+
+ The \a other byte array is converted to a QString using the
+ fromAscii() function.
+
+ You can disable this operator by defining \c
+ QT_NO_CAST_FROM_ASCII when you compile your applications. This
+ can be useful if you want to ensure that all user-visible strings
+ go through QObject::tr(), for example.
+*/
+
+/*! \fn bool QString::operator==(const char *other) const
+
+ \overload operator==()
+
+ The \a other const char pointer is converted to a QString using
+ the fromAscii() function.
+
+ You can disable this operator by defining \c
+ QT_NO_CAST_FROM_ASCII when you compile your applications. This
+ can be useful if you want to ensure that all user-visible strings
+ go through QObject::tr(), for example.
+*/
+
+/*!
+ Returns true if this string is lexically less than string \a
+ other; otherwise returns false.
+
+ The comparison is based exclusively on the numeric Unicode values
+ of the characters and is very fast, but is not what a human would
+ expect. Consider sorting user-interface strings using the
+ QString::localeAwareCompare() function.
+*/
+bool QString::operator<(const QString &other) const
+{
+ return ucstrcmp(constData(), length(), other.constData(), other.length()) < 0;
+}
+
+/*!
+ \overload operator<()
+*/
+bool QString::operator<(const QLatin1String &other) const
+{
+ const ushort *uc = d->data;
+ const ushort *e = uc + d->size;
+ const uchar *c = (uchar *) other.latin1();
+
+ if (!c || *c == 0)
+ return false;
+
+ while (*c) {
+ if (uc == e || *uc != *c)
+ break;
+ ++uc;
+ ++c;
+ }
+ return (uc == e ? *c : *uc < *c);
+}
+
+/*! \fn bool QString::operator<(const QByteArray &other) const
+
+ \overload operator<()
+
+ The \a other byte array is converted to a QString using the
+ fromAscii() function.
+
+ You can disable this operator by defining \c
+ QT_NO_CAST_FROM_ASCII when you compile your applications. This
+ can be useful if you want to ensure that all user-visible strings
+ go through QObject::tr(), for example.
+*/
+
+/*! \fn bool QString::operator<(const char *other) const
+
+ \overload operator<()
+
+ The \a other const char pointer is converted to a QString using
+ the fromAscii() function.
+
+ You can disable this operator by defining \c
+ QT_NO_CAST_FROM_ASCII when you compile your applications. This
+ can be useful if you want to ensure that all user-visible strings
+ go through QObject::tr(), for example.
+*/
+
+/*! \fn bool QString::operator<=(const QString &other) const
+
+ Returns true if this string is lexically less than or equal to
+ string \a other; otherwise returns false.
+
+ The comparison is based exclusively on the numeric Unicode values
+ of the characters and is very fast, but is not what a human would
+ expect. Consider sorting user-interface strings with
+ localeAwareCompare().
+*/
+
+/*! \fn bool QString::operator<=(const QLatin1String &other) const
+
+ \overload operator<=()
+*/
+
+/*! \fn bool QString::operator<=(const QByteArray &other) const
+
+ \overload operator<=()
+
+ The \a other byte array is converted to a QString using the
+ fromAscii() function.
+
+ You can disable this operator by defining \c
+ QT_NO_CAST_FROM_ASCII when you compile your applications. This
+ can be useful if you want to ensure that all user-visible strings
+ go through QObject::tr(), for example.
+*/
+
+/*! \fn bool QString::operator<=(const char *other) const
+
+ \overload operator<=()
+
+ The \a other const char pointer is converted to a QString using
+ the fromAscii() function.
+
+ You can disable this operator by defining \c
+ QT_NO_CAST_FROM_ASCII when you compile your applications. This
+ can be useful if you want to ensure that all user-visible strings
+ go through QObject::tr(), for example.
+*/
+
+/*! \fn bool QString::operator>(const QString &other) const
+
+ Returns true if this string is lexically greater than string \a
+ other; otherwise returns false.
+
+ The comparison is based exclusively on the numeric Unicode values
+ of the characters and is very fast, but is not what a human would
+ expect. Consider sorting user-interface strings with
+ localeAwareCompare().
+*/
+
+/*!
+ \overload operator>()
+*/
+bool QString::operator>(const QLatin1String &other) const
+{
+ const ushort *uc = d->data;;
+ const ushort *e = uc + d->size;
+ const uchar *c = (uchar *) other.latin1();
+
+ if (!c || *c == '\0')
+ return !isEmpty();
+
+ while (*c) {
+ if (uc == e || *uc != *c)
+ break;
+ ++uc;
+ ++c;
+ }
+ return (uc == e ? false : *uc > *c);
+}
+
+/*! \fn bool QString::operator>(const QByteArray &other) const
+
+ \overload operator>()
+
+ The \a other byte array is converted to a QString using the
+ fromAscii() function.
+
+ You can disable this operator by defining \c
+ QT_NO_CAST_FROM_ASCII when you compile your applications. This
+ can be useful if you want to ensure that all user-visible strings
+ go through QObject::tr(), for example.
+*/
+
+/*! \fn bool QString::operator>(const char *other) const
+
+ \overload operator>()
+
+ The \a other const char pointer is converted to a QString using
+ the fromAscii() function.
+
+ You can disable this operator by defining \c QT_NO_CAST_FROM_ASCII
+ when you compile your applications. This can be useful if you want
+ to ensure that all user-visible strings go through QObject::tr(),
+ for example.
+*/
+
+/*! \fn bool QString::operator>=(const QString &other) const
+
+ Returns true if this string is lexically greater than or equal to
+ string \a other; otherwise returns false.
+
+ The comparison is based exclusively on the numeric Unicode values
+ of the characters and is very fast, but is not what a human would
+ expect. Consider sorting user-interface strings with
+ localeAwareCompare().
+*/
+
+/*! \fn bool QString::operator>=(const QLatin1String &other) const
+
+ \overload operator>=()
+*/
+
+/*! \fn bool QString::operator>=(const QByteArray &other) const
+
+ \overload operator>=()
+
+ The \a other byte array is converted to a QString using the
+ fromAscii() function.
+
+ You can disable this operator by defining \c QT_NO_CAST_FROM_ASCII
+ when you compile your applications. This can be useful if you want
+ to ensure that all user-visible strings go through QObject::tr(),
+ for example.
+*/
+
+/*! \fn bool QString::operator>=(const char *other) const
+
+ \overload operator>=()
+
+ The \a other const char pointer is converted to a QString using
+ the fromAscii() function.
+
+ You can disable this operator by defining \c
+ QT_NO_CAST_FROM_ASCII when you compile your applications. This
+ can be useful if you want to ensure that all user-visible strings
+ go through QObject::tr(), for example.
+*/
+
+/*! \fn bool QString::operator!=(const QString &other) const
+
+ Returns true if this string is not equal to string \a other;
+ otherwise returns false.
+
+ The comparison is based exclusively on the numeric Unicode values
+ of the characters and is very fast, but is not what a human would
+ expect. Consider sorting user-interface strings with
+ localeAwareCompare().
+*/
+
+/*! \fn bool QString::operator!=(const QLatin1String &other) const
+
+ \overload operator!=()
+*/
+
+/*! \fn bool QString::operator!=(const QByteArray &other) const
+
+ \overload operator!=()
+
+ The \a other byte array is converted to a QString using the
+ fromAscii() function.
+
+ You can disable this operator by defining \c QT_NO_CAST_FROM_ASCII
+ when you compile your applications. This can be useful if you want
+ to ensure that all user-visible strings go through QObject::tr(),
+ for example.
+*/
+
+/*! \fn bool QString::operator!=(const char *other) const
+
+ \overload operator!=()
+
+ The \a other const char pointer is converted to a QString using
+ the fromAscii() function.
+
+ You can disable this operator by defining \c
+ QT_NO_CAST_FROM_ASCII when you compile your applications. This
+ can be useful if you want to ensure that all user-visible strings
+ go through QObject::tr(), for example.
+*/
+
+/*!
+ Returns the index position of the first occurrence of the string \a
+ str in this string, searching forward from index position \a
+ from. Returns -1 if \a str is not found.
+
+ If \a cs is Qt::CaseSensitive (default), the search is case
+ sensitive; otherwise the search is case insensitive.
+
+ Example:
+
+ \snippet doc/src/snippets/qstring/main.cpp 24
+
+ If \a from is -1, the search starts at the last character; if it is
+ -2, at the next to last character and so on.
+
+ \sa lastIndexOf(), contains(), count()
+*/
+int QString::indexOf(const QString &str, int from, Qt::CaseSensitivity cs) const
+{
+ return qFindString(unicode(), length(), from, str.unicode(), str.length(), cs);
+}
+
+/*!
+ \since 4.5
+ Returns the index position of the first occurrence of the string \a
+ str in this string, searching forward from index position \a
+ from. Returns -1 if \a str is not found.
+
+ If \a cs is Qt::CaseSensitive (default), the search is case
+ sensitive; otherwise the search is case insensitive.
+
+ Example:
+
+ \snippet doc/src/snippets/qstring/main.cpp 24
+
+ If \a from is -1, the search starts at the last character; if it is
+ -2, at the next to last character and so on.
+
+ \sa lastIndexOf(), contains(), count()
+*/
+int QString::indexOf(const QLatin1String &str, int from, Qt::CaseSensitivity cs) const
+{
+ int len = qstrlen(str.latin1());
+ QVarLengthArray<ushort> s(len);
+ for (int i = 0; i < len; ++i)
+ s[i] = str.latin1()[i];
+
+ return qFindString(unicode(), length(), from, (const QChar *)s.data(), len, cs);
+}
+
+int qFindString(
+ const QChar *haystack0, int haystackLen, int from,
+ const QChar *needle0, int needleLen, Qt::CaseSensitivity cs)
+{
+ 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, needle0[0], from, cs);
+
+ /*
+ 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 qFindStringBoyerMoore(haystack0, haystackLen, from,
+ needle0, needleLen, cs);
+
+ /*
+ 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
+ ucstrncmp() or ucstrnicmp().
+ */
+ const ushort *needle = (const ushort *)needle0;
+ const ushort *haystack = (const ushort *)haystack0 + from;
+ const ushort *end = (const ushort *)haystack0 + (l-sl);
+ const int sl_minus_1 = sl-1;
+ int hashNeedle = 0, hashHaystack = 0, idx;
+
+ if (cs == Qt::CaseSensitive) {
+ 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
+ && ucstrncmp((const QChar *)needle, (const QChar *)haystack, sl) == 0)
+ return haystack - (const ushort *)haystack0;
+
+ REHASH(*haystack);
+ ++haystack;
+ }
+ } else {
+ const ushort *haystack_start = (const ushort *)haystack0;
+ for (idx = 0; idx < sl; ++idx) {
+ hashNeedle = (hashNeedle<<1) + foldCase(needle + idx, needle);
+ hashHaystack = (hashHaystack<<1) + foldCase(haystack + idx, haystack_start);
+ }
+ hashHaystack -= foldCase(haystack + sl_minus_1, haystack_start);
+
+ while (haystack <= end) {
+ hashHaystack += foldCase(haystack + sl_minus_1, haystack_start);
+ if (hashHaystack == hashNeedle && ucstrnicmp(needle, haystack, sl) == 0)
+ return haystack - (const ushort *)haystack0;
+
+ REHASH(foldCase(haystack, haystack_start));
+ ++haystack;
+ }
+ }
+ return -1;
+}
+
+/*!
+ \overload indexOf()
+
+ Returns the index position of the first occurrence of the
+ character \a ch in the string, searching forward from index
+ position \a from. Returns -1 if \a ch could not be found.
+*/
+int QString::indexOf(QChar ch, int from, Qt::CaseSensitivity cs) const
+{
+ return findChar(unicode(), length(), ch, from, cs);
+}
+
+static int lastIndexOfHelper(const ushort *haystack, int from, const ushort *needle, int sl, Qt::CaseSensitivity cs)
+{
+ /*
+ See indexOf() for explanations.
+ */
+
+ const ushort *end = haystack;
+ haystack += from;
+ const int sl_minus_1 = sl-1;
+ const ushort *n = needle+sl_minus_1;
+ const ushort *h = haystack+sl_minus_1;
+ int hashNeedle = 0, hashHaystack = 0, idx;
+
+ if (cs == Qt::CaseSensitive) {
+ for (idx = 0; idx < sl; ++idx) {
+ hashNeedle = ((hashNeedle<<1) + *(n-idx));
+ hashHaystack = ((hashHaystack<<1) + *(h-idx));
+ }
+ hashHaystack -= *haystack;
+
+ while (haystack >= end) {
+ hashHaystack += *haystack;
+ if (hashHaystack == hashNeedle
+ && ucstrncmp((const QChar *)needle, (const QChar *)haystack, sl) == 0)
+ return haystack - end;
+ --haystack;
+ REHASH(haystack[sl]);
+ }
+ } else {
+ for (idx = 0; idx < sl; ++idx) {
+ hashNeedle = ((hashNeedle<<1) + foldCase(n-idx, needle));
+ hashHaystack = ((hashHaystack<<1) + foldCase(h-idx, end));
+ }
+ hashHaystack -= foldCase(haystack, end);
+
+ while (haystack >= end) {
+ hashHaystack += foldCase(haystack, end);
+ if (hashHaystack == hashNeedle && ucstrnicmp(needle, haystack, sl) == 0)
+ return haystack - end;
+ --haystack;
+ REHASH(foldCase(haystack + sl, end));
+ }
+ }
+ return -1;
+}
+
+/*!
+ Returns the index position of the last occurrence of the string \a
+ str in this string, searching backward from index position \a
+ from. If \a from is -1 (default), the search starts at the last
+ character; if \a from is -2, at the next to last character and so
+ on. Returns -1 if \a str is not found.
+
+ If \a cs is Qt::CaseSensitive (default), the search is case
+ sensitive; otherwise the search is case insensitive.
+
+ Example:
+
+ \snippet doc/src/snippets/qstring/main.cpp 29
+
+ \sa indexOf(), contains(), count()
+*/
+int QString::lastIndexOf(const QString &str, int from, Qt::CaseSensitivity cs) const
+{
+ const int sl = str.d->size;
+ if (sl == 1)
+ return lastIndexOf(QChar(str.d->data[0]), from, cs);
+
+ const int l = d->size;
+ if (from < 0)
+ from += l;
+ int delta = l-sl;
+ if (from == l && sl == 0)
+ return from;
+ if (from < 0 || from >= l || delta < 0)
+ return -1;
+ if (from > delta)
+ from = delta;
+
+
+ return lastIndexOfHelper(d->data, from, str.d->data, str.d->size, cs);
+}
+
+/*!
+ \since 4.5
+ Returns the index position of the last occurrence of the string \a
+ str in this string, searching backward from index position \a
+ from. If \a from is -1 (default), the search starts at the last
+ character; if \a from is -2, at the next to last character and so
+ on. Returns -1 if \a str is not found.
+
+ If \a cs is Qt::CaseSensitive (default), the search is case
+ sensitive; otherwise the search is case insensitive.
+
+ Example:
+
+ \snippet doc/src/snippets/qstring/main.cpp 29
+
+ \sa indexOf(), contains(), count()
+*/
+int QString::lastIndexOf(const QLatin1String &str, int from, Qt::CaseSensitivity cs) const
+{
+ const int sl = qstrlen(str.latin1());
+ if (sl == 1)
+ return lastIndexOf(QLatin1Char(str.latin1()[0]), from, cs);
+
+ const int l = d->size;
+ if (from < 0)
+ from += l;
+ int delta = l-sl;
+ if (from == l && sl == 0)
+ return from;
+ if (from < 0 || from >= l || delta < 0)
+ return -1;
+ if (from > delta)
+ from = delta;
+
+ QVarLengthArray<ushort> s(sl);
+ for (int i = 0; i < sl; ++i)
+ s[i] = str.latin1()[i];
+
+ return lastIndexOfHelper(d->data, from, s.data(), sl, cs);
+}
+
+/*!
+ \overload lastIndexOf()
+
+ Returns the index position of the last occurrence of the character
+ \a ch, searching backward from position \a from.
+*/
+int QString::lastIndexOf(QChar ch, int from, Qt::CaseSensitivity cs) const
+{
+ ushort c = ch.unicode();
+ if (from < 0)
+ from += d->size;
+ if (from < 0 || from >= d->size)
+ return -1;
+ if (from >= 0) {
+ const ushort *n = d->data + from;
+ const ushort *b = d->data;
+ if (cs == Qt::CaseSensitive) {
+ for (; n >= b; --n)
+ if (*n == c)
+ return n - b;
+ } else {
+ c = foldCase(c);
+ for (; n >= b; --n)
+ if (foldCase(*n) == c)
+ return n - b;
+ }
+ }
+ return -1;
+}
+
+#ifndef QT_NO_REGEXP
+struct QStringCapture
+{
+ int pos;
+ int len;
+ int no;
+};
+
+/*!
+ \overload replace()
+
+ Replaces every occurrence of the regular expression \a rx in the
+ string with \a after. Returns a reference to the string. For
+ example:
+
+ \snippet doc/src/snippets/qstring/main.cpp 42
+
+ For regular expressions containing \l{capturing parentheses},
+ occurrences of \bold{\\1}, \bold{\\2}, ..., in \a after are replaced
+ with \a{rx}.cap(1), cap(2), ...
+
+ \snippet doc/src/snippets/qstring/main.cpp 43
+
+ \sa indexOf(), lastIndexOf(), remove(), QRegExp::cap()
+*/
+QString& QString::replace(const QRegExp &rx, const QString &after)
+{
+ QRegExp rx2(rx);
+
+ if (isEmpty() && rx2.indexIn(*this) == -1)
+ return *this;
+
+ realloc();
+
+ int index = 0;
+ int numCaptures = rx2.numCaptures();
+ int al = after.length();
+ QRegExp::CaretMode caretMode = QRegExp::CaretAtZero;
+
+ if (numCaptures > 0) {
+ const QChar *uc = after.unicode();
+ int numBackRefs = 0;
+
+ for (int i = 0; i < al - 1; i++) {
+ if (uc[i] == QLatin1Char('\\')) {
+ int no = uc[i + 1].digitValue();
+ if (no > 0 && no <= numCaptures)
+ numBackRefs++;
+ }
+ }
+
+ /*
+ This is the harder case where we have back-references.
+ */
+ if (numBackRefs > 0) {
+ QVarLengthArray<QStringCapture, 16> captures(numBackRefs);
+ int j = 0;
+
+ for (int i = 0; i < al - 1; i++) {
+ if (uc[i] == QLatin1Char('\\')) {
+ int no = uc[i + 1].digitValue();
+ if (no > 0 && no <= numCaptures) {
+ QStringCapture capture;
+ capture.pos = i;
+ capture.len = 2;
+
+ if (i < al - 2) {
+ int secondDigit = uc[i + 2].digitValue();
+ if (secondDigit != -1 && ((no * 10) + secondDigit) <= numCaptures) {
+ no = (no * 10) + secondDigit;
+ ++capture.len;
+ }
+ }
+
+ capture.no = no;
+ captures[j++] = capture;
+ }
+ }
+ }
+
+ while (index <= length()) {
+ index = rx2.indexIn(*this, index, caretMode);
+ if (index == -1)
+ break;
+
+ QString after2(after);
+ for (j = numBackRefs - 1; j >= 0; j--) {
+ const QStringCapture &capture = captures[j];
+ after2.replace(capture.pos, capture.len, rx2.cap(capture.no));
+ }
+
+ replace(index, rx2.matchedLength(), after2);
+ index += after2.length();
+
+ // avoid infinite loop on 0-length matches (e.g., QRegExp("[a-z]*"))
+ if (rx2.matchedLength() == 0)
+ ++index;
+
+ caretMode = QRegExp::CaretWontMatch;
+ }
+ return *this;
+ }
+ }
+
+ /*
+ This is the simple and optimized case where we don't have
+ back-references.
+ */
+ while (index != -1) {
+ struct {
+ int pos;
+ int length;
+ } replacements[2048];
+
+ int pos = 0;
+ int adjust = 0;
+ while (pos < 2047) {
+ index = rx2.indexIn(*this, index, caretMode);
+ if (index == -1)
+ break;
+ int ml = rx2.matchedLength();
+ replacements[pos].pos = index;
+ replacements[pos++].length = ml;
+ index += ml;
+ adjust += al - ml;
+ // avoid infinite loop
+ if (!ml)
+ index++;
+ }
+ if (!pos)
+ break;
+ replacements[pos].pos = d->size;
+ int newlen = d->size + adjust;
+
+ // to continue searching at the right position after we did
+ // the first round of replacements
+ if (index != -1)
+ index += adjust;
+ QString newstring;
+ newstring.reserve(newlen + 1);
+ QChar *newuc = newstring.data();
+ QChar *uc = newuc;
+ int copystart = 0;
+ int i = 0;
+ while (i < pos) {
+ int copyend = replacements[i].pos;
+ int size = copyend - copystart;
+ memcpy(uc, d->data + copystart, size * sizeof(QChar));
+ uc += size;
+ memcpy(uc, after.d->data, al * sizeof(QChar));
+ uc += al;
+ copystart = copyend + replacements[i].length;
+ i++;
+ }
+ memcpy(uc, d->data + copystart, (d->size - copystart) * sizeof(QChar));
+ newstring.resize(newlen);
+ *this = newstring;
+ caretMode = QRegExp::CaretWontMatch;
+ }
+ return *this;
+}
+#endif
+
+/*!
+ Returns the number of (potentially overlapping) occurrences of
+ the string \a str in this string.
+
+ If \a cs is Qt::CaseSensitive (default), the search is
+ case sensitive; otherwise the search is case insensitive.
+
+ \sa contains(), indexOf()
+*/
+int QString::count(const QString &str, Qt::CaseSensitivity cs) const
+{
+ int num = 0;
+ int i = -1;
+ if (d->size > 500 && str.d->size > 5) {
+ QStringMatcher matcher(str, cs);
+ while ((i = matcher.indexIn(*this, i + 1)) != -1)
+ ++num;
+ } else {
+ while ((i = indexOf(str, i + 1, cs)) != -1)
+ ++num;
+ }
+ return num;
+}
+
+/*!
+ \overload count()
+
+ Returns the number of occurrences of character \a ch in the string.
+*/
+int QString::count(QChar ch, Qt::CaseSensitivity cs) const
+{
+ ushort c = ch.unicode();
+ int num = 0;
+ const ushort *i = d->data + d->size;
+ const ushort *b = d->data;
+ if (cs == Qt::CaseSensitive) {
+ while (i != b)
+ if (*--i == c)
+ ++num;
+ } else {
+ c = foldCase(c);
+ while (i != b)
+ if (foldCase(*(--i)) == c)
+ ++num;
+ }
+ return num;
+}
+
+/*! \fn bool QString::contains(const QString &str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const
+
+ Returns true if this string contains an occurrence of the string
+ \a str; otherwise returns false.
+
+ If \a cs is Qt::CaseSensitive (default), the search is
+ case sensitive; otherwise the search is case insensitive.
+
+ Example:
+ \snippet doc/src/snippets/qstring/main.cpp 17
+
+ \sa indexOf(), count()
+*/
+
+/*! \fn bool QString::contains(QChar ch, Qt::CaseSensitivity cs = Qt::CaseSensitive) const
+
+ \overload contains()
+
+ Returns true if this string contains an occurrence of the
+ character \a ch; otherwise returns false.
+*/
+
+/*! \fn bool QString::contains(const QRegExp &rx) const
+
+ \overload contains()
+
+ Returns true if the regular expression \a rx matches somewhere in
+ this string; otherwise returns false.
+*/
+
+/*! \fn bool QString::contains(QRegExp &rx) const
+ \overload contains()
+ \since 4.5
+
+ Returns true if the regular expression \a rx matches somewhere in
+ this string; otherwise returns false.
+
+ If there is a match, the \a rx regular expression will contain the
+ matched captures (see QRegExp::matchedLength, QRegExp::cap).
+*/
+
+#ifndef QT_NO_REGEXP
+/*!
+ \overload indexOf()
+
+ Returns the index position of the first match of the regular
+ expression \a rx in the string, searching forward from index
+ position \a from. Returns -1 if \a rx didn't match anywhere.
+
+ Example:
+
+ \snippet doc/src/snippets/qstring/main.cpp 25
+*/
+int QString::indexOf(const QRegExp& rx, int from) const
+{
+ QRegExp rx2(rx);
+ return rx2.indexIn(*this, from);
+}
+
+/*!
+ \overload indexOf()
+ \since 4.5
+
+ Returns the index position of the first match of the regular
+ expression \a rx in the string, searching forward from index
+ position \a from. Returns -1 if \a rx didn't match anywhere.
+
+ If there is a match, the \a rx regular expression will contain the
+ matched captures (see QRegExp::matchedLength, QRegExp::cap).
+
+ Example:
+
+ \snippet doc/src/snippets/qstring/main.cpp 25
+*/
+int QString::indexOf(QRegExp& rx, int from) const
+{
+ return rx.indexIn(*this, from);
+}
+
+/*!
+ \overload lastIndexOf()
+
+ Returns the index position of the last match of the regular
+ expression \a rx in the string, searching backward from index
+ position \a from. Returns -1 if \a rx didn't match anywhere.
+
+ Example:
+
+ \snippet doc/src/snippets/qstring/main.cpp 30
+*/
+int QString::lastIndexOf(const QRegExp& rx, int from) const
+{
+ QRegExp rx2(rx);
+ return rx2.lastIndexIn(*this, from);
+}
+
+/*!
+ \overload lastIndexOf()
+ \since 4.5
+
+ Returns the index position of the last match of the regular
+ expression \a rx in the string, searching backward from index
+ position \a from. Returns -1 if \a rx didn't match anywhere.
+
+ If there is a match, the \a rx regular expression will contain the
+ matched captures (see QRegExp::matchedLength, QRegExp::cap).
+
+ Example:
+
+ \snippet doc/src/snippets/qstring/main.cpp 30
+*/
+int QString::lastIndexOf(QRegExp& rx, int from) const
+{
+ return rx.lastIndexIn(*this, from);
+}
+
+/*!
+ \overload count()
+
+ Returns the number of times the regular expression \a rx matches
+ in the string.
+
+ This function counts overlapping matches, so in the example
+ below, there are four instances of "ana" or "ama":
+
+ \snippet doc/src/snippets/qstring/main.cpp 18
+
+*/
+int QString::count(const QRegExp& rx) const
+{
+ QRegExp rx2(rx);
+ int count = 0;
+ int index = -1;
+ int len = length();
+ while (index < len - 1) { // count overlapping matches
+ index = rx2.indexIn(*this, index + 1);
+ if (index == -1)
+ break;
+ count++;
+ }
+ return count;
+}
+#endif // QT_NO_REGEXP
+
+/*! \fn int QString::count() const
+
+ \overload count()
+
+ Same as size().
+*/
+
+
+/*!
+ \enum QString::SectionFlag
+
+ This enum specifies flags that can be used to affect various
+ aspects of the section() function's behavior with respect to
+ separators and empty fields.
+
+ \value SectionDefault Empty fields are counted, leading and
+ trailing separators are not included, and the separator is
+ compared case sensitively.
+
+ \value SectionSkipEmpty Treat empty fields as if they don't exist,
+ i.e. they are not considered as far as \e start and \e end are
+ concerned.
+
+ \value SectionIncludeLeadingSep Include the leading separator (if
+ any) in the result string.
+
+ \value SectionIncludeTrailingSep Include the trailing separator
+ (if any) in the result string.
+
+ \value SectionCaseInsensitiveSeps Compare the separator
+ case-insensitively.
+
+ \sa section()
+*/
+
+/*!
+ \fn QString QString::section(QChar sep, int start, int end = -1, SectionFlags flags) const
+
+ This function returns a section of the string.
+
+ This string is treated as a sequence of fields separated by the
+ character, \a sep. The returned string consists of the fields from
+ position \a start to position \a end inclusive. If \a end is not
+ specified, all fields from position \a start to the end of the
+ string are included. Fields are numbered 0, 1, 2, etc., counting
+ from the left, and -1, -2, etc., counting from right to left.
+
+ The \a flags argument can be used to affect some aspects of the
+ function's behavior, e.g. whether to be case sensitive, whether
+ to skip empty fields and how to deal with leading and trailing
+ separators; see \l{SectionFlags}.
+
+ \snippet doc/src/snippets/qstring/main.cpp 52
+
+ If \a start or \a end is negative, we count fields from the right
+ of the string, the right-most field being -1, the one from
+ right-most field being -2, and so on.
+
+ \snippet doc/src/snippets/qstring/main.cpp 53
+
+ \sa split()
+*/
+
+/*!
+ \overload section()
+
+ \snippet doc/src/snippets/qstring/main.cpp 51
+ \snippet doc/src/snippets/qstring/main.cpp 54
+
+ \sa split()
+*/
+
+QString QString::section(const QString &sep, int start, int end, SectionFlags flags) const
+{
+ QStringList sections = split(sep, KeepEmptyParts,
+ (flags & SectionCaseInsensitiveSeps) ? Qt::CaseInsensitive : Qt::CaseSensitive);
+ if (sections.isEmpty())
+ return QString();
+ if (!(flags & SectionSkipEmpty)) {
+ if (start < 0)
+ start += sections.count();
+ if (end < 0)
+ end += sections.count();
+ } else {
+ int skip = 0;
+ for (int k=0; k<sections.size(); ++k) {
+ if (sections.at(k).isEmpty())
+ skip++;
+ }
+ if (start < 0)
+ start += sections.count() - skip;
+ if (end < 0)
+ end += sections.count() - skip;
+ }
+ int x = 0;
+ QString ret;
+ int first_i = start, last_i = end;
+ for (int i = 0; x <= end && i < sections.size(); ++i) {
+ QString section = sections.at(i);
+ const bool empty = section.isEmpty();
+ if (x >= start) {
+ if(x == start)
+ first_i = i;
+ if(x == end)
+ last_i = i;
+ if(x > start)
+ ret += sep;
+ ret += section;
+ }
+ if (!empty || !(flags & SectionSkipEmpty))
+ x++;
+ }
+ if((flags & SectionIncludeLeadingSep) && first_i)
+ ret.prepend(sep);
+ if((flags & SectionIncludeTrailingSep) && last_i < sections.size()-1)
+ ret += sep;
+ return ret;
+}
+
+#ifndef QT_NO_REGEXP
+class qt_section_chunk {
+public:
+ qt_section_chunk(int l, QString s) { length = l; string = s; }
+ int length;
+ QString string;
+};
+
+/*!
+ \overload section()
+
+ This string is treated as a sequence of fields separated by the
+ regular expression, \a reg.
+
+ \snippet doc/src/snippets/qstring/main.cpp 55
+
+ \warning Using this QRegExp version is much more expensive than
+ the overloaded string and character versions.
+
+ \sa split() simplified()
+*/
+QString QString::section(const QRegExp &reg, int start, int end, SectionFlags flags) const
+{
+ const QChar *uc = unicode();
+ if(!uc)
+ return QString();
+
+ QRegExp sep(reg);
+ sep.setCaseSensitivity((flags & SectionCaseInsensitiveSeps) ? Qt::CaseInsensitive
+ : Qt::CaseSensitive);
+
+ QList<qt_section_chunk> sections;
+ int n = length(), m = 0, last_m = 0, last_len = 0;
+ while ((m = sep.indexIn(*this, m)) != -1) {
+ sections.append(qt_section_chunk(last_len, QString(uc + last_m, m - last_m)));
+ last_m = m;
+ last_len = sep.matchedLength();
+ m += qMax(sep.matchedLength(), 1);
+ }
+ sections.append(qt_section_chunk(last_len, QString(uc + last_m, n - last_m)));
+
+ if(start < 0)
+ start += sections.count();
+ if(end < 0)
+ end += sections.count();
+
+ QString ret;
+ int x = 0;
+ int first_i = start, last_i = end;
+ for (int i = 0; x <= end && i < sections.size(); ++i) {
+ const qt_section_chunk &section = sections.at(i);
+ const bool empty = (section.length == section.string.length());
+ if (x >= start) {
+ if(x == start)
+ first_i = i;
+ if(x == end)
+ last_i = i;
+ if(x != start)
+ ret += section.string;
+ else
+ ret += section.string.mid(section.length);
+ }
+ if (!empty || !(flags & SectionSkipEmpty))
+ x++;
+ }
+ if((flags & SectionIncludeLeadingSep)) {
+ const qt_section_chunk &section = sections.at(first_i);
+ ret.prepend(section.string.left(section.length));
+ }
+ if((flags & SectionIncludeTrailingSep) && last_i+1 <= sections.size()-1) {
+ const qt_section_chunk &section = sections.at(last_i+1);
+ ret += section.string.left(section.length);
+ }
+ return ret;
+}
+#endif
+
+/*!
+ Returns a substring that contains the \a n leftmost characters
+ of the string.
+
+ The entire string is returned if \a n is greater than size() or
+ less than zero.
+
+ \snippet doc/src/snippets/qstring/main.cpp 31
+
+ \sa right(), mid(), startsWith()
+*/
+QString QString::left(int n) const
+{
+ if (n >= d->size || n < 0)
+ return *this;
+ return QString((const QChar*) d->data, n);
+}
+
+/*!
+ Returns a substring that contains the \a n rightmost characters
+ of the string.
+
+ The entire string is returned if \a n is greater than size() or
+ less than zero.
+
+ \snippet doc/src/snippets/qstring/main.cpp 48
+
+ \sa left(), mid(), endsWith()
+*/
+QString QString::right(int n) const
+{
+ if (n >= d->size || n < 0)
+ return *this;
+ return QString((const QChar*) d->data + d->size - n, n);
+}
+
+/*!
+ Returns a string that contains \a n characters of this string,
+ starting at the specified \a position index.
+
+ Returns a null string if the \a position index exceeds the
+ length of the string. If there are less than \a n characters
+ available in the string starting at the given \a position, or if
+ \a n is -1 (default), the function returns all characters that
+ are available from the specified \a position.
+
+ Example:
+
+ \snippet doc/src/snippets/qstring/main.cpp 34
+
+ \sa left(), right()
+*/
+
+QString QString::mid(int position, int n) const
+{
+ if (d == &shared_null || position >= d->size)
+ return QString();
+ if (n < 0)
+ n = d->size - position;
+ if (position < 0) {
+ n += position;
+ position = 0;
+ }
+ if (n + position > d->size)
+ n = d->size - position;
+ if (position == 0 && n == d->size)
+ return *this;
+ return QString((const QChar*) d->data + position, n);
+}
+
+/*!
+ Returns true if the string starts with \a s; otherwise returns
+ false.
+
+ If \a cs is Qt::CaseSensitive (default), the search is
+ case sensitive; otherwise the search is case insensitive.
+
+ \snippet doc/src/snippets/qstring/main.cpp 65
+
+ \sa endsWith()
+*/
+bool QString::startsWith(const QString& s, Qt::CaseSensitivity cs) const
+{
+ if (d == &shared_null)
+ return (s.d == &shared_null);
+ if (d->size == 0)
+ return s.d->size == 0;
+ if (s.d->size > d->size)
+ return false;
+ if (cs == Qt::CaseSensitive) {
+ return memcmp((char*)d->data, (char*)s.d->data, s.d->size*sizeof(QChar)) == 0;
+ } else {
+ uint last = 0;
+ uint olast = 0;
+ for (int i = 0; i < s.d->size; ++i)
+ if (foldCase(d->data[i], last) != foldCase(s.d->data[i], olast))
+ return false;
+ }
+ return true;
+}
+
+/*!
+ \overload startsWith()
+ */
+bool QString::startsWith(const QLatin1String& s, Qt::CaseSensitivity cs) const
+{
+ if (d == &shared_null)
+ return (s.latin1() == 0);
+ if (d->size == 0)
+ return !s.latin1() || *s.latin1() == 0;
+ int slen = qstrlen(s.latin1());
+ if (slen > d->size)
+ return false;
+ const uchar *latin = (const uchar *)s.latin1();
+ if (cs == Qt::CaseSensitive) {
+ for (int i = 0; i < slen; ++i)
+ if (d->data[i] != latin[i])
+ return false;
+ } else {
+ for (int i = 0; i < slen; ++i)
+ if (foldCase(d->data[i]) != foldCase((ushort)latin[i]))
+ return false;
+ }
+ return true;
+}
+
+/*!
+ \overload startsWith()
+
+ Returns true if the string starts with \a c; otherwise returns
+ false.
+*/
+bool QString::startsWith(const QChar &c, Qt::CaseSensitivity cs) const
+{
+ return d->size
+ && (cs == Qt::CaseSensitive
+ ? d->data[0] == c
+ : foldCase(d->data[0]) == foldCase(c.unicode()));
+}
+
+/*!
+ Returns true if the string ends with \a s; otherwise returns
+ false.
+
+ If \a cs is Qt::CaseSensitive (default), the search is case
+ sensitive; otherwise the search is case insensitive.
+
+ \snippet doc/src/snippets/qstring/main.cpp 20
+
+ \sa startsWith()
+*/
+bool QString::endsWith(const QString& s, Qt::CaseSensitivity cs) const
+{
+ if (d == &shared_null)
+ return (s.d == &shared_null);
+ if (d->size == 0)
+ return s.d->size == 0;
+ int pos = d->size - s.d->size;
+ if (pos < 0)
+ return false;
+ if (cs == Qt::CaseSensitive) {
+ return memcmp((char*)&d->data[pos], (char*)s.d->data, s.d->size*sizeof(QChar)) == 0;
+ } else {
+ uint last = 0;
+ uint olast = 0;
+ for (int i = 0; i < s.length(); i++)
+ if (foldCase(d->data[pos+i], last) != foldCase(s.d->data[i], olast))
+ return false;
+ }
+ return true;
+}
+
+/*!
+ \overload endsWith()
+*/
+bool QString::endsWith(const QLatin1String& s, Qt::CaseSensitivity cs) const
+{
+ if (d == &shared_null)
+ return (s.latin1() == 0);
+ if (d->size == 0)
+ return !s.latin1() || *s.latin1() == 0;
+ int slen = qstrlen(s.latin1());
+ int pos = d->size - slen;
+ const uchar *latin = (const uchar *)s.latin1();
+ if (pos < 0)
+ return false;
+ if (cs == Qt::CaseSensitive) {
+ for (int i = 0; i < slen; i++)
+ if (d->data[pos+i] != latin[i])
+ return false;
+ } else {
+ for (int i = 0; i < slen; i++)
+ if (foldCase(d->data[pos+i]) != foldCase((ushort)latin[i]))
+ return false;
+ }
+ return true;
+}
+
+/*!
+ Returns true if the string ends with \a c; otherwise returns
+ false.
+
+ \overload endsWith()
+ */
+bool QString::endsWith(const QChar &c, Qt::CaseSensitivity cs) const
+{
+ return d->size
+ && (cs == Qt::CaseSensitive
+ ? d->data[d->size - 1] == c
+ : foldCase(d->data[d->size - 1]) == foldCase(c.unicode()));
+}
+
+/*! \fn const char *QString::ascii() const
+ \nonreentrant
+
+ Use toAscii() instead.
+*/
+
+/*! \fn const char *QString::latin1() const
+ \nonreentrant
+
+ Use toLatin1() instead.
+*/
+
+/*! \fn const char *QString::utf8() const
+ \nonreentrant
+
+ Use toUtf8() instead.
+*/
+
+/*! \fn const char *QString::local8Bit() const
+ \nonreentrant
+
+ Use toLocal8Bit() instead.
+*/
+
+static QByteArray toLatin1_helper(const QChar *data, int length)
+{
+ QByteArray ba;
+ if (length) {
+ ba.resize(length);
+ const ushort *i = reinterpret_cast<const ushort *>(data);
+ const ushort *e = i + length;
+ uchar *s = (uchar*) ba.data();
+ while (i != e) {
+ *s++ = (*i>0xff) ? '?' : (uchar) *i;
+ ++i;
+ }
+ }
+ return ba;
+}
+
+/*!
+ Returns a Latin-1 representation of the string as a QByteArray.
+ The returned byte array is undefined if the string contains
+ non-Latin1 characters.
+
+ \sa fromLatin1(), toAscii(), toUtf8(), toLocal8Bit(), QTextCodec
+*/
+QByteArray QString::toLatin1() const
+{
+ return toLatin1_helper(unicode(), length());
+}
+
+// ### Qt 5: Change the return type of at least toAscii(),
+// toLatin1() and unicode() such that the use of Q_COMPILER_MANGLES_RETURN_TYPE
+// isn't necessary in the header. See task 177402.
+
+/*!
+ Returns an 8-bit ASCII representation of the string as a QByteArray.
+
+ If a codec has been set using QTextCodec::setCodecForCStrings(),
+ it is used to convert Unicode to 8-bit char; otherwise this
+ function does the same as toLatin1().
+
+ \sa fromAscii(), toLatin1(), toUtf8(), toLocal8Bit(), QTextCodec
+*/
+QByteArray QString::toAscii() const
+{
+#ifndef QT_NO_TEXTCODEC
+ if (codecForCStrings)
+ return codecForCStrings->fromUnicode(*this);
+#endif // QT_NO_TEXTCODEC
+ return toLatin1();
+}
+
+#ifndef Q_WS_MAC
+static QByteArray toLocal8Bit_helper(const QChar *data, int length)
+{
+#ifndef QT_NO_TEXTCODEC
+ if (QTextCodec::codecForLocale())
+ return QTextCodec::codecForLocale()->fromUnicode(data, length);
+#endif // QT_NO_TEXTCODEC
+ return toLatin1_helper(data, length);
+}
+#endif
+
+/*!
+ Returns the local 8-bit representation of the string as a
+ QByteArray. The returned byte array is undefined if the string
+ contains characters not supported by the local 8-bit encoding.
+
+ QTextCodec::codecForLocale() is used to perform the conversion
+ from Unicode.
+
+ \sa fromLocal8Bit(), toAscii(), toLatin1(), toUtf8(), QTextCodec
+*/
+QByteArray QString::toLocal8Bit() const
+{
+#ifndef QT_NO_TEXTCODEC
+ if (QTextCodec::codecForLocale())
+ return QTextCodec::codecForLocale()->fromUnicode(*this);
+#endif // QT_NO_TEXTCODEC
+ return toLatin1();
+}
+
+/*!
+ Returns a UTF-8 representation of the string as a QByteArray.
+
+ \sa fromUtf8(), toAscii(), toLatin1(), toLocal8Bit(), QTextCodec
+*/
+QByteArray QString::toUtf8() const
+{
+ QByteArray ba;
+ if (d->size) {
+ int l = d->size;
+ int rlen = l*3+1;
+ ba.resize(rlen);
+ uchar *cursor = (uchar*)ba.data();
+ const ushort *ch =d->data;
+ for (int i=0; i < l; i++) {
+ uint u = *ch;
+ if (u < 0x80) {
+ *cursor++ = (uchar)u;
+ } else {
+ if (u < 0x0800) {
+ *cursor++ = 0xc0 | ((uchar) (u >> 6));
+ } else {
+ if (QChar(u).isHighSurrogate() && i < l-1) {
+ ushort low = ch[1];
+ if (QChar(low).isLowSurrogate()) {
+ ++ch;
+ ++i;
+ u = QChar::surrogateToUcs4(u,low);
+ }
+ }
+ if (u > 0xffff) {
+ *cursor++ = 0xf0 | ((uchar) (u >> 18));
+ *cursor++ = 0x80 | (((uchar) (u >> 12)) & 0x3f);
+ } else {
+ *cursor++ = 0xe0 | ((uchar) (u >> 12));
+ }
+ *cursor++ = 0x80 | (((uchar) (u >> 6)) & 0x3f);
+ }
+ *cursor++ = 0x80 | ((uchar) (u&0x3f));
+ }
+ ++ch;
+ }
+ ba.resize(cursor - (uchar*)ba.constData());
+ }
+ return ba;
+}
+
+/*!
+ \since 4.2
+
+ Returns a UCS-4 representation of the string as a QVector<uint>.
+
+ \sa fromUtf8(), toAscii(), toLatin1(), toLocal8Bit(), QTextCodec, fromUcs4(), toWCharArray()
+*/
+QVector<uint> QString::toUcs4() const
+{
+ QVector<uint> v(length());
+ uint *a = v.data();
+ const unsigned short *uc = utf16();
+ for (int i = 0; i < length(); ++i) {
+ uint u = uc[i];
+ if (QChar(u).isHighSurrogate() && i < length()-1) {
+ ushort low = uc[i+1];
+ if (QChar(low).isLowSurrogate()) {
+ ++i;
+ u = QChar::surrogateToUcs4(u, low);
+ }
+ }
+ *a = u;
+ ++a;
+ }
+ v.resize(a - v.data());
+ return v;
+}
+
+QString::Data *QString::fromLatin1_helper(const char *str, int size)
+{
+ Data *d;
+ if (!str) {
+ d = &shared_null;
+ d->ref.ref();
+ } else if (size == 0 || (!*str && size < 0)) {
+ d = &shared_empty;
+ d->ref.ref();
+ } else {
+ if (size < 0)
+ size = qstrlen(str);
+ d = static_cast<Data *>(qMalloc(sizeof(Data) + size * sizeof(QChar)));
+ d->ref = 1;
+ d->alloc = d->size = size;
+ d->clean = d->asciiCache = d->simpletext = d->righttoleft = d->capacity = 0;
+ d->data = d->array;
+ ushort *i = d->data;
+ d->array[size] = '\0';
+ while (size--)
+ *i++ = (uchar)*str++;
+ }
+ return d;
+}
+
+QString::Data *QString::fromAscii_helper(const char *str, int size)
+{
+#ifndef QT_NO_TEXTCODEC
+ if (codecForCStrings) {
+ Data *d;
+ if (!str) {
+ d = &shared_null;
+ d->ref.ref();
+ } else if (size == 0 || (!*str && size < 0)) {
+ d = &shared_empty;
+ d->ref.ref();
+ } else {
+ if (size < 0)
+ size = qstrlen(str);
+ QString s = codecForCStrings->toUnicode(str, size);
+ d = s.d;
+ d->ref.ref();
+ }
+ return d;
+ }
+#endif
+ return fromLatin1_helper(str, size);
+}
+
+/*!
+ Returns a QString initialized with the first \a size characters
+ of the Latin-1 string \a str.
+
+ If \a size is -1 (default), it is taken to be qstrlen(\a
+ str).
+
+ \sa toLatin1(), fromAscii(), fromUtf8(), fromLocal8Bit()
+*/
+QString QString::fromLatin1(const char *str, int size)
+{
+ return QString(fromLatin1_helper(str, size), 0);
+}
+
+
+#ifdef QT3_SUPPORT
+
+/*!
+ \internal
+*/
+const char *QString::ascii_helper() const
+{
+ if (!asciiCache)
+ asciiCache = new QHash<void *, QByteArray>();
+
+ d->asciiCache = true;
+ QByteArray ascii = toAscii();
+ QByteArray old = asciiCache->value(d);
+ if (old == ascii)
+ return old.constData();
+ asciiCache->insert(d, ascii);
+ return ascii.constData();
+}
+
+/*!
+ \internal
+*/
+const char *QString::latin1_helper() const
+{
+ if (!asciiCache)
+ asciiCache = new QHash<void *, QByteArray>();
+
+ d->asciiCache = true;
+ QByteArray ascii = toLatin1();
+ QByteArray old = asciiCache->value(d);
+ if (old == ascii)
+ return old.constData();
+ asciiCache->insert(d, ascii);
+ return ascii.constData();
+}
+
+#endif
+
+QT_END_NAMESPACE
+
+#if defined(Q_OS_WIN32) || defined(Q_OS_WINCE)
+#include "qt_windows.h"
+
+QT_BEGIN_NAMESPACE
+
+QByteArray qt_winQString2MB(const QString& s, int uclen)
+{
+ if (uclen < 0)
+ uclen = s.length();
+ if (s.isNull())
+ return QByteArray();
+ if (uclen == 0)
+ return QByteArray("");
+ return qt_winQString2MB(s.constData(), uclen);
+}
+
+QByteArray qt_winQString2MB(const QChar *ch, int uclen)
+{
+ if (!ch)
+ return QByteArray();
+ if (uclen == 0)
+ return QByteArray("");
+ BOOL used_def;
+ QByteArray mb(4096, 0);
+ int len;
+ while (!(len=WideCharToMultiByte(CP_ACP, 0, (const WCHAR*)ch, uclen,
+ mb.data(), mb.size()-1, 0, &used_def)))
+ {
+ int r = GetLastError();
+ if (r == ERROR_INSUFFICIENT_BUFFER) {
+ mb.resize(1+WideCharToMultiByte(CP_ACP, 0,
+ (const WCHAR*)ch, uclen,
+ 0, 0, 0, &used_def));
+ // and try again...
+ } else {
+#ifndef QT_NO_DEBUG
+ // Fail.
+ qWarning("WideCharToMultiByte: Cannot convert multibyte text (error %d): %s (UTF-8)",
+ r, QString(ch, uclen).toLocal8Bit().data());
+#endif
+ break;
+ }
+ }
+ mb.resize(len);
+ return mb;
+}
+
+QString qt_winMB2QString(const char *mb, int mblen)
+{
+ if (!mb || !mblen)
+ return QString();
+ const int wclen_auto = 4096;
+ WCHAR wc_auto[wclen_auto];
+ int wclen = wclen_auto;
+ WCHAR *wc = wc_auto;
+ int len;
+ while (!(len=MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED,
+ mb, mblen, wc, wclen)))
+ {
+ int r = GetLastError();
+ if (r == ERROR_INSUFFICIENT_BUFFER) {
+ if (wc != wc_auto) {
+ qWarning("MultiByteToWideChar: Size changed");
+ break;
+ } else {
+ wclen = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED,
+ mb, mblen, 0, 0);
+ wc = new WCHAR[wclen];
+ // and try again...
+ }
+ } else {
+ // Fail.
+ qWarning("MultiByteToWideChar: Cannot convert multibyte text");
+ break;
+ }
+ }
+ if (len <= 0)
+ return QString();
+ if (wc[len-1] == 0) // len - 1: we don't want terminator
+ --len;
+ QString s((QChar*)wc, len);
+ if (wc != wc_auto)
+ delete [] wc;
+ return s;
+}
+
+QT_END_NAMESPACE
+
+#endif // Q_OS_WIN32
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ Returns a QString initialized with the first \a size characters
+ of the 8-bit string \a str.
+
+ If \a size is -1 (default), it is taken to be qstrlen(\a
+ str).
+
+ QTextCodec::codecForLocale() is used to perform the conversion
+ from Unicode.
+
+ \sa toLocal8Bit(), fromAscii(), fromLatin1(), fromUtf8()
+*/
+QString QString::fromLocal8Bit(const char *str, int size)
+{
+ if (!str)
+ return QString();
+ if (size == 0 || (!*str && size < 0))
+ return QLatin1String("");
+#if defined(Q_OS_WIN32)
+ if(QSysInfo::WindowsVersion & QSysInfo::WV_DOS_based) {
+ return qt_winMB2QString(str, size);
+ }
+#endif
+#if !defined(QT_NO_TEXTCODEC)
+ if (size < 0)
+ size = qstrlen(str);
+ QTextCodec *codec = QTextCodec::codecForLocale();
+ if (codec)
+ return codec->toUnicode(str, size);
+#endif // !QT_NO_TEXTCODEC
+ return fromLatin1(str, size);
+}
+
+/*!
+ Returns a QString initialized with the first \a size characters
+ of the 8-bit ASCII string \a str.
+
+ If \a size is -1 (default), it is taken to be qstrlen(\a
+ str).
+
+ If a codec has been set using QTextCodec::setCodecForCStrings(),
+ it is used to convert \a str to Unicode; otherwise this function
+ does the same as fromLatin1().
+
+ \sa toAscii(), fromLatin1(), fromUtf8(), fromLocal8Bit()
+*/
+QString QString::fromAscii(const char *str, int size)
+{
+ return QString(fromAscii_helper(str, size), 0);
+}
+
+/*!
+ Returns a QString initialized with the first \a size bytes
+ of the UTF-8 string \a str.
+
+ If \a size is -1 (default), it is taken to be qstrlen(\a
+ str).
+
+ \sa toUtf8(), fromAscii(), fromLatin1(), fromLocal8Bit()
+*/
+QString QString::fromUtf8(const char *str, int size)
+{
+ if (!str)
+ return QString();
+ if (size < 0)
+ size = qstrlen(str);
+
+ QString result;
+ result.resize(size); // worst case
+ ushort *qch = result.d->data;
+ uint uc = 0;
+ uint min_uc = 0;
+ int need = 0;
+ int error = -1;
+ uchar ch;
+ int i = 0;
+
+ // skip utf8-encoded byte order mark
+ if (size >= 3
+ && (uchar)str[0] == 0xef && (uchar)str[1] == 0xbb && (uchar)str[2] == 0xbf)
+ i += 3;
+
+ for (; i < size; ++i) {
+ ch = str[i];
+ if (need) {
+ if ((ch&0xc0) == 0x80) {
+ uc = (uc << 6) | (ch & 0x3f);
+ need--;
+ if (!need) {
+ if (uc > 0xffffU && uc < 0x110000U) {
+ // surrogate pair
+ *qch++ = QChar::highSurrogate(uc);
+ uc = QChar::lowSurrogate(uc);
+ } else if ((uc < min_uc) || (uc >= 0xd800 && uc <= 0xdfff) || (uc >= 0xfffe)) {
+ // overlong seqence, UTF16 surrogate or BOM
+ uc = QChar::ReplacementCharacter;
+ }
+ *qch++ = uc;
+ }
+ } else {
+ i = error;
+ need = 0;
+ *qch++ = QChar::ReplacementCharacter;
+ }
+ } else {
+ if (ch < 128) {
+ *qch++ = ch;
+ } else if ((ch & 0xe0) == 0xc0) {
+ uc = ch & 0x1f;
+ need = 1;
+ error = i;
+ min_uc = 0x80;
+ } else if ((ch & 0xf0) == 0xe0) {
+ uc = ch & 0x0f;
+ need = 2;
+ error = i;
+ min_uc = 0x800;
+ } else if ((ch&0xf8) == 0xf0) {
+ uc = ch & 0x07;
+ need = 3;
+ error = i;
+ min_uc = 0x10000;
+ } else {
+ // Error
+ *qch++ = QChar::ReplacementCharacter;
+ }
+ }
+ }
+ if (need) {
+ // we have some invalid characters remaining we need to add to the string
+ for (int i = error; i < size; ++i)
+ *qch++ = QChar::ReplacementCharacter;
+ }
+
+ result.truncate(qch - result.d->data);
+ return result;
+}
+
+/*!
+ Returns a QString initialized with the first \a size characters
+ of the Unicode string \a unicode (ISO-10646-UTF-16 encoded).
+
+ If \a size is -1 (default), \a unicode must be terminated
+ with a 0.
+
+ QString makes a deep copy of the Unicode data.
+
+ \sa utf16(), setUtf16()
+*/
+QString QString::fromUtf16(const ushort *unicode, int size)
+{
+ if (!unicode)
+ return QString();
+ if (size < 0) {
+ size = 0;
+ while (unicode[size] != 0)
+ ++size;
+ }
+ return QString((const QChar *)unicode, size);
+}
+
+
+/*!
+ \since 4.2
+
+ Returns a QString initialized with the first \a size characters
+ of the Unicode string \a unicode (ISO-10646-UCS-4 encoded).
+
+ If \a size is -1 (default), \a unicode must be terminated
+ with a 0.
+
+ \sa toUcs4(), fromUtf16(), utf16(), setUtf16(), fromWCharArray()
+*/
+QString QString::fromUcs4(const uint *unicode, int size)
+{
+ if (!unicode)
+ return QString();
+ if (size < 0) {
+ size = 0;
+ while (unicode[size] != 0)
+ ++size;
+ }
+
+ QString s;
+ s.resize(size*2); // worst case
+ ushort *uc = s.d->data;
+ for (int i = 0; i < size; ++i) {
+ uint u = unicode[i];
+ if (u > 0xffff) {
+ // decompose into a surrogate pair
+ *uc++ = QChar::highSurrogate(u);
+ u = QChar::lowSurrogate(u);
+ }
+ *uc++ = u;
+ }
+ s.resize(uc - s.d->data);
+ return s;
+}
+
+/*!
+ Resizes the string to \a size characters and copies \a unicode
+ into the string.
+
+ If \a unicode is 0, nothing is copied, but the string is still
+ resized to \a size.
+
+ \sa unicode(), setUtf16()
+*/
+QString& QString::setUnicode(const QChar *unicode, int size)
+{
+ resize(size);
+ if (unicode && size)
+ memcpy(d->data, unicode, size * sizeof(QChar));
+ return *this;
+}
+
+/*!
+ \fn QString &QString::setUtf16(const ushort *unicode, int size)
+
+ Resizes the string to \a size characters and copies \a unicode
+ into the string.
+
+ If \a unicode is 0, nothing is copied, but the string is still
+ resized to \a size.
+
+ \sa utf16(), setUnicode()
+*/
+
+/*!
+ Returns a string that has whitespace removed from the start
+ and the end, and that has each sequence of internal whitespace
+ replaced with a single space.
+
+ Whitespace means any character for which QChar::isSpace() returns
+ true. This includes the ASCII characters '\\t', '\\n', '\\v',
+ '\\f', '\\r', and ' '.
+
+ Example:
+
+ \snippet doc/src/snippets/qstring/main.cpp 57
+
+ \sa trimmed()
+*/
+QString QString::simplified() const
+{
+ if (d->size == 0)
+ return *this;
+ QString result;
+ result.resize(d->size);
+ const QChar *from = (const QChar*) d->data;
+ const QChar *fromend = (const QChar*) from+d->size;
+ int outc=0;
+ QChar *to = (QChar*) result.d->data;
+ for (;;) {
+ while (from!=fromend && from->isSpace())
+ from++;
+ while (from!=fromend && !from->isSpace())
+ to[outc++] = *from++;
+ if (from!=fromend)
+ to[outc++] = QLatin1Char(' ');
+ else
+ break;
+ }
+ if (outc > 0 && to[outc-1] == QLatin1Char(' '))
+ outc--;
+ result.truncate(outc);
+ return result;
+}
+
+/*!
+ Returns a string that has whitespace removed from the start and
+ the end.
+
+ Whitespace means any character for which QChar::isSpace() returns
+ true. This includes the ASCII characters '\\t', '\\n', '\\v',
+ '\\f', '\\r', and ' '.
+
+ Example:
+
+ \snippet doc/src/snippets/qstring/main.cpp 82
+
+ Unlike simplified(), trimmed() leaves internal whitespace alone.
+
+ \sa simplified()
+*/
+QString QString::trimmed() const
+{
+ if (d->size == 0)
+ return *this;
+ const QChar *s = (const QChar*)d->data;
+ if (!s->isSpace() && !s[d->size-1].isSpace())
+ return *this;
+ int start = 0;
+ int end = d->size - 1;
+ while (start<=end && s[start].isSpace()) // skip white space from start
+ start++;
+ if (start <= end) { // only white space
+ while (end && s[end].isSpace()) // skip white space from end
+ end--;
+ }
+ int l = end - start + 1;
+ if (l <= 0) {
+ shared_empty.ref.ref();
+ return QString(&shared_empty, 0);
+ }
+ return QString(s + start, l);
+}
+
+/*! \fn const QChar QString::at(int position) const
+
+ Returns the character at the given index \a position in the
+ string.
+
+ The \a position must be a valid index position in the string
+ (i.e., 0 <= \a position < size()).
+
+ \sa operator[]()
+*/
+
+/*!
+ \fn QCharRef QString::operator[](int position)
+
+ Returns the character at the specified \a position in the string as a
+ modifiable reference.
+
+ Example:
+
+ \snippet doc/src/snippets/qstring/main.cpp 85
+
+ The return value is of type QCharRef, a helper class for QString.
+ When you get an object of type QCharRef, you can use it as if it
+ were a QChar &. If you assign to it, the assignment will apply to
+ the character in the QString from which you got the reference.
+
+ \sa at()
+*/
+
+/*!
+ \fn const QChar QString::operator[](int position) const
+
+ \overload operator[]()
+*/
+
+/*! \fn QCharRef QString::operator[](uint position)
+
+\overload operator[]()
+
+Returns the character at the specified \a position in the string as a
+modifiable reference. Equivalent to \c at(position).
+*/
+
+/*! \fn const QChar QString::operator[](uint position) const
+
+\overload operator[]()
+*/
+
+/*!
+ \fn void QString::truncate(int position)
+
+ Truncates the string at the given \a position index.
+
+ If the specified \a position index is beyond the end of the
+ string, nothing happens.
+
+ Example:
+
+ \snippet doc/src/snippets/qstring/main.cpp 83
+
+ If \a position is negative, it is equivalent to passing zero.
+
+ \sa chop(), resize(), left()
+*/
+
+void QString::truncate(int pos)
+{
+ if (pos < d->size)
+ resize(pos);
+}
+
+
+/*!
+ Removes \a n characters from the end of the string.
+
+ If \a n is greater than size(), the result is an empty string.
+
+ Example:
+ \snippet doc/src/snippets/qstring/main.cpp 15
+
+ If you want to remove characters from the \e beginning of the
+ string, use remove() instead.
+
+ \sa truncate(), resize(), remove()
+*/
+void QString::chop(int n)
+{
+ if (n > 0)
+ resize(d->size - n);
+}
+
+/*!
+ Sets every character in the string to character \a ch. If \a size
+ is different from -1 (default), the string is resized to \a
+ size beforehand.
+
+ Example:
+
+ \snippet doc/src/snippets/qstring/main.cpp 21
+
+ \sa resize()
+*/
+
+QString& QString::fill(QChar ch, int size)
+{
+ resize(size < 0 ? d->size : size);
+ if (d->size) {
+ QChar *i = (QChar*)d->data + d->size;
+ QChar *b = (QChar*)d->data;
+ while (i != b)
+ *--i = ch;
+ }
+ return *this;
+}
+
+/*!
+ \fn int QString::length() const
+
+ Returns the number of characters in this string. Equivalent to
+ size().
+
+ \sa setLength()
+*/
+
+/*!
+ \fn int QString::size() const
+
+ Returns the number of characters in this string.
+
+ The last character in the string is at position size() - 1. In
+ addition, QString ensures that the character 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.
+
+ Example:
+
+ \snippet doc/src/snippets/qstring/main.cpp 58
+
+ \sa isEmpty(), resize()
+*/
+
+/*! \fn bool QString::isNull() const
+
+ Returns true if this string is null; otherwise returns false.
+
+ Example:
+
+ \snippet doc/src/snippets/qstring/main.cpp 28
+
+ Qt makes a distinction between null strings and empty strings for
+ historical reasons. For most applications, what matters is
+ whether or not a string contains any data, and this can be
+ determined using the isEmpty() function.
+
+ \sa isEmpty()
+*/
+
+/*! \fn bool QString::isEmpty() const
+
+ Returns true if the string has no characters; otherwise returns
+ false.
+
+ Example:
+
+ \snippet doc/src/snippets/qstring/main.cpp 27
+
+ \sa size()
+*/
+
+/*! \fn QString &QString::operator+=(const QString &other)
+
+ Appends the string \a other onto the end of this string and
+ returns a reference to this string.
+
+ Example:
+
+ \snippet doc/src/snippets/qstring/main.cpp 84
+
+ This operation is typically very fast (\l{constant time}),
+ because QString preallocates extra space at the end of the string
+ data so it can grow without reallocating the entire string each
+ time.
+
+ \sa append(), prepend()
+*/
+
+/*! \fn QString &QString::operator+=(const QLatin1String &str)
+
+ \overload operator+=()
+
+ Appends the Latin-1 string \a str to this string.
+*/
+
+/*! \fn QString &QString::operator+=(const QByteArray &ba)
+
+ \overload operator+=()
+
+ Appends the byte array \a ba to this string. The byte array is
+ converted to Unicode using the fromAscii() function.
+
+ You can disable this function by defining \c
+ QT_NO_CAST_FROM_ASCII when you compile your applications. This
+ can be useful if you want to ensure that all user-visible strings
+ go through QObject::tr(), for example.
+*/
+
+/*! \fn QString &QString::operator+=(const char *str)
+
+ \overload operator+=()
+
+ Appends the string \a str to this string. The const char pointer
+ is converted to Unicode using the fromAscii() function.
+
+ You can disable this function by defining \c QT_NO_CAST_FROM_ASCII
+ when you compile your applications. This can be useful if you want
+ to ensure that all user-visible strings go through QObject::tr(),
+ for example.
+*/
+
+/*! \fn QString &QString::operator+=(const QStringRef &str)
+
+ \overload operator+=()
+
+ Appends the string section referenced by \a str to this string.
+*/
+
+/*! \fn QString &QString::operator+=(char ch)
+
+ \overload operator+=()
+
+ Appends the character \a ch to this string. The character is
+ converted to Unicode using the fromAscii() function.
+
+ You can disable this function by defining \c QT_NO_CAST_FROM_ASCII
+ when you compile your applications. This can be useful if you want
+ to ensure that all user-visible strings go through QObject::tr(),
+ for example.
+*/
+
+/*! \fn QString &QString::operator+=(QChar ch)
+
+ \overload operator+=()
+
+ Appends the character \a ch to the string.
+*/
+
+/*! \fn QString &QString::operator+=(QChar::SpecialCharacter c)
+
+ \overload operator+=()
+
+ \internal
+*/
+
+/*!
+ \fn bool operator==(const char *s1, const QString &s2)
+
+ \overload operator==()
+ \relates QString
+
+ Returns true if \a s1 is equal to \a s2; otherwise returns false.
+ Note that no string is equal to \a s1 being 0.
+
+ Equivalent to \c {s1 != 0 && compare(s1, s2) == 0}.
+
+ \sa QString::compare()
+*/
+
+/*!
+ \fn bool operator!=(const char *s1, const QString &s2)
+ \relates QString
+
+ Returns true if \a s1 is not equal to \a s2; otherwise returns
+ false.
+
+ For \a s1 != 0, this is equivalent to \c {compare(} \a s1, \a s2
+ \c {) != 0}. Note that no string is equal to \a s1 being 0.
+
+ \sa QString::compare()
+*/
+
+/*!
+ \fn bool operator<(const char *s1, const QString &s2)
+ \relates QString
+
+ Returns true if \a s1 is lexically less than \a s2; otherwise
+ returns false. For \a s1 != 0, this is equivalent to \c
+ {compare(s1, s2) < 0}.
+
+ The comparison is based exclusively on the numeric Unicode values
+ of the characters and is very fast, but is not what a human would
+ expect. Consider sorting user-interface strings using the
+ QString::localeAwareCompare() function.
+
+ \sa QString::compare()
+*/
+
+/*!
+ \fn bool operator<=(const char *s1, const QString &s2)
+ \relates QString
+
+ Returns true if \a s1 is lexically less than or equal to \a s2;
+ otherwise returns false. For \a s1 != 0, this is equivalent to \c
+ {compare(s1, s2) <= 0}.
+
+ The comparison is based exclusively on the numeric Unicode values
+ of the characters and is very fast, but is not what a human would
+ expect. Consider sorting user-interface strings with
+ QString::localeAwareCompare().
+
+ \sa QString::compare()
+*/
+
+/*!
+ \fn bool operator>(const char *s1, const QString &s2)
+ \relates QString
+
+ Returns true if \a s1 is lexically greater than \a s2; otherwise
+ returns false. Equivalent to \c {compare(s1, s2) > 0}.
+
+ The comparison is based exclusively on the numeric Unicode values
+ of the characters and is very fast, but is not what a human would
+ expect. Consider sorting user-interface strings using the
+ QString::localeAwareCompare() function.
+
+ \sa QString::compare()
+*/
+
+/*!
+ \fn bool operator>=(const char *s1, const QString &s2)
+ \relates QString
+
+ Returns true if \a s1 is lexically greater than or equal to \a s2;
+ otherwise returns false. For \a s1 != 0, this is equivalent to \c
+ {compare(s1, s2) >= 0}.
+
+ The comparison is based exclusively on the numeric Unicode values
+ of the characters and is very fast, but is not what a human would
+ expect. Consider sorting user-interface strings using the
+ QString::localeAwareCompare() function.
+*/
+
+/*!
+ \fn const QString operator+(const QString &s1, const QString &s2)
+ \relates QString
+
+ Returns a string which is the result of concatenating \a s1 and \a
+ s2.
+*/
+
+/*!
+ \fn const QString operator+(const QString &s1, const char *s2)
+ \relates QString
+
+ Returns a string which is the result of concatenating \a s1 and \a
+ s2 (\a s2 is converted to Unicode using the QString::fromAscii()
+ function).
+
+ \sa QString::fromAscii()
+*/
+
+/*!
+ \fn const QString operator+(const char *s1, const QString &s2)
+ \relates QString
+
+ Returns a string which is the result of concatenating \a s1 and \a
+ s2 (\a s1 is converted to Unicode using the QString::fromAscii()
+ function).
+
+ \sa QString::fromAscii()
+*/
+
+/*!
+ \fn const QString operator+(const QString &s, char ch)
+ \relates QString
+
+ Returns a string which is the result of concatenating the string
+ \a s and the character \a ch.
+*/
+
+/*!
+ \fn const QString operator+(char ch, const QString &s)
+ \relates QString
+
+ Returns a string which is the result of concatenating the
+ character \a ch and the string \a s.
+*/
+
+/*!
+ \fn int QString::compare(const QString &s1, const QString &s2, Qt::CaseSensitivity cs)
+ \since 4.2
+
+ Compares \a s1 with \a s2 and returns an integer less than, equal
+ to, or greater than zero if \a s1 is less than, equal to, or
+ greater than \a s2.
+
+ If \a cs is Qt::CaseSensitive, the comparison is case sensitive;
+ otherwise the comparison is case insensitive.
+
+ Case sensitive comparison is based exclusively on the numeric
+ Unicode values of the characters and is very fast, but is not what
+ a human would expect. Consider sorting user-visible strings with
+ localeAwareCompare().
+
+ \snippet doc/src/snippets/qstring/main.cpp 16
+
+ \sa operator==(), operator<(), operator>()
+*/
+
+/*!
+ \fn int QString::compare(const QString & s1, const QString & s2)
+
+ \overload compare()
+
+ Performs a case sensitive compare of \a s1 and \a s2.
+*/
+
+/*!
+ \fn int QString::compare(const QString &s1, const QLatin1String &s2, Qt::CaseSensitivity cs)
+ \since 4.2
+ \overload compare()
+
+ Performs a comparison of \a s1 and \a s2, using the case
+ sensitivity setting \a cs.
+*/
+
+/*!
+ \fn int QString::compare(const QLatin1String &s1, const QString &s2, Qt::CaseSensitivity cs = Qt::CaseSensitive)
+
+ \since 4.2
+ \overload compare()
+
+ Performs a comparison of \a s1 and \a s2, using the case
+ sensitivity setting \a cs.
+*/
+
+/*!
+ \overload compare()
+
+ Lexically compares this string with the \a other string and
+ returns an integer less than, equal to, or greater than zero if
+ this string is less than, equal to, or greater than the other
+ string.
+
+ Equivalent to \c {compare(*this, other)}.
+*/
+int QString::compare(const QString &other) const
+{
+ return ucstrcmp(constData(), length(), other.constData(), other.length());
+}
+
+/*!
+ \overload compare()
+ \since 4.2
+
+ Same as compare(*this, \a other, \a cs).
+*/
+int QString::compare(const QString &other, Qt::CaseSensitivity cs) const
+{
+ if (cs == Qt::CaseSensitive)
+ return ucstrcmp(constData(), length(), other.constData(), other.length());
+ return ucstricmp(d->data, d->data + d->size, other.d->data, other.d->data + other.d->size);
+}
+
+/*!
+ \internal
+ \since 4.5
+*/
+int QString::compare_helper(const QChar *data1, int length1, const QChar *data2, int length2,
+ Qt::CaseSensitivity cs)
+{
+ if (cs == Qt::CaseSensitive)
+ return ucstrcmp(data1, length1, data2, length2);
+ register const ushort *s1 = reinterpret_cast<const ushort *>(data1);
+ register const ushort *s2 = reinterpret_cast<const ushort *>(data2);
+ return ucstricmp(s1, s1 + length1, s2, s2 + length2);
+}
+
+/*!
+ \overload compare()
+ \since 4.2
+
+ Same as compare(*this, \a other, \a cs).
+*/
+int QString::compare(const QLatin1String &other, Qt::CaseSensitivity cs) const
+{
+ return compare_helper(unicode(), length(), other, cs);
+}
+
+/*!
+ \fn int QString::compare(const QStringRef &ref, Qt::CaseSensitivity cs = Qt::CaseSensitive) const
+ \overload compare()
+
+ Compares the string reference, \a ref, with the string and returns
+ an integer less than, equal to, or greater than zero if the string
+ is less than, equal to, or greater than \a ref.
+*/
+
+/*!
+ \fn int QString::compare(const QString &s1, const QStringRef &s2, Qt::CaseSensitivity cs = Qt::CaseSensitive)
+ \overload compare()
+*/
+
+/*!
+ \internal
+ \since 4.5
+*/
+int QString::compare_helper(const QChar *data1, int length1, QLatin1String s2,
+ Qt::CaseSensitivity cs)
+{
+ const ushort *uc = reinterpret_cast<const ushort *>(data1);
+ const ushort *e = uc + length1;
+ const uchar *c = (uchar *)s2.latin1();
+
+ if (!c)
+ return length1;
+
+ if (cs == Qt::CaseSensitive) {
+ while (uc != e && *c && *uc == *c)
+ uc++, c++;
+
+ return *uc - *c;
+ } else {
+ return ucstricmp(uc, e, c);
+ }
+}
+
+/*!
+ \fn int QString::localeAwareCompare(const QString & s1, const QString & s2)
+
+ Compares \a s1 with \a s2 and returns an integer less than, equal
+ to, or greater than zero if \a s1 is less than, equal to, or
+ greater than \a s2.
+
+ The comparison is performed in a locale- and also
+ platform-dependent manner. Use this function to present sorted
+ lists of strings to the user.
+
+ On Mac OS X since Qt 4.3, this function compares according the
+ "Order for sorted lists" setting in the International prefereces panel.
+
+ \sa compare(), QTextCodec::locale()
+*/
+
+/*!
+ \fn int QString::localeAwareCompare(const QStringRef &other) const
+ \since 4.5
+ \overload localeAwareCompare()
+
+ Compares this string with the \a other string and returns an
+ integer less than, equal to, or greater than zero if this string
+ is less than, equal to, or greater than the \a other string.
+
+ The comparison is performed in a locale- and also
+ platform-dependent manner. Use this function to present sorted
+ lists of strings to the user.
+
+ Same as \c {localeAwareCompare(*this, other)}.
+*/
+
+/*!
+ \fn int QString::localeAwareCompare(const QString &s1, const QStringRef &s2)
+ \since 4.5
+ \overload localeAwareCompare()
+
+ Compares \a s1 with \a s2 and returns an integer less than, equal
+ to, or greater than zero if \a s1 is less than, equal to, or
+ greater than \a s2.
+
+ The comparison is performed in a locale- and also
+ platform-dependent manner. Use this function to present sorted
+ lists of strings to the user.
+*/
+
+
+#if !defined(CSTR_LESS_THAN)
+#define CSTR_LESS_THAN 1
+#define CSTR_EQUAL 2
+#define CSTR_GREATER_THAN 3
+#endif
+
+/*!
+ \overload localeAwareCompare()
+
+ Compares this string with the \a other string and returns an
+ integer less than, equal to, or greater than zero if this string
+ is less than, equal to, or greater than the \a other string.
+
+ The comparison is performed in a locale- and also
+ platform-dependent manner. Use this function to present sorted
+ lists of strings to the user.
+
+ Same as \c {localeAwareCompare(*this, other)}.
+*/
+int QString::localeAwareCompare(const QString &other) const
+{
+ return localeAwareCompare_helper(constData(), length(), other.constData(), other.length());
+}
+
+/*!
+ \internal
+ \since 4.5
+*/
+int QString::localeAwareCompare_helper(const QChar *data1, int length1,
+ const QChar *data2, int length2)
+{
+ // do the right thing for null and empty
+ if (length1 == 0 || length2 == 0)
+ return ucstrcmp(data1, length1, data2, length2);
+
+#if defined(Q_OS_WIN32) || defined(Q_OS_WINCE)
+ int res;
+ QT_WA({
+ const TCHAR* s1 = (TCHAR*)data1;
+ const TCHAR* s2 = (TCHAR*)data2;
+ res = CompareStringW(GetUserDefaultLCID(), 0, s1, length1, s2, length2);
+ } , {
+ QByteArray s1 = toLocal8Bit_helper(data1, length1);
+ QByteArray s2 = toLocal8Bit_helper(data2, length2);
+ res = CompareStringA(GetUserDefaultLCID(), 0, s1.data(), s1.length(), s2.data(), s2.length());
+ });
+
+ switch (res) {
+ case CSTR_LESS_THAN:
+ return -1;
+ case CSTR_GREATER_THAN:
+ return 1;
+ default:
+ return 0;
+ }
+#elif defined (Q_OS_MAC)
+ // Use CFStringCompare for comparing strings on Mac. This makes Qt order
+ // strings the same way as native applications do, and also respects
+ // the "Order for sorted lists" setting in the International preferences
+ // panel.
+ const CFStringRef thisString =
+ CFStringCreateWithCharactersNoCopy(kCFAllocatorDefault,
+ reinterpret_cast<const UniChar *>(data1), length1, kCFAllocatorNull);
+ const CFStringRef otherString =
+ CFStringCreateWithCharactersNoCopy(kCFAllocatorDefault,
+ reinterpret_cast<const UniChar *>(data2), length2, kCFAllocatorNull);
+
+ const int result = CFStringCompare(thisString, otherString, kCFCompareLocalized);
+ CFRelease(thisString);
+ CFRelease(otherString);
+ return result;
+#elif defined(Q_OS_UNIX)
+ // declared in <string.h>
+ int delta = strcoll(toLocal8Bit_helper(data1, length1), toLocal8Bit_helper(data2, length2));
+ if (delta == 0)
+ delta = ucstrcmp(data1, length1, data2, length2);
+ return delta;
+#else
+ return ucstrcmp(data1, length1, data2, length2);
+#endif
+}
+
+
+/*!
+ \fn const QChar *QString::unicode() const
+
+ Returns a '\\0'-terminated Unicode representation of the string.
+ The result remains valid until the string is modified.
+
+ \sa utf16()
+*/
+
+/*!
+ \fn const ushort *QString::utf16() const
+
+ Returns the QString as a '\\0\'-terminated array of unsigned
+ shorts. The result remains valid until the string is modified.
+
+ \sa unicode()
+*/
+
+const ushort *QString::utf16() const
+{
+ if (d->data != d->array) {
+ QString *that = const_cast<QString*>(this);
+ that->realloc(); // ensure '\\0'-termination for ::fromRawData strings
+ return that->d->data;
+ }
+ return d->array;
+}
+
+/*!
+ Returns a string of size \a width that contains this string
+ padded by the \a fill character.
+
+ If \a truncate is false and the size() of the string is more than
+ \a width, then the returned string is a copy of the string.
+
+ \snippet doc/src/snippets/qstring/main.cpp 32
+
+ If \a truncate is true and the size() of the string is more than
+ \a width, then any characters in a copy of the string after
+ position \a width are removed, and the copy is returned.
+
+ \snippet doc/src/snippets/qstring/main.cpp 33
+
+ \sa rightJustified()
+*/
+
+QString QString::leftJustified(int width, QChar fill, bool truncate) const
+{
+ QString result;
+ int len = length();
+ int padlen = width - len;
+ if (padlen > 0) {
+ result.resize(len+padlen);
+ if (len)
+ memcpy(result.d->data, d->data, sizeof(QChar)*len);
+ QChar *uc = (QChar*)result.d->data + len;
+ while (padlen--)
+ * uc++ = fill;
+ } else {
+ if (truncate)
+ result = left(width);
+ else
+ result = *this;
+ }
+ return result;
+}
+
+/*!
+ Returns a string of size() \a width that contains the \a fill
+ character followed by the string. For example:
+
+ \snippet doc/src/snippets/qstring/main.cpp 49
+
+ If \a truncate is false and the size() of the string is more than
+ \a width, then the returned string is a copy of the string.
+
+ If \a truncate is true and the size() of the string is more than
+ \a width, then the resulting string is truncated at position \a
+ width.
+
+ \snippet doc/src/snippets/qstring/main.cpp 50
+
+ \sa leftJustified()
+*/
+
+QString QString::rightJustified(int width, QChar fill, bool truncate) const
+{
+ QString result;
+ int len = length();
+ int padlen = width - len;
+ if (padlen > 0) {
+ result.resize(len+padlen);
+ QChar *uc = (QChar*)result.d->data;
+ while (padlen--)
+ * uc++ = fill;
+ if (len)
+ memcpy(uc, d->data, sizeof(QChar)*len);
+ } else {
+ if (truncate)
+ result = left(width);
+ else
+ result = *this;
+ }
+ return result;
+}
+
+/*!
+ Returns a lowercase copy of the string.
+
+ \snippet doc/src/snippets/qstring/main.cpp 75
+
+ \sa toUpper()
+*/
+
+QString QString::toLower() const
+{
+ const ushort *p = d->data;
+ if (!p)
+ return *this;
+ if (!d->size)
+ return *this;
+
+ const ushort *e = d->data + d->size;
+
+ // this avoids one out of bounds check in the loop
+ if (QChar(*p).isLowSurrogate())
+ ++p;
+
+ while (p != e) {
+ uint c = *p;
+ if (QChar(c).isLowSurrogate() && QChar(*(p - 1)).isHighSurrogate())
+ c = QChar::surrogateToUcs4(*(p - 1), c);
+ const QUnicodeTables::Properties *prop = qGetProp(c);
+ if (prop->lowerCaseDiff || prop->lowerCaseSpecial) {
+ QString s;
+ s.resize(d->size);
+ memcpy(s.d->data, d->data, (p - d->data)*sizeof(ushort));
+ ushort *pp = s.d->data + (p - d->data);
+ while (p < e) {
+ uint c = *p;
+ if (QChar(c).isLowSurrogate() && QChar(*(p - 1)).isHighSurrogate())
+ c = QChar::surrogateToUcs4(*(p - 1), c);
+ prop = qGetProp(c);
+ if (prop->lowerCaseSpecial) {
+ int pos = pp - s.d->data;
+ s.resize(s.d->size + SPECIAL_CASE_MAX_LEN);
+ pp = s.d->data + pos;
+ const ushort *specialCase = specialCaseMap + prop->lowerCaseDiff;
+ while (*specialCase)
+ *pp++ = *specialCase++;
+ } else {
+ *pp++ = *p + prop->lowerCaseDiff;
+ }
+ ++p;
+ }
+ s.truncate(pp - s.d->data);
+ return s;
+ }
+ ++p;
+ }
+ return *this;
+}
+
+/*!
+ Returns the case folded equivalent of the string. For most Unicode
+ characters this is the same as toLower().
+*/
+QString QString::toCaseFolded() const
+{
+ if (!d->size)
+ return *this;
+
+ const ushort *p = d->data;
+ if (!p)
+ return *this;
+
+ const ushort *e = d->data + d->size;
+
+ uint last = 0;
+ while (p < e) {
+ ushort folded = foldCase(*p, last);
+ if (folded != *p) {
+ QString s(*this);
+ s.detach();
+ ushort *pp = s.d->data + (p - d->data);
+ const ushort *ppe = s.d->data + s.d->size;
+ last = pp > s.d->data ? *(pp - 1) : 0;
+ while (pp < ppe) {
+ *pp = foldCase(*pp, last);
+ ++pp;
+ }
+ return s;
+ }
+ p++;
+ }
+ return *this;
+}
+
+/*!
+ Returns an uppercase copy of the string.
+
+ \snippet doc/src/snippets/qstring/main.cpp 81
+
+ \sa toLower()
+*/
+
+QString QString::toUpper() const
+{
+ const ushort *p = d->data;
+ if (!p)
+ return *this;
+ if (!d->size)
+ return *this;
+
+ const ushort *e = d->data + d->size;
+
+ // this avoids one out of bounds check in the loop
+ if (QChar(*p).isLowSurrogate())
+ ++p;
+
+ while (p != e) {
+ uint c = *p;
+ if (QChar(c).isLowSurrogate() && QChar(*(p - 1)).isHighSurrogate())
+ c = QChar::surrogateToUcs4(*(p - 1), c);
+ const QUnicodeTables::Properties *prop = qGetProp(c);
+ if (prop->upperCaseDiff || prop->upperCaseSpecial) {
+ QString s;
+ s.resize(d->size);
+ memcpy(s.d->data, d->data, (p - d->data)*sizeof(ushort));
+ ushort *pp = s.d->data + (p - d->data);
+ while (p < e) {
+ uint c = *p;
+ if (QChar(c).isLowSurrogate() && QChar(*(p - 1)).isHighSurrogate())
+ c = QChar::surrogateToUcs4(*(p - 1), c);
+ prop = qGetProp(c);
+ if (prop->upperCaseSpecial) {
+ int pos = pp - s.d->data;
+ s.resize(s.d->size + SPECIAL_CASE_MAX_LEN);
+ pp = s.d->data + pos;
+ const ushort *specialCase = specialCaseMap + prop->upperCaseDiff;
+ while (*specialCase)
+ *pp++ = *specialCase++;
+ } else {
+ *pp++ = *p + prop->upperCaseDiff;
+ }
+ ++p;
+ }
+ s.truncate(pp - s.d->data);
+ return s;
+ }
+ ++p;
+ }
+ return *this;
+}
+
+// ### Qt 5: Consider whether this function shouldn't be removed See task 202871.
+/*!
+ Safely builds a formatted string from the format string \a cformat
+ and an arbitrary list of arguments.
+
+ The %lc escape sequence expects a unicode character of type ushort
+ (as returned by QChar::unicode()). The %ls escape sequence expects
+ a pointer to a zero-terminated array of unicode characters of type
+ ushort (as returned by QString::utf16()).
+
+ \note This function expects a UTF-8 string for %s.
+
+ The format string supports most of the conversion specifiers
+ provided by printf() in the standard C++ library. It doesn't
+ honor the length modifiers (e.g. \c h for \c short, \c ll for
+ \c{long long}). If you need those, use the standard snprintf()
+ function instead:
+
+ \snippet doc/src/snippets/qstring/main.cpp 63
+
+ \warning We do not recommend using QString::sprintf() in new Qt
+ code. Instead, consider using QTextStream or arg(), both of
+ which support Unicode strings seamlessly and are type-safe.
+ Here's an example that uses QTextStream:
+
+ \snippet doc/src/snippets/qstring/main.cpp 64
+
+ For \l {QObject::tr()}{translations}, especially if the strings
+ contains more than one escape sequence, you should consider using
+ the arg() function instead. This allows the order of the
+ replacements to be controlled by the translator.
+
+ \sa arg()
+*/
+
+QString &QString::sprintf(const char *cformat, ...)
+{
+ va_list ap;
+ va_start(ap, cformat);
+ QString &s = vsprintf(cformat, ap);
+ va_end(ap);
+ return s;
+}
+
+/*!
+ Equivalent method to sprintf(), but takes a va_list \a ap
+ instead a list of variable arguments. See the sprintf()
+ documentation for an explanation of \a cformat.
+
+ This method does not call the va_end macro, the caller
+ is responsible to call va_end on \a ap.
+
+ \sa sprintf()
+*/
+
+QString &QString::vsprintf(const char* cformat, va_list ap)
+{
+ QLocale locale(QLocale::C);
+
+ if (!cformat || !*cformat) {
+ // Qt 1.x compat
+ *this = fromLatin1("");
+ return *this;
+ }
+
+ // Parse cformat
+
+ QString result;
+ const char *c = cformat;
+ for (;;) {
+ // Copy non-escape chars to result
+ while (*c != '\0' && *c != '%')
+ result.append(QLatin1Char(*c++));
+
+ if (*c == '\0')
+ break;
+
+ // Found '%'
+ const char *escape_start = c;
+ ++c;
+
+ if (*c == '\0') {
+ result.append(QLatin1Char('%')); // a % at the end of the string - treat as non-escape text
+ break;
+ }
+ if (*c == '%') {
+ result.append(QLatin1Char('%')); // %%
+ ++c;
+ continue;
+ }
+
+ // Parse flag characters
+ uint flags = 0;
+ bool no_more_flags = false;
+ do {
+ switch (*c) {
+ case '#': flags |= QLocalePrivate::Alternate; break;
+ case '0': flags |= QLocalePrivate::ZeroPadded; break;
+ case '-': flags |= QLocalePrivate::LeftAdjusted; break;
+ case ' ': flags |= QLocalePrivate::BlankBeforePositive; break;
+ case '+': flags |= QLocalePrivate::AlwaysShowSign; break;
+ case '\'': flags |= QLocalePrivate::ThousandsGroup; break;
+ default: no_more_flags = true; break;
+ }
+
+ if (!no_more_flags)
+ ++c;
+ } while (!no_more_flags);
+
+ if (*c == '\0') {
+ result.append(QLatin1String(escape_start)); // incomplete escape, treat as non-escape text
+ break;
+ }
+
+ // Parse field width
+ int width = -1; // -1 means unspecified
+ if (qIsDigit(*c)) {
+ QString width_str;
+ while (*c != '\0' && qIsDigit(*c))
+ width_str.append(QLatin1Char(*c++));
+
+ // can't be negative - started with a digit
+ // contains at least one digit
+ width = width_str.toInt();
+ }
+ else if (*c == '*') {
+ width = va_arg(ap, int);
+ if (width < 0)
+ width = -1; // treat all negative numbers as unspecified
+ ++c;
+ }
+
+ if (*c == '\0') {
+ result.append(QLatin1String(escape_start)); // incomplete escape, treat as non-escape text
+ break;
+ }
+
+ // Parse precision
+ int precision = -1; // -1 means unspecified
+ if (*c == '.') {
+ ++c;
+ if (qIsDigit(*c)) {
+ QString precision_str;
+ while (*c != '\0' && qIsDigit(*c))
+ precision_str.append(QLatin1Char(*c++));
+
+ // can't be negative - started with a digit
+ // contains at least one digit
+ precision = precision_str.toInt();
+ }
+ else if (*c == '*') {
+ precision = va_arg(ap, int);
+ if (precision < 0)
+ precision = -1; // treat all negative numbers as unspecified
+ ++c;
+ }
+ }
+
+ if (*c == '\0') {
+ result.append(QLatin1String(escape_start)); // incomplete escape, treat as non-escape text
+ break;
+ }
+
+ // Parse the length modifier
+ enum LengthMod { lm_none, lm_hh, lm_h, lm_l, lm_ll, lm_L, lm_j, lm_z, lm_t };
+ LengthMod length_mod = lm_none;
+ switch (*c) {
+ case 'h':
+ ++c;
+ if (*c == 'h') {
+ length_mod = lm_hh;
+ ++c;
+ }
+ else
+ length_mod = lm_h;
+ break;
+
+ case 'l':
+ ++c;
+ if (*c == 'l') {
+ length_mod = lm_ll;
+ ++c;
+ }
+ else
+ length_mod = lm_l;
+ break;
+
+ case 'L':
+ ++c;
+ length_mod = lm_L;
+ break;
+
+ case 'j':
+ ++c;
+ length_mod = lm_j;
+ break;
+
+ case 'z':
+ case 'Z':
+ ++c;
+ length_mod = lm_z;
+ break;
+
+ case 't':
+ ++c;
+ length_mod = lm_t;
+ break;
+
+ default: break;
+ }
+
+ if (*c == '\0') {
+ result.append(QLatin1String(escape_start)); // incomplete escape, treat as non-escape text
+ break;
+ }
+
+ // Parse the conversion specifier and do the conversion
+ QString subst;
+ switch (*c) {
+ case 'd':
+ case 'i': {
+ qint64 i;
+ switch (length_mod) {
+ case lm_none: i = va_arg(ap, int); break;
+ case lm_hh: i = va_arg(ap, int); break;
+ case lm_h: i = va_arg(ap, int); break;
+ case lm_l: i = va_arg(ap, long int); break;
+ case lm_ll: i = va_arg(ap, qint64); break;
+ case lm_j: i = va_arg(ap, long int); break;
+ case lm_z: i = va_arg(ap, size_t); break;
+ case lm_t: i = va_arg(ap, int); break;
+ default: i = 0; break;
+ }
+ subst = locale.d()->longLongToString(i, precision, 10, width, flags);
+ ++c;
+ break;
+ }
+ case 'o':
+ case 'u':
+ case 'x':
+ case 'X': {
+ quint64 u;
+ switch (length_mod) {
+ case lm_none: u = va_arg(ap, uint); break;
+ case lm_hh: u = va_arg(ap, uint); break;
+ case lm_h: u = va_arg(ap, uint); break;
+ case lm_l: u = va_arg(ap, ulong); break;
+ case lm_ll: u = va_arg(ap, quint64); break;
+ case lm_z: u = va_arg(ap, size_t); break;
+ default: u = 0; break;
+ }
+
+ if (qIsUpper(*c))
+ flags |= QLocalePrivate::CapitalEorX;
+
+ int base = 10;
+ switch (qToLower(*c)) {
+ case 'o':
+ base = 8; break;
+ case 'u':
+ base = 10; break;
+ case 'x':
+ base = 16; break;
+ default: break;
+ }
+ subst = locale.d()->unsLongLongToString(u, precision, base, width, flags);
+ ++c;
+ break;
+ }
+ case 'E':
+ case 'e':
+ case 'F':
+ case 'f':
+ case 'G':
+ case 'g':
+ case 'A':
+ case 'a': {
+ double d;
+ if (length_mod == lm_L)
+ d = va_arg(ap, long double); // not supported - converted to a double
+ else
+ d = va_arg(ap, double);
+
+ if (qIsUpper(*c))
+ flags |= QLocalePrivate::CapitalEorX;
+
+ QLocalePrivate::DoubleForm form = QLocalePrivate::DFDecimal;
+ switch (qToLower(*c)) {
+ case 'e': form = QLocalePrivate::DFExponent; break;
+ case 'a': // not supported - decimal form used instead
+ case 'f': form = QLocalePrivate::DFDecimal; break;
+ case 'g': form = QLocalePrivate::DFSignificantDigits; break;
+ default: break;
+ }
+ subst = locale.d()->doubleToString(d, precision, form, width, flags);
+ ++c;
+ break;
+ }
+ case 'c': {
+ if (length_mod == lm_l)
+ subst = QChar((ushort) va_arg(ap, int));
+ else
+ subst = QLatin1Char((uchar) va_arg(ap, int));
+ ++c;
+ break;
+ }
+ case 's': {
+ if (length_mod == lm_l) {
+ const ushort *buff = va_arg(ap, const ushort*);
+ const ushort *ch = buff;
+ while (*ch != 0)
+ ++ch;
+ subst.setUtf16(buff, ch - buff);
+ } else
+ subst = QString::fromUtf8(va_arg(ap, const char*));
+ if (precision != -1)
+ subst.truncate(precision);
+ ++c;
+ break;
+ }
+ case 'p': {
+ void *arg = va_arg(ap, void*);
+#ifdef Q_OS_WIN64
+ quint64 i = reinterpret_cast<quint64>(arg);
+#else
+ quint64 i = reinterpret_cast<unsigned long>(arg);
+#endif
+ flags |= QLocalePrivate::Alternate;
+ subst = locale.d()->unsLongLongToString(i, precision, 16, width, flags);
+ ++c;
+ break;
+ }
+ case 'n':
+ switch (length_mod) {
+ case lm_hh: {
+ signed char *n = va_arg(ap, signed char*);
+ *n = result.length();
+ break;
+ }
+ case lm_h: {
+ short int *n = va_arg(ap, short int*);
+ *n = result.length();
+ break;
+ }
+ case lm_l: {
+ long int *n = va_arg(ap, long int*);
+ *n = result.length();
+ break;
+ }
+ case lm_ll: {
+ qint64 *n = va_arg(ap, qint64*);
+ volatile uint tmp = result.length(); // egcs-2.91.66 gets internal
+ *n = tmp; // compiler error without volatile
+ break;
+ }
+ default: {
+ int *n = va_arg(ap, int*);
+ *n = result.length();
+ break;
+ }
+ }
+ ++c;
+ break;
+
+ default: // bad escape, treat as non-escape text
+ for (const char *cc = escape_start; cc != c; ++cc)
+ result.append(QLatin1Char(*cc));
+ continue;
+ }
+
+ if (flags & QLocalePrivate::LeftAdjusted)
+ result.append(subst.leftJustified(width));
+ else
+ result.append(subst.rightJustified(width));
+ }
+
+ *this = result;
+
+ return *this;
+}
+
+/*!
+ Returns the string converted to a \c{long long} using base \a
+ base, which is 10 by default and must be between 2 and 36, or 0.
+ Returns 0 if the conversion fails.
+
+ If a conversion error occurs, *\a{ok} is set to false; otherwise
+ *\a{ok} is set to true.
+
+ If \a base is 0, the C language convention is used: If the string
+ begins with "0x", base 16 is used; if the string begins with "0",
+ base 8 is used; otherwise, base 10 is used.
+
+ Example:
+
+ \snippet doc/src/snippets/qstring/main.cpp 74
+
+ \sa number(), toULongLong(), toInt()
+*/
+
+qint64 QString::toLongLong(bool *ok, int base) const
+{
+#if defined(QT_CHECK_RANGE)
+ if (base != 0 && (base < 2 || base > 36)) {
+ qWarning("QString::toLongLong: Invalid base (%d)", base);
+ base = 10;
+ }
+#endif
+
+ bool my_ok;
+ QLocale def_locale;
+ qint64 result = def_locale.d()->stringToLongLong(*this, base, &my_ok, QLocalePrivate::FailOnGroupSeparators);
+ if (my_ok) {
+ if (ok != 0)
+ *ok = true;
+ return result;
+ }
+
+ QLocale c_locale(QLocale::C);
+ return c_locale.d()->stringToLongLong(*this, base, ok, QLocalePrivate::FailOnGroupSeparators);
+}
+
+/*!
+ Returns the string 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.
+ Returns 0 if the conversion fails.
+
+ If a conversion error occurs, *\a{ok} is set to false; otherwise
+ *\a{ok} is set to true.
+
+ If \a base is 0, the C language convention is used: If the string
+ begins with "0x", base 16 is used; if the string begins with "0",
+ base 8 is used; otherwise, base 10 is used.
+
+ Example:
+
+ \snippet doc/src/snippets/qstring/main.cpp 79
+
+ \sa number(), toLongLong()
+*/
+
+quint64 QString::toULongLong(bool *ok, int base) const
+{
+#if defined(QT_CHECK_RANGE)
+ if (base != 0 && (base < 2 || base > 36)) {
+ qWarning("QString::toULongLong: Invalid base (%d)", base);
+ base = 10;
+ }
+#endif
+
+ bool my_ok;
+ QLocale def_locale;
+ quint64 result = def_locale.d()->stringToUnsLongLong(*this, base, &my_ok, QLocalePrivate::FailOnGroupSeparators);
+ if (my_ok) {
+ if (ok != 0)
+ *ok = true;
+ return result;
+ }
+
+ QLocale c_locale(QLocale::C);
+ return c_locale.d()->stringToUnsLongLong(*this, base, ok, QLocalePrivate::FailOnGroupSeparators);
+}
+
+/*!
+ \fn long QString::toLong(bool *ok, int base) const
+
+ Returns the string converted to a \c long using base \a
+ base, which is 10 by default and must be between 2 and 36, or 0.
+ Returns 0 if the conversion fails.
+
+ If a conversion error occurs, *\a{ok} is set to false; otherwise
+ *\a{ok} is set to true.
+
+ If \a base is 0, the C language convention is used: If the string
+ begins with "0x", base 16 is used; if the string begins with "0",
+ base 8 is used; otherwise, base 10 is used.
+
+ Example:
+
+ \snippet doc/src/snippets/qstring/main.cpp 73
+
+ \sa number(), toULong(), toInt()
+*/
+
+long QString::toLong(bool *ok, int base) const
+{
+ qint64 v = toLongLong(ok, base);
+ if (v < LONG_MIN || v > LONG_MAX) {
+ if (ok)
+ *ok = false;
+ v = 0;
+ }
+ return (long)v;
+}
+
+/*!
+ \fn ulong QString::toULong(bool *ok, int base) const
+
+ Returns the string converted to an \c{unsigned long} using base \a
+ base, which is 10 by default and must be between 2 and 36, or 0.
+ Returns 0 if the conversion fails.
+
+ If a conversion error occurs, *\a{ok} is set to false; otherwise
+ *\a{ok} is set to true.
+
+ If \a base is 0, the C language convention is used: If the string
+ begins with "0x", base 16 is used; if the string begins with "0",
+ base 8 is used; otherwise, base 10 is used.
+
+ Example:
+
+ \snippet doc/src/snippets/qstring/main.cpp 78
+
+ \sa number()
+*/
+
+ulong QString::toULong(bool *ok, int base) const
+{
+ quint64 v = toULongLong(ok, base);
+ if (v > ULONG_MAX) {
+ if (ok)
+ *ok = false;
+ v = 0;
+ }
+ return (ulong)v;
+}
+
+
+/*!
+ Returns the string converted to an \c int using base \a
+ base, which is 10 by default and must be between 2 and 36, or 0.
+ Returns 0 if the conversion fails.
+
+ If a conversion error occurs, *\a{ok} is set to false; otherwise
+ *\a{ok} is set to true.
+
+ If \a base is 0, the C language convention is used: If the string
+ begins with "0x", base 16 is used; if the string begins with "0",
+ base 8 is used; otherwise, base 10 is used.
+
+ Example:
+
+ \snippet doc/src/snippets/qstring/main.cpp 72
+
+ \sa number(), toUInt(), toDouble()
+*/
+
+int QString::toInt(bool *ok, int base) const
+{
+ qint64 v = toLongLong(ok, base);
+ if (v < INT_MIN || v > INT_MAX) {
+ if (ok)
+ *ok = false;
+ v = 0;
+ }
+ return v;
+}
+
+/*!
+ Returns the string converted to an \c{unsigned int} using base \a
+ base, which is 10 by default and must be between 2 and 36, or 0.
+ Returns 0 if the conversion fails.
+
+ If a conversion error occurs, *\a{ok} is set to false; otherwise
+ *\a{ok} is set to true.
+
+ If \a base is 0, the C language convention is used: If the string
+ begins with "0x", base 16 is used; if the string begins with "0",
+ base 8 is used; otherwise, base 10 is used.
+
+ Example:
+
+ \snippet doc/src/snippets/qstring/main.cpp 77
+
+ \sa number(), toInt()
+*/
+
+uint QString::toUInt(bool *ok, int base) const
+{
+ quint64 v = toULongLong(ok, base);
+ if (v > UINT_MAX) {
+ if (ok)
+ *ok = false;
+ v = 0;
+ }
+ return (uint)v;
+}
+
+/*!
+ Returns the string converted to a \c short using base \a
+ base, which is 10 by default and must be between 2 and 36, or 0.
+ Returns 0 if the conversion fails.
+
+ If a conversion error occurs, *\a{ok} is set to false; otherwise
+ *\a{ok} is set to true.
+
+ If \a base is 0, the C language convention is used: If the string
+ begins with "0x", base 16 is used; if the string begins with "0",
+ base 8 is used; otherwise, base 10 is used.
+
+ Example:
+
+ \snippet doc/src/snippets/qstring/main.cpp 76
+
+ \sa number(), toUShort(), toInt()
+*/
+
+short QString::toShort(bool *ok, int base) const
+{
+ long v = toLongLong(ok, base);
+ if (v < SHRT_MIN || v > SHRT_MAX) {
+ if (ok)
+ *ok = false;
+ v = 0;
+ }
+ return (short)v;
+}
+
+/*!
+ Returns the string converted to an \c{unsigned short} using base \a
+ base, which is 10 by default and must be between 2 and 36, or 0.
+ Returns 0 if the conversion fails.
+
+ If a conversion error occurs, *\a{ok} is set to false; otherwise
+ *\a{ok} is set to true.
+
+ If \a base is 0, the C language convention is used: If the string
+ begins with "0x", base 16 is used; if the string begins with "0",
+ base 8 is used; otherwise, base 10 is used.
+
+ Example:
+
+ \snippet doc/src/snippets/qstring/main.cpp 80
+
+ \sa number(), toShort()
+*/
+
+ushort QString::toUShort(bool *ok, int base) const
+{
+ ulong v = toULongLong(ok, base);
+ if (v > USHRT_MAX) {
+ if (ok)
+ *ok = false;
+ v = 0;
+ }
+ return (ushort)v;
+}
+
+
+/*!
+ Returns the string converted to a \c double value.
+
+ Returns 0.0 if the conversion fails.
+
+ If a conversion error occurs, \c{*}\a{ok} is set to false;
+ otherwise \c{*}\a{ok} is set to true.
+
+ \snippet doc/src/snippets/qstring/main.cpp 66
+
+ Various string formats for floating point numbers can be converted
+ to double values:
+
+ \snippet doc/src/snippets/qstring/main.cpp 67
+
+ This function tries to interpret the string according to the
+ current locale. The current locale is determined from the
+ system at application startup and can be changed by calling
+ QLocale::setDefault(). If the string cannot be interpreted
+ according to the current locale, this function falls back
+ on the "C" locale.
+
+ \snippet doc/src/snippets/qstring/main.cpp 69
+ \snippet doc/src/snippets/qstring/main.cpp 70
+
+ Due to the ambiguity between the decimal point and thousands group
+ separator in various locales, this function does not handle
+ thousands group separators. If you need to convert such numbers,
+ see QLocale::toDouble().
+
+ \snippet doc/src/snippets/qstring/main.cpp 68
+
+ \sa number() QLocale::setDefault() QLocale::toDouble() trimmed()
+*/
+
+double QString::toDouble(bool *ok) const
+{
+ bool my_ok;
+ QLocale def_locale;
+ double result = def_locale.d()->stringToDouble(*this, &my_ok, QLocalePrivate::FailOnGroupSeparators);
+ if (my_ok) {
+ if (ok != 0)
+ *ok = true;
+ return result;
+ }
+
+ QLocale c_locale(QLocale::C);
+ return c_locale.d()->stringToDouble(*this, ok, QLocalePrivate::FailOnGroupSeparators);
+}
+
+/*!
+ Returns the string converted to a \c float value.
+
+ If a conversion error occurs, *\a{ok} is set to false; otherwise
+ *\a{ok} is set to true. Returns 0.0 if the conversion fails.
+
+ Example:
+
+ \snippet doc/src/snippets/qstring/main.cpp 71
+
+ \sa number(), toDouble(), toInt()
+*/
+
+#define QT_MAX_FLOAT 3.4028234663852886e+38
+
+float QString::toFloat(bool *ok) const
+{
+ bool myOk;
+ double d = toDouble(&myOk);
+ if (!myOk || d > QT_MAX_FLOAT || d < -QT_MAX_FLOAT) {
+ if (ok != 0)
+ *ok = false;
+ return 0.0;
+ }
+ if (ok != 0)
+ *ok = true;
+ return (float) d;
+}
+
+/*! \fn QString &QString::setNum(int n, int base)
+
+ Sets the string to the printed value of \a n in the specified \a
+ base, and returns a reference to the string.
+
+ The base is 10 by default and must be between 2 and 36. For bases
+ other than 10, \a n is treated as an unsigned integer.
+
+ \snippet doc/src/snippets/qstring/main.cpp 56
+
+ The formatting always uses QLocale::C, i.e., English/UnitedStates.
+ To get a localized string representation of a number, use
+ QLocale::toString() with the appropriate locale.
+*/
+
+/*! \fn QString &QString::setNum(uint n, int base)
+
+ \overload
+*/
+
+/*! \fn QString &QString::setNum(long n, int base)
+
+ \overload
+*/
+
+/*! \fn QString &QString::setNum(ulong n, int base)
+
+ \overload
+*/
+
+/*!
+ \overload
+*/
+QString &QString::setNum(qlonglong n, int base)
+{
+#if defined(QT_CHECK_RANGE)
+ if (base < 2 || base > 36) {
+ qWarning("QString::setNum: Invalid base (%d)", base);
+ base = 10;
+ }
+#endif
+ QLocale locale(QLocale::C);
+ *this = locale.d()->longLongToString(n, -1, base);
+ return *this;
+}
+
+/*!
+ \overload
+*/
+QString &QString::setNum(qulonglong n, int base)
+{
+#if defined(QT_CHECK_RANGE)
+ if (base < 2 || base > 36) {
+ qWarning("QString::setNum: Invalid base (%d)", base);
+ base = 10;
+ }
+#endif
+ QLocale locale(QLocale::C);
+ *this = locale.d()->unsLongLongToString(n, -1, base);
+ return *this;
+}
+
+/*! \fn QString &QString::setNum(short n, int base)
+
+ \overload
+*/
+
+/*! \fn QString &QString::setNum(ushort n, int base)
+
+ \overload
+*/
+
+/*!
+ \fn QString &QString::setNum(double n, char format, int precision)
+ \overload
+
+ Sets the string to the printed value of \a n, formatted according
+ to the given \a format and \a precision, and returns a reference
+ to the string.
+
+ The \a format can be 'f', 'F', 'e', 'E', 'g' or 'G' (see the
+ arg() function documentation for an explanation of the formats).
+
+ Unlike QLocale::toString(), this function doesn't honor the
+ user's locale settings.
+*/
+
+QString &QString::setNum(double n, char f, int prec)
+{
+ QLocalePrivate::DoubleForm form = QLocalePrivate::DFDecimal;
+ uint flags = 0;
+
+ if (qIsUpper(f))
+ flags = QLocalePrivate::CapitalEorX;
+ f = qToLower(f);
+
+ switch (f) {
+ case 'f':
+ form = QLocalePrivate::DFDecimal;
+ break;
+ case 'e':
+ form = QLocalePrivate::DFExponent;
+ break;
+ case 'g':
+ form = QLocalePrivate::DFSignificantDigits;
+ break;
+ default:
+#if defined(QT_CHECK_RANGE)
+ qWarning("QString::setNum: Invalid format char '%c'", f);
+#endif
+ break;
+ }
+
+ QLocale locale(QLocale::C);
+ *this = locale.d()->doubleToString(n, prec, form, -1, flags);
+ return *this;
+}
+
+/*!
+ \fn QString &QString::setNum(float n, char format, int precision)
+ \overload
+
+ Sets the string to the printed value of \a n, formatted according
+ to the given \a format and \a precision, and returns a reference
+ to the string.
+*/
+
+
+/*!
+ \fn QString QString::number(long n, int base)
+
+ Returns a string equivalent of the number \a n according to the
+ specified \a base.
+
+ The base is 10 by default and must be between 2
+ and 36. For bases other than 10, \a n is treated as an
+ unsigned integer.
+
+ \snippet doc/src/snippets/qstring/main.cpp 35
+
+ \sa setNum()
+*/
+
+QString QString::number(long n, int base)
+{
+ QString s;
+ s.setNum(n, base);
+ return s;
+}
+
+/*!
+ \fn QString QString::number(ulong n, int base)
+
+ \overload
+*/
+QString QString::number(ulong n, int base)
+{
+ QString s;
+ s.setNum(n, base);
+ return s;
+}
+
+/*!
+ \overload
+*/
+QString QString::number(int n, int base)
+{
+ QString s;
+ s.setNum(n, base);
+ return s;
+}
+
+/*!
+ \overload
+*/
+QString QString::number(uint n, int base)
+{
+ QString s;
+ s.setNum(n, base);
+ return s;
+}
+
+/*!
+ \overload
+*/
+QString QString::number(qlonglong n, int base)
+{
+ QString s;
+ s.setNum(n, base);
+ return s;
+}
+
+/*!
+ \overload
+*/
+QString QString::number(qulonglong n, int base)
+{
+ QString s;
+ s.setNum(n, base);
+ return s;
+}
+
+
+/*!
+ \fn QString QString::number(double n, char format, int precision)
+
+ Returns a string equivalent of the number \a n, formatted
+ according to the specified \a format and \a precision. See
+ \l{Argument Formats} for details.
+
+ Unlike QLocale::toString(), this function does not honor the
+ user's locale settings.
+
+ \sa setNum(), QLocale::toString()
+*/
+QString QString::number(double n, char f, int prec)
+{
+ QString s;
+ s.setNum(n, f, prec);
+ return s;
+}
+
+/*!
+ Splits the string into substrings wherever \a sep occurs, and
+ returns the list of those strings. If \a sep does not match
+ anywhere in the string, split() returns a single-element list
+ containing this string.
+
+ \a cs specifies whether \a sep should be matched case
+ sensitively or case insensitively.
+
+ If \a behavior is QString::SkipEmptyParts, empty entries don't
+ appear in the result. By default, empty entries are kept.
+
+ Example:
+
+ \snippet doc/src/snippets/qstring/main.cpp 62
+
+ \sa QStringList::join(), section()
+*/
+QStringList QString::split(const QString &sep, SplitBehavior behavior, Qt::CaseSensitivity cs) const
+{
+ QStringList list;
+ int start = 0;
+ int extra = 0;
+ int end;
+ while ((end = indexOf(sep, start + extra, cs)) != -1) {
+ if (start != end || behavior == KeepEmptyParts)
+ list.append(mid(start, end - start));
+ start = end + sep.size();
+ extra = (sep.size() == 0 ? 1 : 0);
+ }
+ if (start != size() || behavior == KeepEmptyParts)
+ list.append(mid(start));
+ return list;
+}
+
+/*!
+ \overload
+*/
+QStringList QString::split(const QChar &sep, SplitBehavior behavior, Qt::CaseSensitivity cs) const
+{
+ QStringList list;
+ int start = 0;
+ int end;
+ while ((end = indexOf(sep, start, cs)) != -1) {
+ if (start != end || behavior == KeepEmptyParts)
+ list.append(mid(start, end - start));
+ start = end + 1;
+ }
+ if (start != size() || behavior == KeepEmptyParts)
+ list.append(mid(start));
+ return list;
+}
+
+#ifndef QT_NO_REGEXP
+/*!
+ \overload
+
+ Splits the string into substrings wherever the regular expression
+ \a rx matches, and returns the list of those strings. If \a rx
+ does not match anywhere in the string, split() returns a
+ single-element list containing this string.
+
+ Here's an example where we extract the words in a sentence
+ using one or more whitespace characters as the separator:
+
+ \snippet doc/src/snippets/qstring/main.cpp 59
+
+ Here's a similar example, but this time we use any sequence of
+ non-word characters as the separator:
+
+ \snippet doc/src/snippets/qstring/main.cpp 60
+
+ Here's a third example where we use a zero-length assertion,
+ \bold{\\b} (word boundary), to split the string into an
+ alternating sequence of non-word and word tokens:
+
+ \snippet doc/src/snippets/qstring/main.cpp 61
+
+ \sa QStringList::join(), section()
+*/
+QStringList QString::split(const QRegExp &rx, SplitBehavior behavior) const
+{
+ QRegExp rx2(rx);
+ QStringList list;
+ int start = 0;
+ int extra = 0;
+ int end;
+ while ((end = rx2.indexIn(*this, start + extra)) != -1) {
+ int matchedLen = rx2.matchedLength();
+ if (start != end || behavior == KeepEmptyParts)
+ list.append(mid(start, end - start));
+ start = end + matchedLen;
+ extra = (matchedLen == 0) ? 1 : 0;
+ }
+ if (start != size() || behavior == KeepEmptyParts)
+ list.append(mid(start));
+ return list;
+}
+#endif
+
+/*!
+ \enum QString::NormalizationForm
+
+ This enum describes the various normalized forms of Unicode text.
+
+ \value NormalizationForm_D Canonical Decomposition
+ \value NormalizationForm_C Canonical Decomposition followed by Canonical Composition
+ \value NormalizationForm_KD Compatibility Decomposition
+ \value NormalizationForm_KC Compatibility Decomposition followed by Canonical Composition
+
+ \sa normalized(),
+ {http://www.unicode.org/reports/tr15/}{Unicode Standard Annex #15}
+*/
+
+/*!
+ \fn QString QString::normalized(NormalizationForm mode) const
+ Returns the string in the given Unicode normalization \a mode.
+*/
+QString QString::normalized(QString::NormalizationForm mode) const
+{
+ return normalized(mode, CURRENT_VERSION);
+}
+
+/*!
+ \since 4.5
+
+ Returns a copy of this string repeated the specified number of \a times.
+
+ If \a times is less than 1, an empty string is returned.
+
+ Example:
+
+ \code
+ QString str("ab");
+ str.repeated(4); // returns "abababab"
+ \endcode
+*/
+QString QString::repeated(int times) const
+{
+ if (d->size == 0)
+ return *this;
+
+ if (times <= 1) {
+ if (times == 1)
+ return *this;
+ return QString();
+ }
+
+ const int resultSize = times * d->size;
+
+ QString result;
+ result.reserve(resultSize);
+ if (result.d->alloc != resultSize)
+ return QString(); // not enough memory
+
+ qMemCopy(result.d->data, d->data, d->size * sizeof(ushort));
+
+ int sizeSoFar = d->size;
+ ushort *end = result.d->data + sizeSoFar;
+
+ const int halfResultSize = resultSize >> 1;
+ while (sizeSoFar <= halfResultSize) {
+ qMemCopy(end, result.d->data, sizeSoFar * sizeof(ushort));
+ end += sizeSoFar;
+ sizeSoFar <<= 1;
+ }
+ qMemCopy(end, result.d->data, (resultSize - sizeSoFar) * sizeof(ushort));
+ result.d->data[resultSize] = '\0';
+ result.d->size = resultSize;
+ return result;
+}
+
+/*!
+ \overload
+ \fn QString QString::normalized(NormalizationForm mode, QChar::UnicodeVersion version) const
+
+ Returns the string in the given Unicode normalization \a mode,
+ according to the given \a version of the Unicode standard.
+*/
+QString QString::normalized(QString::NormalizationForm mode, QChar::UnicodeVersion version) const
+{
+ bool simple = true;
+ for (int i = 0; i < d->size; ++i) {
+ if (d->data[i] >= 0x80) {
+ simple = false;
+ break;
+ }
+ }
+ if (simple)
+ return *this;
+
+ QString s = *this;
+ if (version != CURRENT_VERSION) {
+ for (int i = 0; i < NumNormalizationCorrections; ++i) {
+ const NormalizationCorrection &n = uc_normalization_corrections[i];
+ if (n.version > version) {
+ if (n.ucs4 > 0xffff) {
+ ushort ucs4High = QChar::highSurrogate(n.ucs4);
+ ushort ucs4Low = QChar::lowSurrogate(n.ucs4);
+ ushort oldHigh = QChar::highSurrogate(n.old_mapping);
+ ushort oldLow = QChar::lowSurrogate(n.old_mapping);
+ int pos = 0;
+ while (pos < s.d->size - 1) {
+ if (s.d->data[pos] == ucs4High && s.d->data[pos + 1] == ucs4Low) {
+ s.detach();
+ s.d->data[pos] = oldHigh;
+ s.d->data[pos + 1] = oldLow;
+ ++pos;
+ }
+ ++pos;
+ }
+ } else {
+ int pos = 0;
+ while (pos < s.d->size) {
+ if (s.d->data[pos] == n.ucs4) {
+ s.detach();
+ s.d->data[pos] = n.old_mapping;
+ }
+ ++pos;
+ }
+ }
+ }
+ }
+ }
+ s = decomposeHelper(s, mode < QString::NormalizationForm_KD, version);
+
+ s = canonicalOrderHelper(s, version);
+
+ if (mode == QString::NormalizationForm_D || mode == QString::NormalizationForm_KD)
+ return s;
+
+ return composeHelper(s);
+
+}
+
+
+struct ArgEscapeData
+{
+ int min_escape; // lowest escape sequence number
+ int occurrences; // number of occurrences of the lowest escape sequence number
+ int locale_occurrences; // number of occurrences of the lowest escape sequence number that
+ // contain 'L'
+ int escape_len; // total length of escape sequences which will be replaced
+};
+
+static ArgEscapeData findArgEscapes(const QString &s)
+{
+ const QChar *uc_begin = s.unicode();
+ const QChar *uc_end = uc_begin + s.length();
+
+ ArgEscapeData d;
+
+ d.min_escape = INT_MAX;
+ d.occurrences = 0;
+ d.escape_len = 0;
+ d.locale_occurrences = 0;
+
+ const QChar *c = uc_begin;
+ while (c != uc_end) {
+ while (c != uc_end && c->unicode() != '%')
+ ++c;
+
+ if (c == uc_end)
+ break;
+ const QChar *escape_start = c;
+ if (++c == uc_end)
+ break;
+
+ bool locale_arg = false;
+ if (c->unicode() == 'L') {
+ locale_arg = true;
+ if (++c == uc_end)
+ break;
+ }
+
+ if (c->digitValue() == -1)
+ continue;
+
+ int escape = c->digitValue();
+ ++c;
+
+ if (c != uc_end && c->digitValue() != -1) {
+ escape = (10 * escape) + c->digitValue();
+ ++c;
+ }
+
+ if (escape > d.min_escape)
+ continue;
+
+ if (escape < d.min_escape) {
+ d.min_escape = escape;
+ d.occurrences = 0;
+ d.escape_len = 0;
+ d.locale_occurrences = 0;
+ }
+
+ ++d.occurrences;
+ if (locale_arg)
+ ++d.locale_occurrences;
+ d.escape_len += c - escape_start;
+ }
+ return d;
+}
+
+static QString replaceArgEscapes(const QString &s, const ArgEscapeData &d, int field_width,
+ const QString &arg, const QString &larg, const QChar &fillChar = QLatin1Char(' '))
+{
+ const QChar *uc_begin = s.unicode();
+ const QChar *uc_end = uc_begin + s.length();
+
+ int abs_field_width = qAbs(field_width);
+ int result_len = s.length()
+ - d.escape_len
+ + (d.occurrences - d.locale_occurrences)
+ *qMax(abs_field_width, arg.length())
+ + d.locale_occurrences
+ *qMax(abs_field_width, larg.length());
+
+ QString result;
+ result.resize(result_len);
+ QChar *result_buff = (QChar*) result.unicode();
+
+ QChar *rc = result_buff;
+ const QChar *c = uc_begin;
+ int repl_cnt = 0;
+ while (c != uc_end) {
+ /* We don't have to check if we run off the end of the string with c,
+ because as long as d.occurrences > 0 we KNOW there are valid escape
+ sequences. */
+
+ const QChar *text_start = c;
+
+ while (c->unicode() != '%')
+ ++c;
+
+ const QChar *escape_start = c++;
+
+ bool locale_arg = false;
+ if (c->unicode() == 'L') {
+ locale_arg = true;
+ ++c;
+ }
+
+ int escape = c->digitValue();
+ if (escape != -1) {
+ if (c + 1 != uc_end && (c + 1)->digitValue() != -1) {
+ escape = (10 * escape) + (c + 1)->digitValue();
+ ++c;
+ }
+ }
+
+ if (escape != d.min_escape) {
+ memcpy(rc, text_start, (c - text_start)*sizeof(QChar));
+ rc += c - text_start;
+ }
+ else {
+ ++c;
+
+ memcpy(rc, text_start, (escape_start - text_start)*sizeof(QChar));
+ rc += escape_start - text_start;
+
+ uint pad_chars;
+ if (locale_arg)
+ pad_chars = qMax(abs_field_width, larg.length()) - larg.length();
+ else
+ pad_chars = qMax(abs_field_width, arg.length()) - arg.length();
+
+ if (field_width > 0) { // left padded
+ for (uint i = 0; i < pad_chars; ++i)
+ (rc++)->unicode() = fillChar.unicode();
+ }
+
+ if (locale_arg) {
+ memcpy(rc, larg.unicode(), larg.length()*sizeof(QChar));
+ rc += larg.length();
+ }
+ else {
+ memcpy(rc, arg.unicode(), arg.length()*sizeof(QChar));
+ rc += arg.length();
+ }
+
+ if (field_width < 0) { // right padded
+ for (uint i = 0; i < pad_chars; ++i)
+ (rc++)->unicode() = fillChar.unicode();
+ }
+
+ if (++repl_cnt == d.occurrences) {
+ memcpy(rc, c, (uc_end - c)*sizeof(QChar));
+ rc += uc_end - c;
+ Q_ASSERT(rc - result_buff == result_len);
+ c = uc_end;
+ }
+ }
+ }
+ Q_ASSERT(rc == result_buff + result_len);
+
+ return result;
+}
+
+/*!
+ Returns a copy of this string with the lowest numbered place marker
+ replaced by string \a a, i.e., \c %1, \c %2, ..., \c %99.
+
+ \a fieldWidth specifies the minimum amount of space that argument \a
+ a shall occupy. If \a a requires less space than \a fieldWidth, it
+ is padded to \a fieldWidth with character \a fillChar. A positive
+ \a fieldWidth produces right-aligned text. A negative \a fieldWidth
+ produces left-aligned text.
+
+ This example shows how we might create a \c status string for
+ reporting progress while processing a list of files:
+
+ \snippet doc/src/snippets/qstring/main.cpp 11
+
+ First, \c arg(i) replaces \c %1. Then \c arg(total) replaces \c
+ %2. Finally, \c arg(fileName) replaces \c %3.
+
+ One advantage of using arg() over sprintf() is that the order of the
+ numbered place markers can change, if the application's strings are
+ translated into other languages, but each arg() will still replace
+ the lowest numbered unreplaced place marker, no matter where it
+ appears. Also, if place marker \c %i appears more than once in the
+ string, the arg() replaces all of them.
+
+ If there is no unreplaced place marker remaining, a warning message
+ is output and the result is undefined. Place marker numbers must be
+ in the range 1 to 99.
+*/
+QString QString::arg(const QString &a, int fieldWidth, const QChar &fillChar) const
+{
+ ArgEscapeData d = findArgEscapes(*this);
+
+ if (d.occurrences == 0) {
+ qWarning("QString::arg: Argument missing: %s, %s", toLocal8Bit().data(),
+ a.toLocal8Bit().data());
+ return *this;
+ }
+ return replaceArgEscapes(*this, d, fieldWidth, a, a, fillChar);
+}
+
+/*!
+ \fn QString QString::arg(const QString& a1, const QString& a2) const
+ \overload arg()
+
+ This is the same as \c {str.arg(a1).arg(a2)}, except that the
+ strings \a a1 and \a a2 are replaced in one pass. This can make a
+ difference if \a a1 contains e.g. \c{%1}:
+
+ \snippet doc/src/snippets/qstring/main.cpp 13
+*/
+
+/*!
+ \fn QString QString::arg(const QString& a1, const QString& a2, const QString& a3) const
+ \overload arg()
+
+ This is the same as calling \c str.arg(a1).arg(a2).arg(a3), except
+ that the strings \a a1, \a a2 and \a a3 are replaced in one pass.
+*/
+
+/*!
+ \fn QString QString::arg(const QString& a1, const QString& a2, const QString& a3, const QString& a4) const
+ \overload arg()
+
+ This is the same as calling \c
+ {str.arg(a1).arg(a2).arg(a3).arg(a4)}, except that the strings \a
+ a1, \a a2, \a a3 and \a a4 are replaced in one pass.
+*/
+
+/*!
+ \fn QString QString::arg(const QString& a1, const QString& a2, const QString& a3, const QString& a4, const QString& a5) const
+ \overload arg()
+
+ This is the same as calling \c
+ {str.arg(a1).arg(a2).arg(a3).arg(a4).arg(a5)}, except that the strings
+ \a a1, \a a2, \a a3, \a a4, and \a a5 are replaced in one pass.
+*/
+
+/*!
+ \fn QString QString::arg(const QString& a1, const QString& a2, const QString& a3, const QString& a4, const QString& a5, const QString& a6) const
+ \overload arg()
+
+ This is the same as calling \c
+ {str.arg(a1).arg(a2).arg(a3).arg(a4).arg(a5).arg(a6))}, except that
+ the strings \a a1, \a a2, \a a3, \a a4, \a a5, and \a a6 are
+ replaced in one pass.
+*/
+
+/*!
+ \fn QString QString::arg(const QString& a1, const QString& a2, const QString& a3, const QString& a4, const QString& a5, const QString& a6, const QString& a7) const
+ \overload arg()
+
+ This is the same as calling \c
+ {str.arg(a1).arg(a2).arg(a3).arg(a4).arg(a5).arg(a6).arg(a7)},
+ except that the strings \a a1, \a a2, \a a3, \a a4, \a a5, \a a6,
+ and \a a7 are replaced in one pass.
+*/
+
+/*!
+ \fn QString QString::arg(const QString& a1, const QString& a2, const QString& a3, const QString& a4, const QString& a5, const QString& a6, const QString& a7, const QString& a8) const
+ \overload arg()
+
+ This is the same as calling \c
+ {str.arg(a1).arg(a2).arg(a3).arg(a4).arg(a5).arg(a6).arg(a7).arg(a8)},
+ except that the strings \a a1, \a a2, \a a3, \a a4, \a a5, \a a6, \a
+ a7, and \a a8 are replaced in one pass.
+*/
+
+/*!
+ \fn QString QString::arg(const QString& a1, const QString& a2, const QString& a3, const QString& a4, const QString& a5, const QString& a6, const QString& a7, const QString& a8, const QString& a9) const
+ \overload arg()
+
+ This is the same as calling \c
+ {str.arg(a1).arg(a2).arg(a3).arg(a4).arg(a5).arg(a6).arg(a7).arg(a8).arg(a9)},
+ except that the strings \a a1, \a a2, \a a3, \a a4, \a a5, \a a6, \a
+ a7, \a a8, and \a a9 are replaced in one pass.
+*/
+
+/*! \fn QString QString::arg(int a, int fieldWidth, int base, const QChar &fillChar) const
+ \overload arg()
+
+ The \a a argument is expressed in base \a base, which is 10 by
+ default and must be between 2 and 36. For bases other than 10, \a a
+ is treated as an unsigned integer.
+
+ \a fieldWidth specifies the minimum amount of space that \a a is
+ padded to and filled with the character \a fillChar. A positive
+ value produces right-aligned text; a negative value produces
+ left-aligned text.
+
+ The '%' can be followed by an 'L', in which case the sequence is
+ replaced with a localized representation of \a a. The conversion
+ uses the default locale, set by QLocale::setDefault(). If no default
+ locale was specified, the "C" locale is used. The 'L' flag is
+ ignored if \a base is not 10.
+
+ \snippet doc/src/snippets/qstring/main.cpp 12
+ \snippet doc/src/snippets/qstring/main.cpp 14
+
+ If \a fillChar is '0' (the number 0, ASCII 48), the locale's zero is
+ used. For negative numbers, zero padding might appear before the
+ minus sign.
+*/
+
+/*! \fn QString QString::arg(uint a, int fieldWidth, int base, const QChar &fillChar) const
+ \overload arg()
+
+ The \a base argument specifies the base to use when converting the
+ integer \a a into a string. The base must be between 2 and 36.
+
+ If \a fillChar is '0' (the number 0, ASCII 48), the locale's zero is
+ used. For negative numbers, zero padding might appear before the
+ minus sign.
+*/
+
+/*! \fn QString QString::arg(long a, int fieldWidth, int base, const QChar &fillChar) const
+ \overload arg()
+
+ \a fieldWidth specifies the minimum amount of space that \a a is
+ padded to and filled with the character \a fillChar. A positive
+ value produces right-aligned text; a negative value produces
+ left-aligned text.
+
+ The \a a argument is expressed in the given \a base, which is 10 by
+ default and must be between 2 and 36.
+
+ The '%' can be followed by an 'L', in which case the sequence is
+ replaced with a localized representation of \a a. The conversion
+ uses the default locale. The default locale is determined from the
+ system's locale settings at application startup. It can be changed
+ using QLocale::setDefault(). The 'L' flag is ignored if \a base is
+ not 10.
+
+ \snippet doc/src/snippets/qstring/main.cpp 12
+ \snippet doc/src/snippets/qstring/main.cpp 14
+
+ If \a fillChar is '0' (the number 0, ASCII 48), the locale's zero is
+ used. For negative numbers, zero padding might appear before the
+ minus sign.
+*/
+
+/*! \fn QString QString::arg(ulong a, int fieldWidth, int base, const QChar &fillChar) const
+ \overload arg()
+
+ \a fieldWidth specifies the minimum amount of space that \a a is
+ padded to and filled with the character \a fillChar. A positive
+ value produces right-aligned text; a negative value produces
+ left-aligned text.
+
+ The \a base argument specifies the base to use when converting the
+ integer \a a to a string. The base must be between 2 and 36, with 8
+ giving octal, 10 decimal, and 16 hexadecimal numbers.
+
+ If \a fillChar is '0' (the number 0, ASCII 48), the locale's zero is
+ used. For negative numbers, zero padding might appear before the
+ minus sign.
+*/
+
+/*!
+ \overload arg()
+
+ \a fieldWidth specifies the minimum amount of space that \a a is
+ padded to and filled with the character \a fillChar. A positive
+ value produces right-aligned text; a negative value produces
+ left-aligned text.
+
+ The \a base argument specifies the base to use when converting the
+ integer \a a into a string. The base must be between 2 and 36, with
+ 8 giving octal, 10 decimal, and 16 hexadecimal numbers.
+
+ If \a fillChar is '0' (the number 0, ASCII 48), the locale's zero is
+ used. For negative numbers, zero padding might appear before the
+ minus sign.
+*/
+QString QString::arg(qlonglong a, int fieldWidth, int base, const QChar &fillChar) const
+{
+ ArgEscapeData d = findArgEscapes(*this);
+
+ if (d.occurrences == 0) {
+ qWarning("QString::arg: Argument missing: %s, %lld", toLocal8Bit().data(), a);
+ return *this;
+ }
+
+ unsigned flags = QLocalePrivate::NoFlags;
+ if (fillChar == QLatin1Char('0'))
+ flags = QLocalePrivate::ZeroPadded;
+
+ QString arg;
+ if (d.occurrences > d.locale_occurrences)
+ arg = QLocale::c().d()->longLongToString(a, -1, base, fieldWidth, flags);
+
+ QString locale_arg;
+ if (d.locale_occurrences > 0) {
+ QLocale locale;
+ locale_arg = locale.d()->longLongToString(a, -1, base, fieldWidth,
+ flags | QLocalePrivate::ThousandsGroup);
+ }
+
+ return replaceArgEscapes(*this, d, fieldWidth, arg, locale_arg, fillChar);
+}
+
+/*!
+ \overload arg()
+
+ \a fieldWidth specifies the minimum amount of space that \a a is
+ padded to and filled with the character \a fillChar. A positive
+ value produces right-aligned text; a negative value produces
+ left-aligned text.
+
+ The \a base argument specifies the base to use when converting the
+ integer \a a into a string. \a base must be between 2 and 36, with 8
+ giving octal, 10 decimal, and 16 hexadecimal numbers.
+
+ If \a fillChar is '0' (the number 0, ASCII 48), the locale's zero is
+ used. For negative numbers, zero padding might appear before the
+ minus sign.
+*/
+QString QString::arg(qulonglong a, int fieldWidth, int base, const QChar &fillChar) const
+{
+ ArgEscapeData d = findArgEscapes(*this);
+
+ if (d.occurrences == 0) {
+ qWarning("QString::arg: Argument missing: %s, %llu", toLocal8Bit().data(), a);
+ return *this;
+ }
+
+ unsigned flags = QLocalePrivate::NoFlags;
+ if (fillChar == QLatin1Char('0'))
+ flags = QLocalePrivate::ZeroPadded;
+
+ QString arg;
+ if (d.occurrences > d.locale_occurrences)
+ arg = QLocale::c().d()->unsLongLongToString(a, -1, base, fieldWidth, flags);
+
+ QString locale_arg;
+ if (d.locale_occurrences > 0) {
+ QLocale locale;
+ locale_arg = locale.d()->unsLongLongToString(a, -1, base, fieldWidth,
+ flags | QLocalePrivate::ThousandsGroup);
+ }
+
+ return replaceArgEscapes(*this, d, fieldWidth, arg, locale_arg, fillChar);
+}
+
+/*!
+ \overload arg()
+
+ \fn QString QString::arg(short a, int fieldWidth, int base, const QChar &fillChar) const
+
+ \a fieldWidth specifies the minimum amount of space that \a a is
+ padded to and filled with the character \a fillChar. A positive
+ value produces right-aligned text; a negative value produces
+ left-aligned text.
+
+ The \a base argument specifies the base to use when converting the
+ integer \a a into a string. The base must be between 2 and 36, with
+ 8 giving octal, 10 decimal, and 16 hexadecimal numbers.
+
+ If \a fillChar is '0' (the number 0, ASCII 48), the locale's zero is
+ used. For negative numbers, zero padding might appear before the
+ minus sign.
+*/
+
+/*!
+ \fn QString QString::arg(ushort a, int fieldWidth, int base, const QChar &fillChar) const
+ \overload arg()
+
+ \a fieldWidth specifies the minimum amount of space that \a a is
+ padded to and filled with the character \a fillChar. A positive
+ value produces right-aligned text; a negative value produces
+ left-aligned text.
+
+ The \a base argument specifies the base to use when converting the
+ integer \a a into a string. The base must be between 2 and 36, with
+ 8 giving octal, 10 decimal, and 16 hexadecimal numbers.
+
+ If \a fillChar is '0' (the number 0, ASCII 48), the locale's zero is
+ used. For negative numbers, zero padding might appear before the
+ minus sign.
+*/
+
+/*!
+ \overload arg()
+*/
+QString QString::arg(QChar a, int fieldWidth, const QChar &fillChar) const
+{
+ QString c;
+ c += a;
+ return arg(c, fieldWidth, fillChar);
+}
+
+/*!
+ \overload arg()
+
+ The \a a argument is interpreted as a Latin-1 character.
+*/
+QString QString::arg(char a, int fieldWidth, const QChar &fillChar) const
+{
+ QString c;
+ c += QLatin1Char(a);
+ return arg(c, fieldWidth, fillChar);
+}
+
+/*!
+ \fn QString QString::arg(double a, int fieldWidth, char format, int precision, const QChar &fillChar) const
+ \overload arg()
+
+ Argument \a a is formatted according to the specified \a format and
+ \a precision. See \l{Argument Formats} for details.
+
+ \a fieldWidth specifies the minimum amount of space that \a a is
+ padded to and filled with the character \a fillChar. A positive
+ value produces right-aligned text; a negative value produces
+ left-aligned text.
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qstring.cpp 2
+
+ The '%' can be followed by an 'L', in which case the sequence is
+ replaced with a localized representation of \a a. The conversion
+ uses the default locale, set by QLocale::setDefaultLocale(). If no
+ default locale was specified, the "C" locale is used.
+
+ If \a fillChar is '0' (the number 0, ASCII 48), this function will
+ use the locale's zero to pad. For negative numbers, the zero padding
+ will probably appear before the minus sign.
+
+ \sa QLocale::toString()
+*/
+QString QString::arg(double a, int fieldWidth, char fmt, int prec, const QChar &fillChar) const
+{
+ ArgEscapeData d = findArgEscapes(*this);
+
+ if (d.occurrences == 0) {
+ qWarning("QString::arg: Argument missing: %s, %g", toLocal8Bit().data(), a);
+ return *this;
+ }
+
+ unsigned flags = QLocalePrivate::NoFlags;
+ if (fillChar == QLatin1Char('0'))
+ flags = QLocalePrivate::ZeroPadded;
+
+ if (qIsUpper(fmt))
+ flags |= QLocalePrivate::CapitalEorX;
+ fmt = qToLower(fmt);
+
+ QLocalePrivate::DoubleForm form = QLocalePrivate::DFDecimal;
+ switch (fmt) {
+ case 'f':
+ form = QLocalePrivate::DFDecimal;
+ break;
+ case 'e':
+ form = QLocalePrivate::DFExponent;
+ break;
+ case 'g':
+ form = QLocalePrivate::DFSignificantDigits;
+ break;
+ default:
+#if defined(QT_CHECK_RANGE)
+ qWarning("QString::arg: Invalid format char '%c'", fmt);
+#endif
+ break;
+ }
+
+ QString arg;
+ if (d.occurrences > d.locale_occurrences)
+ arg = QLocale::c().d()->doubleToString(a, prec, form, fieldWidth, flags);
+
+ QString locale_arg;
+ if (d.locale_occurrences > 0) {
+ QLocale locale;
+
+ flags |= QLocalePrivate::ThousandsGroup;
+ locale_arg = locale.d()->doubleToString(a, prec, form, fieldWidth, flags);
+ }
+
+ return replaceArgEscapes(*this, d, fieldWidth, arg, locale_arg, fillChar);
+}
+
+static int getEscape(const QChar *uc, int *pos, int len, int maxNumber = 999)
+{
+ int i = *pos;
+ ++i;
+ if (i < len && uc[i] == QLatin1Char('L'))
+ ++i;
+ if (i < len) {
+ int escape = uc[i].unicode() - '0';
+ if (uint(escape) >= 10U)
+ return -1;
+ ++i;
+ while (i < len) {
+ int digit = uc[i].unicode() - '0';
+ if (uint(digit) >= 10U)
+ break;
+ escape = (escape * 10) + digit;
+ ++i;
+ }
+ if (escape <= maxNumber) {
+ *pos = i;
+ return escape;
+ }
+ }
+ return -1;
+}
+
+QString QString::multiArg(int numArgs, const QString **args) const
+{
+ QString result;
+ QMap<int, int> numbersUsed;
+ const QChar *uc = (const QChar *) d->data;
+ const int len = d->size;
+ const int end = len - 1;
+ int lastNumber = -1;
+ int i = 0;
+
+ // populate the numbersUsed map with the %n's that actually occur in the string
+ while (i < end) {
+ if (uc[i] == QLatin1Char('%')) {
+ int number = getEscape(uc, &i, len);
+ if (number != -1) {
+ numbersUsed.insert(number, -1);
+ continue;
+ }
+ }
+ ++i;
+ }
+
+ // assign an argument number to each of the %n's
+ QMap<int, int>::iterator j = numbersUsed.begin();
+ QMap<int, int>::iterator jend = numbersUsed.end();
+ int arg = 0;
+ while (j != jend && arg < numArgs) {
+ *j = arg++;
+ lastNumber = j.key();
+ ++j;
+ }
+
+ // sanity
+ if (numArgs > arg) {
+ qWarning("QString::arg: %d argument(s) missing in %s", numArgs - arg, toLocal8Bit().data());
+ numArgs = arg;
+ }
+
+ i = 0;
+ while (i < len) {
+ if (uc[i] == QLatin1Char('%') && i != end) {
+ int number = getEscape(uc, &i, len, lastNumber);
+ int arg = numbersUsed[number];
+ if (number != -1 && arg != -1) {
+ result += *args[arg];
+ continue;
+ }
+ }
+ result += uc[i++];
+ }
+ return result;
+}
+
+/*! \internal
+ */
+void QString::updateProperties() const
+{
+ ushort *p = d->data;
+ ushort *end = p + d->size;
+ d->simpletext = true;
+ while (p < end) {
+ ushort uc = *p;
+ // sort out regions of complex text formatting
+ if (uc > 0x058f && (uc < 0x1100 || uc > 0xfb0f)) {
+ d->simpletext = false;
+ }
+ p++;
+ }
+
+ p = d->data;
+ d->righttoleft = false;
+ while (p < end) {
+ switch(QChar::direction(*p))
+ {
+ case QChar::DirL:
+ case QChar::DirLRO:
+ case QChar::DirLRE:
+ goto end;
+ case QChar::DirR:
+ case QChar::DirAL:
+ case QChar::DirRLO:
+ case QChar::DirRLE:
+ d->righttoleft = true;
+ goto end;
+ default:
+ break;
+ }
+ ++p;
+ }
+ end:
+ d->clean = true;
+ return;
+}
+
+/*! \fn bool QString::isSimpleText() const
+
+ \internal
+*/
+
+/*! \fn bool QString::isRightToLeft() const
+
+ \internal
+*/
+
+
+/*! \fn QChar *QString::data()
+
+ Returns a pointer to the data stored in the QString. The pointer
+ can be used to access and modify the characters that compose the
+ string. For convenience, the data is '\\0'-terminated.
+
+ Example:
+
+ \snippet doc/src/snippets/qstring/main.cpp 19
+
+ Note that the pointer remains valid only as long as the string is
+ not modified by other means. For read-only access, constData() is
+ faster because it never causes a \l{deep copy} to occur.
+
+ \sa constData(), operator[]()
+*/
+
+/*! \fn const QChar *QString::data() const
+
+ \overload
+*/
+
+/*! \fn const QChar *QString::constData() const
+
+ Returns a pointer to the data stored in the QString. The pointer
+ can be used to access the characters that compose the string. For
+ convenience, the data is '\\0'-terminated.
+
+ Note that the pointer remains valid only as long as the string is
+ not modified.
+
+ \sa data(), operator[]()
+*/
+
+/*! \fn void QString::push_front(const QString &other)
+
+ This function is provided for STL compatibility, prepending the
+ given \a other string to the beginning of this string. It is
+ equivalent to \c prepend(other).
+
+ \sa prepend()
+*/
+
+/*! \fn void QString::push_front(QChar ch)
+
+ \overload
+
+ Prepends the given \a ch character to the beginning of this string.
+*/
+
+/*! \fn void QString::push_back(const QString &other)
+
+ This function is provided for STL compatibility, appending the
+ given \a other string onto the end of this string. It is
+ equivalent to \c append(other).
+
+ \sa append()
+*/
+
+/*! \fn void QString::push_back(QChar ch)
+
+ \overload
+
+ Appends the given \a ch character onto the end of this string.
+*/
+
+/*!
+ \fn std::string QString::toStdString() const
+
+ Returns a std::string object with the data contained in this
+ QString. The Unicode data is converted into 8-bit characters using
+ the toAscii() function.
+
+ This operator is mostly useful to pass a QString to a function
+ that accepts a std::string object.
+
+ If the QString contains non-ASCII Unicode characters, using this
+ operator can lead to loss of information, since the implementation
+ calls toAscii().
+
+ This operator is only available if Qt is configured with STL
+ compatibility enabled.
+
+ \sa toAscii(), toLatin1(), toUtf8(), toLocal8Bit()
+*/
+
+/*!
+ Constructs a QString that uses the first \a size Unicode characters
+ in the array \a unicode. The data in \a unicode is \e not
+ copied. The caller must be able to guarantee that \a unicode will
+ not be deleted or modified as long as the QString (or an
+ unmodified copy of it) exists.
+
+ Any attempts to modify the QString or copies of it will cause it
+ to create a deep copy of the data, ensuring that the raw data
+ isn't modified.
+
+ Here's an example of how we can use a QRegExp on raw data in
+ memory without requiring to copy the data into a QString:
+
+ \snippet doc/src/snippets/qstring/main.cpp 22
+ \snippet doc/src/snippets/qstring/main.cpp 23
+
+ \warning A string created with fromRawData() is \e not
+ '\\0'-terminated, unless the raw data contains a '\\0' character
+ at position \a size. This means unicode() will \e not return a
+ '\\0'-terminated string (although utf16() does, at the cost of
+ copying the raw data).
+
+ \sa fromUtf16()
+*/
+QString QString::fromRawData(const QChar *unicode, int size)
+{
+ Data *x = static_cast<Data *>(qMalloc(sizeof(Data)));
+ if (unicode) {
+ x->data = (ushort *)unicode;
+ } else {
+ x->data = x->array;
+ size = 0;
+ }
+ x->ref = 1;
+ x->alloc = x->size = size;
+ *x->array = '\0';
+ x->clean = x->asciiCache = x->simpletext = x->righttoleft = x->capacity = 0;
+ return QString(x, 0);
+}
+
+/*! \class QLatin1String
+ \brief The QLatin1String class provides a thin wrapper around an ASCII/Latin-1 encoded string literal.
+
+ \ingroup text
+ \reentrant
+
+ Many of QString's member functions are overloaded to accept
+ \c{const char *} instead of QString. This includes the copy
+ constructor, the assignment operator, the comparison operators,
+ and various other functions such as \link QString::insert()
+ insert() \endlink, \link QString::replace() replace()\endlink,
+ and \link QString::indexOf() indexOf()\endlink. These functions
+ are usually optimized to avoid constructing a QString object for
+ the \c{const char *} data. For example, assuming \c str is a
+ QString,
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qstring.cpp 3
+
+ is much faster than
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qstring.cpp 4
+
+ because it doesn't construct four temporary QString objects and
+ make a deep copy of the character data.
+
+ Applications that define \c QT_NO_CAST_FROM_ASCII (as explained
+ in the QString documentation) don't have access to QString's
+ \c{const char *} API. To provide an efficient way of specifying
+ constant Latin-1 strings, Qt provides the QLatin1String, which is
+ just a very thin wrapper around a \c{const char *}. Using
+ QLatin1String, the example code above becomes
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qstring.cpp 5
+
+ This is a bit longer to type, but it provides exactly the same
+ benefits as the first version of the code, and is faster than
+ converting the Latin-1 strings using QString::fromLatin1().
+
+ Thanks to the QString(const QLatin1String &) constructor,
+ QLatin1String can be used everywhere a QString is expected. For
+ example:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qstring.cpp 6
+
+ \sa QString, QLatin1Char
+*/
+
+/*! \fn QLatin1String::QLatin1String(const char *str)
+
+ Constructs a QLatin1String object that stores \a str. Note that if
+ \a str is 0, an empty string is created; this case is handled by
+ QString.
+
+ The string data is \e not copied. The caller must be able to
+ guarantee that \a str will not be deleted or modified as long as
+ the QLatin1String object exists.
+
+ \sa latin1()
+*/
+
+/*!
+ \since 4.1
+ \fn QLatin1String &QLatin1String::operator=(const QLatin1String &other)
+
+ Constructs a copy of \a other.
+*/
+
+/*! \fn const char *QLatin1String::latin1() const
+
+ Returns the Latin-1 string stored in this object.
+*/
+
+/*! \fn bool QLatin1String::operator==(const QString &other) const
+
+ Returns true if this string is equal to string \a other;
+ otherwise returns false.
+
+ The comparison is based exclusively on the numeric Unicode values
+ of the characters and is very fast, but is not what a human would
+ expect. Consider sorting user-interface strings with
+ QString::localeAwareCompare().
+*/
+
+/*!
+ \fn bool QLatin1String::operator==(const char *other) const
+ \since 4.3
+ \overload
+
+ The \a other const char pointer is converted to a QLatin1String using
+ the QString::fromAscii() function.
+
+ You can disable this operator by defining \c
+ QT_NO_CAST_FROM_ASCII when you compile your applications. This
+ can be useful if you want to ensure that all user-visible strings
+ go through QObject::tr(), for example.
+*/
+
+/*! \fn bool QLatin1String::operator!=(const QString &other) const
+
+ Returns true if this string is not equal to string \a other;
+ otherwise returns false.
+
+ The comparison is based exclusively on the numeric Unicode values
+ of the characters and is very fast, but is not what a human would
+ expect. Consider sorting user-interface strings with
+ QString::localeAwareCompare().
+*/
+
+/*!
+ \fn bool QLatin1String::operator!=(const char *other) const
+ \since 4.3
+ \overload operator!=()
+
+ The \a other const char pointer is converted to a QLatin1String using
+ the QString::fromAscii() function.
+
+ You can disable this operator by defining \c
+ QT_NO_CAST_FROM_ASCII when you compile your applications. This
+ can be useful if you want to ensure that all user-visible strings
+ go through QObject::tr(), for example.
+*/
+
+/*!
+ \fn bool QLatin1String::operator>(const QString &other) const
+
+ Returns true if this string is lexically greater than string \a
+ other; otherwise returns false.
+
+ The comparison is based exclusively on the numeric Unicode values
+ of the characters and is very fast, but is not what a human would
+ expect. Consider sorting user-interface strings with
+ QString::localeAwareCompare().
+*/
+
+/*!
+ \fn bool QLatin1String::operator>(const char *other) const
+ \since 4.3
+ \overload
+
+ The \a other const char pointer is converted to a QLatin1String using
+ the QString::fromAscii() function.
+
+ You can disable this operator by defining \c QT_NO_CAST_FROM_ASCII
+ when you compile your applications. This can be useful if you want
+ to ensure that all user-visible strings go through QObject::tr(),
+ for example.
+*/
+
+/*!
+ \fn bool QLatin1String::operator<(const QString &other) const
+
+ Returns true if this string is lexically less than the \a other
+ string; otherwise returns false.
+
+ The comparison is based exclusively on the numeric Unicode values
+ of the characters and is very fast, but is not what a human would
+ expect. Consider sorting user-interface strings using the
+ QString::localeAwareCompare() function.
+*/
+
+/*!
+ \fn bool QLatin1String::operator<(const char *other) const
+ \since 4.3
+ \overload
+
+ The \a other const char pointer is converted to a QLatin1String using
+ the QString::fromAscii() function.
+
+ You can disable this operator by defining \c
+ QT_NO_CAST_FROM_ASCII when you compile your applications. This
+ can be useful if you want to ensure that all user-visible strings
+ go through QObject::tr(), for example.
+*/
+
+/*!
+ \fn bool QLatin1String::operator>=(const QString &other) const
+
+ Returns true if this string is lexically greater than or equal
+ to string \a other; otherwise returns false.
+
+ The comparison is based exclusively on the numeric Unicode values
+ of the characters and is very fast, but is not what a human would
+ expect. Consider sorting user-interface strings with
+ QString::localeAwareCompare().
+*/
+
+/*!
+ \fn bool QLatin1String::operator>=(const char *other) const
+ \since 4.3
+ \overload
+
+ The \a other const char pointer is converted to a QLatin1String using
+ the QString::fromAscii() function.
+
+ You can disable this operator by defining \c
+ QT_NO_CAST_FROM_ASCII when you compile your applications. This
+ can be useful if you want to ensure that all user-visible strings
+ go through QObject::tr(), for example.
+*/
+
+/*! \fn bool QLatin1String::operator<=(const QString &other) const
+
+ Returns true if this string is lexically less than or equal
+ to string \a other; otherwise returns false.
+
+ The comparison is based exclusively on the numeric Unicode values
+ of the characters and is very fast, but is not what a human would
+ expect. Consider sorting user-interface strings with
+ QString::localeAwareCompare().
+*/
+
+/*!
+ \fn bool QLatin1String::operator<=(const char *other) const
+ \since 4.3
+ \overload
+
+ The \a other const char pointer is converted to a QString using
+ the QString::fromAscii() function.
+
+ You can disable this operator by defining \c
+ QT_NO_CAST_FROM_ASCII when you compile your applications. This
+ can be useful if you want to ensure that all user-visible strings
+ go through QObject::tr(), for example.
+*/
+
+
+
+/* \fn bool operator==(const QLatin1String &s1, const QLatin1String &s2)
+ \relates QLatin1String
+
+ Returns true if string \a s1 is lexically equal to string \a s2; otherwise
+ returns false.
+*/
+/* \fn bool operator!=(const QLatin1String &s1, const QLatin1String &s2)
+ \relates QLatin1String
+
+ Returns true if string \a s1 is lexically unequal to string \a s2; otherwise
+ returns false.
+*/
+/* \fn bool operator<(const QLatin1String &s1, const QLatin1String &s2)
+ \relates QLatin1String
+
+ Returns true if string \a s1 is lexically smaller than string \a s2; otherwise
+ returns false.
+*/
+/* \fn bool operator<=(const QLatin1String &s1, const QLatin1String &s2)
+ \relates QLatin1String
+
+ Returns true if string \a s1 is lexically smaller than or equal to string \a s2; otherwise
+ returns false.
+*/
+/* \fn bool operator>(const QLatin1String &s1, const QLatin1String &s2)
+ \relates QLatin1String
+
+ Returns true if string \a s1 is lexically greater than string \a s2; otherwise
+ returns false.
+*/
+/* \fn bool operator>=(const QLatin1String &s1, const QLatin1String &s2)
+ \relates QLatin1String
+
+ Returns true if string \a s1 is lexically greater than or equal to
+ string \a s2; otherwise returns false.
+*/
+
+
+#ifndef QT_NO_DATASTREAM
+/*!
+ \fn QDataStream &operator<<(QDataStream &stream, const QString &string)
+ \relates QString
+
+ Writes the given \a string to the specified \a stream.
+
+ \sa {Format of the QDataStream Operators}
+*/
+
+QDataStream &operator<<(QDataStream &out, const QString &str)
+{
+ if (out.version() == 1) {
+ out << str.toLatin1();
+ } else {
+ if (!str.isNull() || out.version() < 3) {
+ int byteOrder = out.byteOrder();
+ const QChar* ub = str.unicode();
+ static const uint auto_size = 1024;
+ char t[auto_size];
+ char *b;
+ if (str.length()*sizeof(QChar) > auto_size) {
+ b = new char[str.length()*sizeof(QChar)];
+ } else {
+ b = t;
+ }
+ int l = str.length();
+ char *c=b;
+ while (l--) {
+ if (byteOrder == QDataStream::BigEndian) {
+ *c++ = (char)ub->row();
+ *c++ = (char)ub->cell();
+ } else {
+ *c++ = (char)ub->cell();
+ *c++ = (char)ub->row();
+ }
+ ub++;
+ }
+ out.writeBytes(b, sizeof(QChar)*str.length());
+ if (str.length()*sizeof(QChar) > auto_size)
+ delete [] b;
+ } else {
+ // write null marker
+ out << (quint32)0xffffffff;
+ }
+ }
+ return out;
+}
+
+/*!
+ \fn QDataStream &operator>>(QDataStream &stream, QString &string)
+ \relates QString
+
+ Reads a string from the specified \a stream into the given \a string.
+
+ \sa {Format of the QDataStream Operators}
+*/
+
+QDataStream &operator>>(QDataStream &in, QString &str)
+{
+#ifdef QT_QSTRING_UCS_4
+#if defined(Q_CC_GNU)
+#warning "operator>> not working properly"
+#endif
+#endif
+
+ if (in.version() == 1) {
+ QByteArray l;
+ in >> l;
+ str = QString::fromLatin1(l);
+ } else {
+ quint32 bytes = 0;
+ in >> bytes; // read size of string
+ if (bytes == 0xffffffff) { // null string
+ str.clear();
+ } else if (bytes > 0) { // not empty
+ if (bytes & 0x1) {
+ str.clear();
+ in.setStatus(QDataStream::ReadCorruptData);
+ return in;
+ }
+
+ const quint32 Step = 1024 * 1024;
+ quint32 len = bytes / 2;
+ quint32 allocated = 0;
+
+ while (allocated < len) {
+ int blockSize = qMin(Step, len - allocated);
+ str.resize(allocated + blockSize);
+ if (in.readRawData(reinterpret_cast<char *>(str.data()) + allocated * 2,
+ blockSize * 2) != blockSize * 2) {
+ str.clear();
+ in.setStatus(QDataStream::ReadPastEnd);
+ return in;
+ }
+ allocated += blockSize;
+ }
+
+ if ((in.byteOrder() == QDataStream::BigEndian)
+ != (QSysInfo::ByteOrder == QSysInfo::BigEndian)) {
+ ushort *data = reinterpret_cast<ushort *>(str.data());
+ while (len--) {
+ *data = (*data >> 8) | (*data << 8);
+ ++data;
+ }
+ }
+ } else {
+ str = QLatin1String("");
+ }
+ }
+ return in;
+}
+#endif // QT_NO_DATASTREAM
+
+/*!
+ \fn void QString::setLength(int nl)
+
+ Use resize() instead.
+*/
+
+/*!
+ \fn QString QString::copy() const
+
+ Use simple assignment instead. QString is implicitly shared so if
+ a copy is modified only the copy is changed.
+*/
+
+/*!
+ \fn QString &QString::remove(QChar c, bool cs)
+
+ Use the remove(QChar, Qt::CaseSensitive) overload instead.
+*/
+
+/*!
+ \fn QString &QString::remove(const QString &s, bool cs)
+
+ Use the remove(QString, Qt::CaseSensitive) overload instead.
+*/
+
+/*!
+ \fn QString &QString::replace(QChar c, const QString &after, bool cs)
+
+ Use the replace(QChar, QString, Qt::CaseSensitive) overload instead.
+*/
+
+/*!
+ \fn QString &QString::replace(const QString &before, const QString &after, bool cs)
+
+ Use the replace(QString, QString, Qt::CaseSensitive) overload instead.
+*/
+
+/*!
+ \fn QString &QString::replace(char c, const QString &after, bool cs)
+
+ Use the replace(QChar, QString, Qt::CaseSensitive) overload instead.
+*/
+
+/*!
+ \fn QString &QString::replace(char c, const QString &after, Qt::CaseSensitivity cs)
+
+ Use the replace(QChar, QString, Qt::CaseSensitive) overload instead.
+*/
+
+/*!
+ \fn int QString::find(QChar c, int i = 0, bool cs = true) const
+
+ Use indexOf() instead.
+*/
+
+/*!
+ \fn int QString::find(const QString &s, int i = 0, bool cs = true) const
+
+ Use indexOf() instead.
+*/
+
+/*!
+ \fn int QString::findRev(QChar c, int i = -1, bool cs = true) const
+
+ Use lastIndexOf() instead.
+*/
+
+/*!
+ \fn int QString::findRev(const QString &s, int i = -1, bool cs = true) const
+
+ Use lastIndexOf() instead.
+*/
+
+/*!
+ \fn int QString::find(const QRegExp &rx, int i=0) const
+
+ Use indexOf() instead.
+*/
+
+/*!
+ \fn int QString::find(QRegExp &rx, int i=0) const
+ \internal
+ \since 4.5
+
+ Use indexOf() instead.
+*/
+
+/*!
+ \fn int QString::findRev(const QRegExp &rx, int i=-1) const
+
+ Use lastIndexOf() instead.
+*/
+
+/*!
+ \fn int QString::findRev(QRegExp &rx, int i=0) const
+ \internal
+ \since 4.5
+
+ Use lastIndexOf() instead.
+*/
+
+/*!
+ \fn QBool QString::contains(QChar c, bool cs) const
+
+ Use the contains(QChar, Qt::CaseSensitive) overload instead.
+*/
+
+/*!
+ \fn QBool QString::contains(const QString &s, bool cs) const
+
+ Use the contains(QString, Qt::CaseSensitive) overload instead.
+*/
+
+/*!
+ \fn bool QString::startsWith(const QString &s, bool cs) const
+
+ Use the startsWith(QString, Qt::CaseSensitive) overload instead.
+*/
+
+/*!
+ \fn bool QString::endsWith(const QString &s, bool cs) const
+
+ Use the endsWith(QString, Qt::CaseSensitive) overload instead.
+*/
+
+/*!
+ \fn QString QString::leftJustify(int width, QChar fill = QLatin1Char(' '), bool trunc=false) const
+
+ Use leftJustified() instead.
+*/
+
+/*!
+ \fn QString QString::rightJustify(int width, QChar fill = QLatin1Char(' '), bool trunc=false) const
+
+ Use rightJustified() instead.
+*/
+
+/*!
+ \fn QString QString::lower() const
+
+ Use toLower() instead.
+*/
+
+/*!
+ \fn QString QString::upper() const
+
+ Use toUpper() instead.
+*/
+
+/*!
+ \fn QString QString::stripWhiteSpace() const
+
+ Use trimmed() instead.
+*/
+
+/*!
+ \fn QString QString::simplifyWhiteSpace() const
+
+ Use simplified() instead.
+*/
+
+/*!
+ \fn QString &QString::setUnicodeCodes(const ushort *unicode_as_ushorts, int size)
+
+ Use setUtf16() instead.
+*/
+
+/*!
+ \fn ushort *QString::ucs2() const
+
+ Use utf16() instead.
+*/
+
+/*!
+ \fn QString QString::fromUcs2(const ushort *unicode, int size = -1)
+
+ Use fromUtf16() instead.
+*/
+
+/*!
+ \fn QString &QString::setAscii(const char *str, int len = -1)
+
+ Use fromAscii() instead.
+*/
+
+/*!
+ \fn QString &QString::setLatin1(const char *str, int len = -1)
+
+ Use fromLatin1() instead.
+*/
+
+/*!
+ \fn QChar QString::constref(uint i) const
+
+ Use at() instead.
+*/
+
+/*!
+ \fn QChar &QString::ref(uint i);
+
+ Use operator[]() instead.
+*/
+
+/*!
+ \fn QString::operator const char *() const
+
+ Use toAscii().constData() instead.
+*/
+
+/*!
+ \class QConstString
+ \brief The QConstString class is a wrapper for constant Unicode string data.
+ \compat
+
+ In Qt 4, QConstString is replaced by QString::fromRawData(), a
+ static function that constructs a QString object based on Unicode
+ string data.
+
+ Because QString::fromRawData() has slightly more stringent
+ constraints than QConstString had in Qt 3, the new QConstString
+ class takes a deep copy of the string data.
+
+ \sa QString::fromRawData()
+*/
+
+/*!
+ \fn QConstString::QConstString(const QChar *unicode, int size)
+
+ Use QString(\a unicode, \a size) or
+ QString::fromRawData(\a unicode, \a size) instead.
+*/
+
+/*!
+ \fn const QString &QConstString::string() const
+
+ Returns \c *this. Not necessary in Qt 4.
+*/
+
+
+
+/*!
+ \class QStringRef
+ \since 4.3
+ \brief The QStringRef class provides a thin wrapper around QString substrings.
+ \reentrant
+ \ingroup tools
+ \ingroup text
+
+ QStringRef provides a read-only subset of the QString API.
+
+ A string reference explicitly references a portion of a string()
+ with a given size(), starting at a specific position(). Calling
+ toString() returns a copy of the data as a real QString instance.
+
+ This class is designed to improve the performance of substring
+ handling when manipulating substrings obtained from existing QString
+ instances. QStringRef avoids the memory allocation and reference
+ counting overhead of a standard QString by simply referencing a
+ part of the original string. This can prove to be advantageous in
+ low level code, such as that used in a parser, at the expense of
+ potentially more complex code.
+
+ For most users, there are no semantic benefits to using QStringRef
+ instead of QString since QStringRef requires attention to be paid
+ to memory management issues, potentially making code more complex
+ to write and maintain.
+
+ \warning A QStringRef is only valid as long as the referenced
+ string exists. If the original string is deleted, the string
+ reference points to an invalid memory location.
+
+ We suggest that you only use this class in stable code where profiling
+ has clearly identified that performance improvements can be made by
+ replacing standard string operations with the optimized substring
+ handling provided by this class.
+
+ \sa {Implicitly Shared Classes}
+*/
+
+
+/*!
+ \fn QStringRef::QStringRef()
+
+ Constructs an empty string reference.
+*/
+
+/*! \fn QStringRef::QStringRef(const QString *string, int position, int length)
+
+Constructs a string reference to the range of characters in the given
+\a string specified by the starting \a position and \a length in characters.
+
+\warning This function exists to improve performance as much as possible,
+and performs no bounds checking. For program correctness, \a position and
+\a length must describe a valid substring of \a string.
+
+This means that the starting \a position must be positive or 0 and smaller
+than \a string's length, and \a length must be positive or 0 but smaller than
+the string's length minus the starting \a position;
+i.e, 0 <= position < string->length() and
+0 <= length <= string->length() - position must both be satisfied.
+*/
+
+/*! \fn QStringRef::QStringRef(const QString *string)
+
+Constructs a string reference to the given \a string.
+*/
+
+/*! \fn QStringRef::QStringRef(const QStringRef &other)
+
+Constructs a copy of the \a other string reference.
+ */
+/*!
+\fn QStringRef::~QStringRef()
+
+Destroys the string reference.
+
+Since this class is only used to refer to string data, and does not take
+ownership of it, no memory is freed when instances are destroyed.
+*/
+
+
+/*!
+ \fn int QStringRef::position() const
+
+ Returns the starting position in the referenced string that is referred to
+ by the string reference.
+
+ \sa size(), string()
+*/
+
+/*!
+ \fn int QStringRef::size() const
+
+ Returns the number of characters referred to by the string reference.
+ Equivalent to length() and count().
+
+ \sa position(), string()
+*/
+/*!
+ \fn int QStringRef::count() const
+ Returns the number of characters referred to by the string reference.
+ Equivalent to size() and length().
+
+ \sa position(), string()
+*/
+/*!
+ \fn int QStringRef::length() const
+ Returns the number of characters referred to by the string reference.
+ Equivalent to size() and count().
+
+ \sa position(), string()
+*/
+
+
+/*!
+ \fn bool QStringRef::isEmpty() const
+
+ Returns true if the string reference has no characters; otherwise returns
+ false.
+
+ A string reference is empty if its size is zero.
+
+ \sa size()
+*/
+
+/*!
+ \fn bool QStringRef::isNull() const
+
+ Returns true if string() returns a null pointer or a pointer to a
+ null string; otherwise returns true.
+
+ \sa size()
+*/
+
+/*!
+ \fn const QString *QStringRef::string() const
+
+ Returns a pointer to the string referred to by the string reference, or
+ 0 if it does not reference a string.
+
+ \sa unicode()
+*/
+
+
+/*!
+ \fn const QChar *QStringRef::unicode() const
+
+ Returns a Unicode representation of the string reference. Since
+ the data stems directly from the referenced string, it is not
+ null-terminated unless the string reference includes the string's
+ null terminator.
+
+ \sa string()
+*/
+
+/*!
+ \fn const QChar *QStringRef::data() const
+
+ Same as unicode().
+*/
+
+/*!
+ \fn const QChar *QStringRef::constData() const
+
+ Same as unicode().
+*/
+
+/*!
+ Returns a copy of the string reference as a QString object.
+
+ If the string reference is not a complete reference of the string
+ (meaning that position() is 0 and size() equals string()->size()),
+ this function will allocate a new string to return.
+
+ \sa string()
+*/
+
+QString QStringRef::toString() const {
+ if (!m_string)
+ return QString();
+ if (m_size && m_position == 0 && m_size == m_string->size())
+ return *m_string;
+ return QString::fromUtf16(reinterpret_cast<const ushort*>(m_string->unicode() + m_position), m_size);
+}
+
+
+/*! \relates QStringRef
+
+ Returns true if string reference \a s1 is lexically equal to string reference \a s2; otherwise
+ returns false.
+*/
+bool operator==(const QStringRef &s1,const QStringRef &s2)
+{ return (s1.size() == s2.size() &&
+ (memcmp((char*)s1.unicode(), (char*)s2.unicode(), s1.size()*sizeof(QChar))==0)); }
+
+/*! \relates QStringRef
+
+ Returns true if string \a s1 is lexically equal to string reference \a s2; otherwise
+ returns false.
+*/
+bool operator==(const QString &s1,const QStringRef &s2)
+{ return (s1.size() == s2.size() &&
+ (memcmp((char*)s1.unicode(), (char*)s2.unicode(), s1.size()*sizeof(QChar))==0)); }
+
+/*! \relates QStringRef
+
+ Returns true if string \a s1 is lexically equal to string reference \a s2; otherwise
+ returns false.
+*/
+bool operator==(const QLatin1String &s1, const QStringRef &s2)
+{
+ const ushort *uc = reinterpret_cast<const ushort *>(s2.unicode());
+ const ushort *e = uc + s2.size();
+ const uchar *c = reinterpret_cast<const uchar *>(s1.latin1());
+ if (!c)
+ return s2.isEmpty();
+
+ while (*c) {
+ if (uc == e || *uc != *c)
+ return false;
+ ++uc;
+ ++c;
+ }
+ return (uc == e);
+}
+
+/*!
+ \relates QStringRef
+
+ Returns true if string reference \a s1 is lexically less than
+ string reference \a s2; otherwise returns false.
+
+ The comparison is based exclusively on the numeric Unicode values
+ of the characters and is very fast, but is not what a human would
+ expect. Consider sorting user-interface strings using the
+ QString::localeAwareCompare() function.
+*/
+bool operator<(const QStringRef &s1,const QStringRef &s2)
+{
+ return ucstrcmp(s1.constData(), s1.length(), s2.constData(), s2.length()) < 0;
+}
+
+/*!\fn bool operator<=(const QStringRef &s1,const QStringRef &s2)
+
+ \relates QStringRef
+
+ Returns true if string reference \a s1 is lexically less than
+ or equal to string reference \a s2; otherwise returns false.
+
+ The comparison is based exclusively on the numeric Unicode values
+ of the characters and is very fast, but is not what a human would
+ expect. Consider sorting user-interface strings using the
+ QString::localeAwareCompare() function.
+*/
+
+/*!\fn bool operator>=(const QStringRef &s1,const QStringRef &s2)
+
+ \relates QStringRef
+
+ Returns true if string reference \a s1 is lexically greater than
+ or equal to string reference \a s2; otherwise returns false.
+
+ The comparison is based exclusively on the numeric Unicode values
+ of the characters and is very fast, but is not what a human would
+ expect. Consider sorting user-interface strings using the
+ QString::localeAwareCompare() function.
+*/
+
+/*!\fn bool operator>(const QStringRef &s1,const QStringRef &s2)
+
+ \relates QStringRef
+
+ Returns true if string reference \a s1 is lexically greater than
+ string reference \a s2; otherwise returns false.
+
+ The comparison is based exclusively on the numeric Unicode values
+ of the characters and is very fast, but is not what a human would
+ expect. Consider sorting user-interface strings using the
+ QString::localeAwareCompare() function.
+*/
+
+
+/*!
+ \fn const QChar QStringRef::at(int position) const
+
+ Returns the character at the given index \a position in the
+ string reference.
+
+ The \a position must be a valid index position in the string
+ (i.e., 0 <= \a position < size()).
+*/
+
+/*!
+ \fn void QStringRef::clear()
+
+ Clears the contents of the string reference by making it null and empty.
+
+ \sa isEmpty(), isNull()
+*/
+
+/*!
+ \fn QStringRef &QStringRef::operator=(const QStringRef &other)
+
+ Assigns the \a other string reference to this string reference, and
+ returns the result.
+*/
+
+/*!
+ \fn QStringRef &QStringRef::operator=(const QString *string)
+
+ Constructs a string reference to the given \a string and assigns it to
+ this string reference, returning the result.
+*/
+
+/*!
+ \typedef QString::DataPtr
+ \internal
+*/
+
+/*!
+ \fn DataPtr & QString::data_ptr()
+ \internal
+*/
+
+
+
+/*! Appends the string reference to \a string, and returns a new
+reference to the combined string data.
+ */
+QStringRef QStringRef::appendTo(QString *string) const
+{
+ if (!string)
+ return QStringRef();
+ int pos = string->size();
+ string->insert(pos, unicode(), size());
+ return QStringRef(string, pos, size());
+}
+
+/*!
+ \fn int QStringRef::compare(const QStringRef &s1, const QString &s2, Qt::CaseSensitivity cs = Qt::CaseSensitive)
+ \since 4.5
+
+ Compares the string \a s1 with the string \a s2 and returns an
+ integer less than, equal to, or greater than zero if \a s1
+ is less than, equal to, or greater than \a s2.
+
+ If \a cs is Qt::CaseSensitive, the comparison is case sensitive;
+ otherwise the comparison is case insensitive.
+*/
+
+/*!
+ \fn int QStringRef::compare(const QStringRef &s1, const QStringRef &s2, Qt::CaseSensitivity cs = Qt::CaseSensitive)
+ \since 4.5
+ \overload
+
+ Compares the string \a s1 with the string \a s2 and returns an
+ integer less than, equal to, or greater than zero if \a s1
+ is less than, equal to, or greater than \a s2.
+
+ If \a cs is Qt::CaseSensitive, the comparison is case sensitive;
+ otherwise the comparison is case insensitive.
+*/
+
+/*!
+ \fn int QStringRef::compare(const QStringRef &s1, QLatin1String s2, Qt::CaseSensitivity cs = Qt::CaseSensitive)
+ \since 4.5
+ \overload
+
+ Compares the string \a s1 with the string \a s2 and returns an
+ integer less than, equal to, or greater than zero if \a s1
+ is less than, equal to, or greater than \a s2.
+
+ If \a cs is Qt::CaseSensitive, the comparison is case sensitive;
+ otherwise the comparison is case insensitive.
+*/
+
+/*!
+ \overload
+ \fn int QStringRef::compare(const QString &other, Qt::CaseSensitivity cs = Qt::CaseSensitive) const
+ \since 4.5
+
+ Compares this string with the \a other string and returns an
+ integer less than, equal to, or greater than zero if this string
+ is less than, equal to, or greater than the \a other string.
+
+ If \a cs is Qt::CaseSensitive, the comparison is case sensitive;
+ otherwise the comparison is case insensitive.
+
+ Equivalent to \c {compare(*this, other, cs)}.
+
+ \sa QString::compare()
+*/
+
+/*!
+ \overload
+ \fn int QStringRef::compare(const QStringRef &other, Qt::CaseSensitivity cs = Qt::CaseSensitive) const
+ \since 4.5
+
+ Compares this string with the \a other string and returns an
+ integer less than, equal to, or greater than zero if this string
+ is less than, equal to, or greater than the \a other string.
+
+ If \a cs is Qt::CaseSensitive, the comparison is case sensitive;
+ otherwise the comparison is case insensitive.
+
+ Equivalent to \c {compare(*this, other, cs)}.
+
+ \sa QString::compare()
+*/
+
+/*!
+ \overload
+ \fn int QStringRef::compare(QLatin1String other, Qt::CaseSensitivity cs = Qt::CaseSensitive) const
+ \since 4.5
+
+ Compares this string with the \a other string and returns an
+ integer less than, equal to, or greater than zero if this string
+ is less than, equal to, or greater than the \a other string.
+
+ If \a cs is Qt::CaseSensitive, the comparison is case sensitive;
+ otherwise the comparison is case insensitive.
+
+ Equivalent to \c {compare(*this, other, cs)}.
+
+ \sa QString::compare()
+*/
+
+/*!
+ \fn int QStringRef::localeAwareCompare(const QStringRef &s1, const QString & s2)
+ \since 4.5
+
+ Compares \a s1 with \a s2 and returns an integer less than, equal
+ to, or greater than zero if \a s1 is less than, equal to, or
+ greater than \a s2.
+
+ The comparison is performed in a locale- and also
+ platform-dependent manner. Use this function to present sorted
+ lists of strings to the user.
+
+ On Mac OS X, this function compares according the
+ "Order for sorted lists" setting in the International prefereces panel.
+
+ \sa compare(), QTextCodec::locale()
+*/
+
+/*!
+ \fn int QStringRef::localeAwareCompare(const QStringRef &s1, const QStringRef & s2)
+ \since 4.5
+ \overload
+
+ Compares \a s1 with \a s2 and returns an integer less than, equal
+ to, or greater than zero if \a s1 is less than, equal to, or
+ greater than \a s2.
+
+ The comparison is performed in a locale- and also
+ platform-dependent manner. Use this function to present sorted
+ lists of strings to the user.
+
+*/
+
+/*!
+ \fn int QStringRef::localeAwareCompare(const QString &other) const
+ \since 4.5
+ \overload
+
+ Compares this string with the \a other string and returns an
+ integer less than, equal to, or greater than zero if this string
+ is less than, equal to, or greater than the \a other string.
+
+ The comparison is performed in a locale- and also
+ platform-dependent manner. Use this function to present sorted
+ lists of strings to the user.
+*/
+
+/*!
+ \fn int QStringRef::localeAwareCompare(const QStringRef &other) const
+ \since 4.5
+ \overload
+
+ Compares this string with the \a other string and returns an
+ integer less than, equal to, or greater than zero if this string
+ is less than, equal to, or greater than the \a other string.
+
+ The comparison is performed in a locale- and also
+ platform-dependent manner. Use this function to present sorted
+ lists of strings to the user.
+*/
+
+/*!
+ \fn QString &QString::append(const QStringRef &reference)
+ \since 4.4
+
+ Appends the given string \a reference to this string and returns the result.
+ */
+QString &QString::append(const QStringRef &str)
+{
+ if (str.string() == this) {
+ str.appendTo(this);
+ } else if (str.string()) {
+ int oldSize = size();
+ resize(oldSize + str.size());
+ memcpy(data() + oldSize, str.unicode(), str.size() * sizeof(QChar));
+ }
+ return *this;
+}
+
+/*!
+ \since 4.4
+
+ Returns a substring reference to the \a n leftmost characters
+ of the string.
+
+ If \a n is greater than size() or less than zero, a reference to the entire
+ string is returned.
+
+ \snippet doc/src/snippets/qstring/main.cpp leftRef
+
+ \sa left(), rightRef(), midRef(), startsWith()
+*/
+QStringRef QString::leftRef(int n) const
+{
+ if (n >= d->size || n < 0)
+ n = d->size;
+ return QStringRef(this, 0, n);
+}
+
+/*!
+ \since 4.4
+
+ Returns a substring reference to the \a n rightmost characters
+ of the string.
+
+ If \a n is greater than size() or less than zero, a reference to the entire
+ string is returned.
+
+ \snippet doc/src/snippets/qstring/main.cpp rightRef
+
+ \sa right(), leftRef(), midRef(), endsWith()
+*/
+QStringRef QString::rightRef(int n) const
+{
+ if (n >= d->size || n < 0)
+ n = d->size;
+ return QStringRef(this, d->size - n, n);
+}
+
+/*!
+ \since 4.4
+
+ Returns a substring reference to \a n characters of this string,
+ starting at the specified \a position.
+
+ If the \a position exceeds the length of the string, an empty
+ reference is returned.
+
+ If there are less than \a n characters available in the string,
+ starting at the given \a position, or if \a n is -1 (default), the
+ function returns all characters from the specified \a position
+ onwards.
+
+ Example:
+
+ \snippet doc/src/snippets/qstring/main.cpp midRef
+
+ \sa mid(), leftRef(), rightRef()
+*/
+
+QStringRef QString::midRef(int position, int n) const
+{
+ if (d == &shared_null || position >= d->size)
+ return QStringRef();
+ if (n < 0)
+ n = d->size - position;
+ if (position < 0) {
+ n += position;
+ position = 0;
+ }
+ if (n + position > d->size)
+ n = d->size - position;
+ return QStringRef(this, position, n);
+}
+
+QT_END_NAMESPACE
diff --git a/src/corelib/tools/qstring.h b/src/corelib/tools/qstring.h
new file mode 100644
index 0000000000..1493dcefd2
--- /dev/null
+++ b/src/corelib/tools/qstring.h
@@ -0,0 +1,1234 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSTRING_H
+#define QSTRING_H
+
+#include <QtCore/qchar.h>
+#include <QtCore/qbytearray.h>
+#include <QtCore/qatomic.h>
+#include <QtCore/qnamespace.h>
+#ifdef QT_INCLUDE_COMPAT
+#include <Qt3Support/q3cstring.h>
+#endif
+
+#ifndef QT_NO_STL
+# if defined (Q_CC_MSVC_NET) && _MSC_VER < 1310 // Avoids nasty warning for xlocale, line 450
+# pragma warning (push)
+# pragma warning (disable : 4189)
+# include <string>
+# pragma warning (pop)
+# else
+# include <string>
+# endif
+
+# ifndef QT_NO_STL_WCHAR
+// workaround for some headers not typedef'ing std::wstring
+typedef std::basic_string<wchar_t> QStdWString;
+# endif // QT_NO_STL_WCHAR
+
+#endif // QT_NO_STL
+
+#include <stdarg.h>
+
+#ifdef truncate
+#error qstring.h must be included before any header file that defines truncate
+#endif
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Core)
+
+class QCharRef;
+class QRegExp;
+class QStringList;
+class QTextCodec;
+class QLatin1String;
+class QStringRef;
+template <typename T> class QVector;
+
+class Q_CORE_EXPORT QString
+{
+public:
+ inline QString();
+ QString(const QChar *unicode, int size);
+ QString(QChar c);
+ QString(int size, QChar c);
+ inline QString(const QLatin1String &latin1);
+ inline QString(const QString &);
+ inline ~QString();
+ QString &operator=(QChar c);
+ QString &operator=(const QString &);
+ inline QString &operator=(const QLatin1String &);
+
+ inline int size() const { return d->size; }
+ inline int count() const { return d->size; }
+ inline int length() const;
+ inline bool isEmpty() const;
+ void resize(int size);
+
+ QString &fill(QChar c, int size = -1);
+ void truncate(int pos);
+ void chop(int n);
+
+ int capacity() const;
+ inline void reserve(int size);
+ inline void squeeze() { if (d->size < d->alloc) realloc(); d->capacity = 0;}
+
+ inline const QChar *unicode() const;
+ inline QChar *data();
+ inline const QChar *data() const;
+ inline const QChar *constData() const;
+
+ inline void detach();
+ inline bool isDetached() const;
+ void clear();
+
+ inline const QChar at(int i) const;
+ const QChar operator[](int i) const;
+ QCharRef operator[](int i);
+ const QChar operator[](uint i) const;
+ QCharRef operator[](uint i);
+
+ QString arg(qlonglong a, int fieldwidth=0, int base=10,
+ const QChar &fillChar = QLatin1Char(' ')) const Q_REQUIRED_RESULT;
+ QString arg(qulonglong a, int fieldwidth=0, int base=10,
+ const QChar &fillChar = QLatin1Char(' ')) const Q_REQUIRED_RESULT;
+ QString arg(long a, int fieldwidth=0, int base=10,
+ const QChar &fillChar = QLatin1Char(' ')) const Q_REQUIRED_RESULT;
+ QString arg(ulong a, int fieldwidth=0, int base=10,
+ const QChar &fillChar = QLatin1Char(' ')) const Q_REQUIRED_RESULT;
+ QString arg(int a, int fieldWidth = 0, int base = 10,
+ const QChar &fillChar = QLatin1Char(' ')) const Q_REQUIRED_RESULT;
+ QString arg(uint a, int fieldWidth = 0, int base = 10,
+ const QChar &fillChar = QLatin1Char(' ')) const Q_REQUIRED_RESULT;
+ QString arg(short a, int fieldWidth = 0, int base = 10,
+ const QChar &fillChar = QLatin1Char(' ')) const Q_REQUIRED_RESULT;
+ QString arg(ushort a, int fieldWidth = 0, int base = 10,
+ const QChar &fillChar = QLatin1Char(' ')) const Q_REQUIRED_RESULT;
+ QString arg(double a, int fieldWidth = 0, char fmt = 'g', int prec = -1,
+ const QChar &fillChar = QLatin1Char(' ')) const Q_REQUIRED_RESULT;
+ QString arg(char a, int fieldWidth = 0,
+ const QChar &fillChar = QLatin1Char(' ')) const Q_REQUIRED_RESULT;
+ QString arg(QChar a, int fieldWidth = 0,
+ const QChar &fillChar = QLatin1Char(' ')) const Q_REQUIRED_RESULT;
+ QString arg(const QString &a, int fieldWidth = 0,
+ const QChar &fillChar = QLatin1Char(' ')) const Q_REQUIRED_RESULT;
+ QString arg(const QString &a1, const QString &a2) const Q_REQUIRED_RESULT;
+ QString arg(const QString &a1, const QString &a2, const QString &a3) const Q_REQUIRED_RESULT;
+ QString arg(const QString &a1, const QString &a2, const QString &a3,
+ const QString &a4) const Q_REQUIRED_RESULT;
+ QString arg(const QString &a1, const QString &a2, const QString &a3,
+ const QString &a4, const QString &a5) const Q_REQUIRED_RESULT;
+ QString arg(const QString &a1, const QString &a2, const QString &a3,
+ const QString &a4, const QString &a5, const QString &a6) const Q_REQUIRED_RESULT;
+ QString arg(const QString &a1, const QString &a2, const QString &a3,
+ const QString &a4, const QString &a5, const QString &a6,
+ const QString &a7) const Q_REQUIRED_RESULT;
+ QString arg(const QString &a1, const QString &a2, const QString &a3,
+ const QString &a4, const QString &a5, const QString &a6,
+ const QString &a7, const QString &a8) const Q_REQUIRED_RESULT;
+ QString arg(const QString &a1, const QString &a2, const QString &a3,
+ const QString &a4, const QString &a5, const QString &a6,
+ const QString &a7, const QString &a8, const QString &a9) const Q_REQUIRED_RESULT;
+
+ QString &vsprintf(const char *format, va_list ap)
+#if defined(Q_CC_GNU) && !defined(__INSURE__)
+ __attribute__ ((format (printf, 2, 0)))
+#endif
+ ;
+ QString &sprintf(const char *format, ...)
+#if defined(Q_CC_GNU) && !defined(__INSURE__)
+ __attribute__ ((format (printf, 2, 3)))
+#endif
+ ;
+
+ int indexOf(QChar c, int from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
+ int indexOf(const QString &s, int from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
+ int indexOf(const QLatin1String &s, int from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
+ int lastIndexOf(QChar c, int from = -1, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
+ int lastIndexOf(const QString &s, int from = -1, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
+ int lastIndexOf(const QLatin1String &s, int from = -1, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
+
+ inline QBool contains(QChar c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
+ inline QBool contains(const QString &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
+ int count(QChar c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
+ int count(const QString &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
+
+#ifndef QT_NO_REGEXP
+ int indexOf(const QRegExp &, int from = 0) const;
+ int lastIndexOf(const QRegExp &, int from = -1) const;
+ inline QBool contains(const QRegExp &rx) const { return QBool(indexOf(rx) != -1); }
+ int count(const QRegExp &) const;
+
+ int indexOf(QRegExp &, int from = 0) const;
+ int lastIndexOf(QRegExp &, int from = -1) const;
+ inline QBool contains(QRegExp &rx) const { return QBool(indexOf(rx) != -1); }
+#endif
+
+ enum SectionFlag {
+ SectionDefault = 0x00,
+ SectionSkipEmpty = 0x01,
+ SectionIncludeLeadingSep = 0x02,
+ SectionIncludeTrailingSep = 0x04,
+ SectionCaseInsensitiveSeps = 0x08
+ };
+ Q_DECLARE_FLAGS(SectionFlags, SectionFlag)
+
+ QString section(QChar sep, int start, int end = -1, SectionFlags flags = SectionDefault) const;
+ QString section(const QString &in_sep, int start, int end = -1, SectionFlags flags = SectionDefault) const;
+#ifndef QT_NO_REGEXP
+ QString section(const QRegExp &reg, int start, int end = -1, SectionFlags flags = SectionDefault) const;
+#endif
+
+ QString left(int n) const Q_REQUIRED_RESULT;
+ QString right(int n) const Q_REQUIRED_RESULT;
+ QString mid(int position, int n = -1) const Q_REQUIRED_RESULT;
+ QStringRef leftRef(int n) const Q_REQUIRED_RESULT;
+ QStringRef rightRef(int n) const Q_REQUIRED_RESULT;
+ QStringRef midRef(int position, int n = -1) const Q_REQUIRED_RESULT;
+
+ bool startsWith(const QString &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
+ bool startsWith(const QLatin1String &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
+ bool startsWith(const QChar &c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
+ bool endsWith(const QString &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
+ bool endsWith(const QLatin1String &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
+ bool endsWith(const QChar &c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
+
+ QString leftJustified(int width, QChar fill = QLatin1Char(' '), bool trunc = false) const Q_REQUIRED_RESULT;
+ QString rightJustified(int width, QChar fill = QLatin1Char(' '), bool trunc = false) const Q_REQUIRED_RESULT;
+
+ QString toLower() const Q_REQUIRED_RESULT;
+ QString toUpper() const Q_REQUIRED_RESULT;
+ QString toCaseFolded() const Q_REQUIRED_RESULT;
+
+ QString trimmed() const Q_REQUIRED_RESULT;
+ QString simplified() const Q_REQUIRED_RESULT;
+
+ QString &insert(int i, QChar c);
+ QString &insert(int i, const QChar *uc, int len);
+ inline QString &insert(int i, const QString &s) { return insert(i, s.constData(), s.length()); }
+ QString &insert(int i, const QLatin1String &s);
+ QString &append(QChar c);
+ QString &append(const QString &s);
+ QString &append(const QStringRef &s);
+ QString &append(const QLatin1String &s);
+ inline QString &prepend(QChar c) { return insert(0, c); }
+ inline QString &prepend(const QString &s) { return insert(0, s); }
+ inline QString &prepend(const QLatin1String &s) { return insert(0, s); }
+
+ inline QString &operator+=(QChar c) {
+ if (d->ref != 1 || d->size + 1 > d->alloc)
+ realloc(grow(d->size + 1));
+ d->data[d->size++] = c.unicode();
+ d->data[d->size] = '\0';
+ return *this;
+ }
+
+ inline QString &operator+=(QChar::SpecialCharacter c) { return append(QChar(c)); }
+ inline QString &operator+=(const QString &s) { return append(s); }
+ inline QString &operator+=(const QStringRef &s) { return append(s); }
+ inline QString &operator+=(const QLatin1String &s) { return append(s); }
+
+ QString &remove(int i, int len);
+ QString &remove(QChar c, Qt::CaseSensitivity cs = Qt::CaseSensitive);
+ QString &remove(const QString &s, Qt::CaseSensitivity cs = Qt::CaseSensitive);
+ QString &replace(int i, int len, QChar after);
+ QString &replace(int i, int len, const QChar *s, int slen);
+ QString &replace(int i, int len, const QString &after);
+ QString &replace(QChar before, QChar after, Qt::CaseSensitivity cs = Qt::CaseSensitive);
+ QString &replace(const QChar *before, int blen, const QChar *after, int alen, Qt::CaseSensitivity cs = Qt::CaseSensitive);
+ QString &replace(const QLatin1String &before, const QLatin1String &after, Qt::CaseSensitivity cs = Qt::CaseSensitive);
+ QString &replace(const QLatin1String &before, const QString &after, Qt::CaseSensitivity cs = Qt::CaseSensitive);
+ QString &replace(const QString &before, const QLatin1String &after, Qt::CaseSensitivity cs = Qt::CaseSensitive);
+ QString &replace(const QString &before, const QString &after,
+ Qt::CaseSensitivity cs = Qt::CaseSensitive);
+ QString &replace(QChar c, const QString &after, Qt::CaseSensitivity cs = Qt::CaseSensitive);
+ QString &replace(QChar c, const QLatin1String &after, Qt::CaseSensitivity cs = Qt::CaseSensitive);
+#ifndef QT_NO_REGEXP
+ QString &replace(const QRegExp &rx, const QString &after);
+ inline QString &remove(const QRegExp &rx)
+ { return replace(rx, QString()); }
+#endif
+
+ enum SplitBehavior { KeepEmptyParts, SkipEmptyParts };
+
+ QStringList split(const QString &sep, SplitBehavior behavior = KeepEmptyParts,
+ Qt::CaseSensitivity cs = Qt::CaseSensitive) const Q_REQUIRED_RESULT;
+ QStringList split(const QChar &sep, SplitBehavior behavior = KeepEmptyParts,
+ Qt::CaseSensitivity cs = Qt::CaseSensitive) const Q_REQUIRED_RESULT;
+#ifndef QT_NO_REGEXP
+ QStringList split(const QRegExp &sep, SplitBehavior behavior = KeepEmptyParts) const Q_REQUIRED_RESULT;
+#endif
+
+ enum NormalizationForm {
+ NormalizationForm_D,
+ NormalizationForm_C,
+ NormalizationForm_KD,
+ NormalizationForm_KC
+ };
+ QString normalized(NormalizationForm mode) const Q_REQUIRED_RESULT;
+ QString normalized(NormalizationForm mode, QChar::UnicodeVersion version) const Q_REQUIRED_RESULT;
+
+ QString repeated(int times) const;
+
+ const ushort *utf16() const;
+
+ QByteArray toAscii() const Q_REQUIRED_RESULT;
+ QByteArray toLatin1() const Q_REQUIRED_RESULT;
+ QByteArray toUtf8() const Q_REQUIRED_RESULT;
+ QByteArray toLocal8Bit() const Q_REQUIRED_RESULT;
+ QVector<uint> toUcs4() const Q_REQUIRED_RESULT;
+
+ static QString fromAscii(const char *, int size = -1);
+ static QString fromLatin1(const char *, int size = -1);
+ static QString fromUtf8(const char *, int size = -1);
+ static QString fromLocal8Bit(const char *, int size = -1);
+ static QString fromUtf16(const ushort *, int size = -1);
+ static QString fromUcs4(const uint *, int size = -1);
+ static QString fromRawData(const QChar *, int size);
+
+ int toWCharArray(wchar_t *array) const;
+ static QString fromWCharArray(const wchar_t *, int size = -1);
+
+ QString &setUnicode(const QChar *unicode, int size);
+ inline QString &setUtf16(const ushort *utf16, int size);
+
+ // ### Qt 5: merge these two functions
+ int compare(const QString &s) const;
+ int compare(const QString &s, Qt::CaseSensitivity cs) const;
+
+ int compare(const QLatin1String &other, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
+
+ // ### Qt 5: merge these two functions
+ static inline int compare(const QString &s1, const QString &s2)
+ { return s1.compare(s2); }
+ static inline int compare(const QString &s1, const QString &s2, Qt::CaseSensitivity cs)
+ { return s1.compare(s2, cs); }
+
+ static inline int compare(const QString& s1, const QLatin1String &s2,
+ Qt::CaseSensitivity cs = Qt::CaseSensitive)
+ { return s1.compare(s2, cs); }
+ static inline int compare(const QLatin1String& s1, const QString &s2,
+ Qt::CaseSensitivity cs = Qt::CaseSensitive)
+ { return -s2.compare(s1, cs); }
+
+ int compare(const QStringRef &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
+ static int compare(const QString &s1, const QStringRef &s2,
+ Qt::CaseSensitivity = Qt::CaseSensitive);
+
+ int localeAwareCompare(const QString& s) const;
+ static int localeAwareCompare(const QString& s1, const QString& s2)
+ { return s1.localeAwareCompare(s2); }
+
+ int localeAwareCompare(const QStringRef &s) const;
+ static int localeAwareCompare(const QString& s1, const QStringRef& s2);
+
+ short toShort(bool *ok=0, int base=10) const;
+ ushort toUShort(bool *ok=0, int base=10) const;
+ int toInt(bool *ok=0, int base=10) const;
+ uint toUInt(bool *ok=0, int base=10) const;
+ long toLong(bool *ok=0, int base=10) const;
+ ulong toULong(bool *ok=0, int base=10) const;
+ qlonglong toLongLong(bool *ok=0, int base=10) const;
+ qulonglong toULongLong(bool *ok=0, int base=10) const;
+ float toFloat(bool *ok=0) const;
+ double toDouble(bool *ok=0) const;
+
+ QString &setNum(short, int base=10);
+ QString &setNum(ushort, int base=10);
+ QString &setNum(int, int base=10);
+ QString &setNum(uint, int base=10);
+ QString &setNum(long, int base=10);
+ QString &setNum(ulong, int base=10);
+ QString &setNum(qlonglong, int base=10);
+ QString &setNum(qulonglong, int base=10);
+ QString &setNum(float, char f='g', int prec=6);
+ QString &setNum(double, char f='g', int prec=6);
+
+ static QString number(int, int base=10);
+ static QString number(uint, int base=10);
+ static QString number(long, int base=10);
+ static QString number(ulong, int base=10);
+ static QString number(qlonglong, int base=10);
+ static QString number(qulonglong, int base=10);
+ static QString number(double, char f='g', int prec=6);
+
+ bool operator==(const QString &s) const;
+ bool operator<(const QString &s) const;
+ inline bool operator>(const QString &s) const { return s < *this; }
+ inline bool operator!=(const QString &s) const { return !operator==(s); }
+ inline bool operator<=(const QString &s) const { return !operator>(s); }
+ inline bool operator>=(const QString &s) const { return !operator<(s); }
+
+ bool operator==(const QLatin1String &s) const;
+ bool operator<(const QLatin1String &s) const;
+ bool operator>(const QLatin1String &s) const;
+ inline bool operator!=(const QLatin1String &s) const { return !operator==(s); }
+ inline bool operator<=(const QLatin1String &s) const { return !operator>(s); }
+ inline bool operator>=(const QLatin1String &s) const { return !operator<(s); }
+
+ // ASCII compatibility
+#ifndef QT_NO_CAST_FROM_ASCII
+ inline QT_ASCII_CAST_WARN_CONSTRUCTOR QString(const char *ch) : d(fromAscii_helper(ch))
+ {}
+ inline QT_ASCII_CAST_WARN_CONSTRUCTOR QString(const QByteArray &a)
+ : d(fromAscii_helper(a.constData(), qstrnlen(a.constData(), a.size())))
+ {}
+ inline QT_ASCII_CAST_WARN QString &operator=(const char *ch)
+ { return (*this = fromAscii(ch)); }
+ inline QT_ASCII_CAST_WARN QString &operator=(const QByteArray &a)
+ { return (*this = fromAscii(a.constData(), qstrnlen(a.constData(), a.size()))); }
+ inline QT_ASCII_CAST_WARN QString &operator=(char c)
+ { return (*this = QChar::fromAscii(c)); }
+
+ // these are needed, so it compiles with STL support enabled
+ inline QT_ASCII_CAST_WARN QString &prepend(const char *s)
+ { return prepend(QString::fromAscii(s)); }
+ inline QT_ASCII_CAST_WARN QString &prepend(const QByteArray &s)
+ { return prepend(QString::fromAscii(s.constData(), qstrnlen(s.constData(), s.size()))); }
+ inline QT_ASCII_CAST_WARN QString &append(const char *s)
+ { return append(QString::fromAscii(s)); }
+ inline QT_ASCII_CAST_WARN QString &append(const QByteArray &s)
+ { return append(QString::fromAscii(s.constData(), qstrnlen(s.constData(), s.size()))); }
+ inline QT_ASCII_CAST_WARN QString &operator+=(const char *s)
+ { return append(QString::fromAscii(s)); }
+ inline QT_ASCII_CAST_WARN QString &operator+=(const QByteArray &s)
+ { return append(QString::fromAscii(s.constData(), qstrnlen(s.constData(), s.size()))); }
+ inline QT_ASCII_CAST_WARN QString &operator+=(char c)
+ { return append(QChar::fromAscii(c)); }
+
+ inline QT_ASCII_CAST_WARN bool operator==(const char *s) const;
+ inline QT_ASCII_CAST_WARN bool operator!=(const char *s) const;
+ inline QT_ASCII_CAST_WARN bool operator<(const char *s) const;
+ inline QT_ASCII_CAST_WARN bool operator<=(const char *s2) const;
+ inline QT_ASCII_CAST_WARN bool operator>(const char *s2) const;
+ inline QT_ASCII_CAST_WARN bool operator>=(const char *s2) const;
+
+ inline QT_ASCII_CAST_WARN bool operator==(const QByteArray &s) const;
+ inline QT_ASCII_CAST_WARN bool operator!=(const QByteArray &s) const;
+ inline QT_ASCII_CAST_WARN bool operator<(const QByteArray &s) const
+ { return *this < QString::fromAscii(s.constData(), s.size()); }
+ inline QT_ASCII_CAST_WARN bool operator>(const QByteArray &s) const
+ { return *this > QString::fromAscii(s.constData(), s.size()); }
+ inline QT_ASCII_CAST_WARN bool operator<=(const QByteArray &s) const
+ { return *this <= QString::fromAscii(s.constData(), s.size()); }
+ inline QT_ASCII_CAST_WARN bool operator>=(const QByteArray &s) const
+ { return *this >= QString::fromAscii(s.constData(), s.size()); }
+#endif
+
+ typedef QChar *iterator;
+ typedef const QChar *const_iterator;
+ typedef iterator Iterator;
+ typedef const_iterator ConstIterator;
+ iterator begin();
+ const_iterator begin() const;
+ const_iterator constBegin() const;
+ iterator end();
+ const_iterator end() const;
+ const_iterator constEnd() const;
+
+ // STL compatibility
+ inline void push_back(QChar c) { append(c); }
+ inline void push_back(const QString &s) { append(s); }
+ inline void push_front(QChar c) { prepend(c); }
+ inline void push_front(const QString &s) { prepend(s); }
+
+#ifndef QT_NO_STL
+ static inline QString fromStdString(const std::string &s);
+ inline std::string toStdString() const;
+# ifdef qdoc
+ static inline QString fromStdWString(const std::wstring &s);
+ inline std::wstring toStdWString() const;
+# else
+# ifndef QT_NO_STL_WCHAR
+ static inline QString fromStdWString(const QStdWString &s);
+ inline QStdWString toStdWString() const;
+# endif // QT_NO_STL_WCHAR
+# endif // qdoc
+#endif
+
+ // compatibility
+ struct Null { };
+ static const Null null;
+ inline QString(const Null &): d(&shared_null) { d->ref.ref(); }
+ inline QString &operator=(const Null &) { *this = QString(); return *this; }
+ inline bool isNull() const { return d == &shared_null; }
+
+#ifdef QT3_SUPPORT
+ inline QT3_SUPPORT const char *ascii() const { return ascii_helper(); }
+ inline QT3_SUPPORT const char *latin1() const { return latin1_helper(); }
+ inline QT3_SUPPORT QByteArray utf8() const { return toUtf8(); }
+ inline QT3_SUPPORT QByteArray local8Bit() const{ return toLocal8Bit(); }
+ inline QT3_SUPPORT void setLength(int nl) { resize(nl); }
+ inline QT3_SUPPORT QString copy() const { return *this; }
+ inline QT3_SUPPORT QString &remove(QChar c, bool cs)
+ { return remove(c, cs?Qt::CaseSensitive:Qt::CaseInsensitive); }
+ inline QT3_SUPPORT QString &remove(const QString &s, bool cs)
+ { return remove(s, cs?Qt::CaseSensitive:Qt::CaseInsensitive); }
+ inline QT3_SUPPORT QString &replace(QChar c, const QString &after, bool cs)
+ { return replace(c, after, cs?Qt::CaseSensitive:Qt::CaseInsensitive); }
+ inline QT3_SUPPORT QString &replace(const QString &before, const QString &after, bool cs)
+ { return replace(before, after, cs?Qt::CaseSensitive:Qt::CaseInsensitive); }
+#ifndef QT_NO_CAST_FROM_ASCII
+ inline QT3_SUPPORT QString &replace(char c, const QString &after, bool cs)
+ { return replace(QChar::fromAscii(c), after, cs ? Qt::CaseSensitive : Qt::CaseInsensitive); }
+ // strange overload, required to avoid GCC 3.3 error
+ inline QT3_SUPPORT QString &replace(char c, const QString &after, Qt::CaseSensitivity cs)
+ { return replace(QChar::fromAscii(c), after, cs ? Qt::CaseSensitive : Qt::CaseInsensitive); }
+#endif
+ inline QT3_SUPPORT int find(QChar c, int i = 0, bool cs = true) const
+ { return indexOf(c, i, cs?Qt::CaseSensitive:Qt::CaseInsensitive); }
+ inline QT3_SUPPORT int find(const QString &s, int i = 0, bool cs = true) const
+ { return indexOf(s, i, cs?Qt::CaseSensitive:Qt::CaseInsensitive); }
+ inline QT3_SUPPORT int findRev(QChar c, int i = -1, bool cs = true) const
+ { return lastIndexOf(c, i, cs?Qt::CaseSensitive:Qt::CaseInsensitive); }
+ inline QT3_SUPPORT int findRev(const QString &s, int i = -1, bool cs = true) const
+ { return lastIndexOf(s, i, cs?Qt::CaseSensitive:Qt::CaseInsensitive); }
+#ifndef QT_NO_REGEXP
+ inline QT3_SUPPORT int find(const QRegExp &rx, int i=0) const
+ { return indexOf(rx, i); }
+ inline QT3_SUPPORT int findRev(const QRegExp &rx, int i=-1) const
+ { return lastIndexOf(rx, i); }
+ inline QT3_SUPPORT int find(QRegExp &rx, int i=0) const
+ { return indexOf(rx, i); }
+ inline QT3_SUPPORT int findRev(QRegExp &rx, int i=-1) const
+ { return lastIndexOf(rx, i); }
+#endif
+ inline QT3_SUPPORT QBool contains(QChar c, bool cs) const
+ { return contains(c, cs?Qt::CaseSensitive:Qt::CaseInsensitive); }
+ inline QT3_SUPPORT QBool contains(const QString &s, bool cs) const
+ { return contains(s, cs?Qt::CaseSensitive:Qt::CaseInsensitive); }
+ inline QT3_SUPPORT bool startsWith(const QString &s, bool cs) const
+ { return startsWith(s, cs?Qt::CaseSensitive:Qt::CaseInsensitive); }
+ inline QT3_SUPPORT bool endsWith(const QString &s, bool cs) const
+ { return endsWith(s, cs?Qt::CaseSensitive:Qt::CaseInsensitive); }
+ inline QT3_SUPPORT QChar constref(uint i) const
+ { return at(i); }
+ QT3_SUPPORT QChar &ref(uint i);
+ inline QT3_SUPPORT QString leftJustify(int width, QChar aFill = QLatin1Char(' '), bool trunc=false) const
+ { return leftJustified(width, aFill, trunc); }
+ inline QT3_SUPPORT QString rightJustify(int width, QChar aFill = QLatin1Char(' '), bool trunc=false) const
+ { return rightJustified(width, aFill, trunc); }
+ inline QT3_SUPPORT QString lower() const { return toLower(); }
+ inline QT3_SUPPORT QString upper() const { return toUpper(); }
+ inline QT3_SUPPORT QString stripWhiteSpace() const { return trimmed(); }
+ inline QT3_SUPPORT QString simplifyWhiteSpace() const { return simplified(); }
+ inline QT3_SUPPORT QString &setUnicodeCodes(const ushort *unicode_as_ushorts, int aSize)
+ { return setUtf16(unicode_as_ushorts, aSize); }
+ inline QT3_SUPPORT const ushort *ucs2() const { return utf16(); }
+ inline static QT3_SUPPORT QString fromUcs2(const ushort *unicode, int size = -1)
+ { return fromUtf16(unicode, size); }
+ inline QT3_SUPPORT QString &setAscii(const char *str, int len = -1)
+ { *this = fromAscii(str, len); return *this; }
+ inline QT3_SUPPORT QString &setLatin1(const char *str, int len = -1)
+ { *this = fromLatin1(str, len); return *this; }
+protected:
+ friend class QObject;
+ const char *ascii_helper() const;
+ const char *latin1_helper() const;
+public:
+#ifndef QT_NO_CAST_TO_ASCII
+ inline QT3_SUPPORT operator const char *() const { return ascii_helper(); }
+private:
+ QT3_SUPPORT operator QNoImplicitBoolCast() const;
+public:
+#endif
+#endif
+
+ bool isSimpleText() const { if (!d->clean) updateProperties(); return d->simpletext; }
+ bool isRightToLeft() const { if (!d->clean) updateProperties(); return d->righttoleft; }
+
+private:
+#if defined(QT_NO_CAST_FROM_ASCII) && !defined(Q_NO_DECLARED_NOT_DEFINED)
+ QString &operator+=(const char *s);
+ QString &operator+=(const QByteArray &s);
+ QString(const char *ch);
+ QString(const QByteArray &a);
+ QString &operator=(const char *ch);
+ QString &operator=(const QByteArray &a);
+#endif
+
+ struct Data {
+ QBasicAtomicInt ref;
+ int alloc, size;
+ ushort *data;
+ ushort clean : 1;
+ ushort simpletext : 1;
+ ushort righttoleft : 1;
+ ushort asciiCache : 1;
+ ushort capacity : 1;
+ ushort reserved : 11;
+ ushort array[1];
+ };
+ static Data shared_null;
+ static Data shared_empty;
+ Data *d;
+ QString(Data *dd, int /*dummy*/) : d(dd) {}
+#ifndef QT_NO_TEXTCODEC
+ static QTextCodec *codecForCStrings;
+#endif
+ static int grow(int);
+ static void free(Data *);
+ void realloc();
+ void realloc(int alloc);
+ void expand(int i);
+ void updateProperties() const;
+ QString multiArg(int numArgs, const QString **args) const;
+ static int compare_helper(const QChar *data1, int length1,
+ const QChar *data2, int length2,
+ Qt::CaseSensitivity cs = Qt::CaseSensitive);
+ static int compare_helper(const QChar *data1, int length1,
+ QLatin1String s2,
+ Qt::CaseSensitivity cs = Qt::CaseSensitive);
+ static int localeAwareCompare_helper(const QChar *data1, int length1,
+ const QChar *data2, int length2);
+ static Data *fromLatin1_helper(const char *str, int size = -1);
+ static Data *fromAscii_helper(const char *str, int size = -1);
+ void replace_helper(uint *indices, int nIndices, int blen, const QChar *after, int alen);
+ friend class QCharRef;
+ friend class QTextCodec;
+ friend class QStringRef;
+ friend inline bool qStringComparisonHelper(const QString &s1, const char *s2);
+ friend inline bool qStringComparisonHelper(const QStringRef &s1, const char *s2);
+public:
+ typedef Data * DataPtr;
+ inline DataPtr &data_ptr() { return d; }
+};
+
+
+class Q_CORE_EXPORT QLatin1String
+{
+public:
+ inline explicit QLatin1String(const char *s) : chars(s) {}
+ inline QLatin1String &operator=(const QLatin1String &other)
+ { chars = other.chars; return *this; }
+
+ inline const char *latin1() const { return chars; }
+
+ inline bool operator==(const QString &s) const
+ { return s == *this; }
+ inline bool operator!=(const QString &s) const
+ { return s != *this; }
+ inline bool operator>(const QString &s) const
+ { return s < *this; }
+ inline bool operator<(const QString &s) const
+ { return s > *this; }
+ inline bool operator>=(const QString &s) const
+ { return s <= *this; }
+ inline bool operator<=(const QString &s) const
+ { return s >= *this; }
+
+ inline QT_ASCII_CAST_WARN bool operator==(const char *s) const
+ { return QString::fromAscii(s) == *this; }
+ inline QT_ASCII_CAST_WARN bool operator!=(const char *s) const
+ { return QString::fromAscii(s) != *this; }
+ inline QT_ASCII_CAST_WARN bool operator<(const char *s) const
+ { return QString::fromAscii(s) > *this; }
+ inline QT_ASCII_CAST_WARN bool operator>(const char *s) const
+ { return QString::fromAscii(s) < *this; }
+ inline QT_ASCII_CAST_WARN bool operator<=(const char *s) const
+ { return QString::fromAscii(s) >= *this; }
+ inline QT_ASCII_CAST_WARN bool operator>=(const char *s) const
+ { return QString::fromAscii(s) <= *this; }
+private:
+ const char *chars;
+};
+
+
+
+inline QString::QString(const QLatin1String &aLatin1) : d(fromLatin1_helper(aLatin1.latin1()))
+{ }
+inline int QString::length() const
+{ return d->size; }
+inline const QChar QString::at(int i) const
+{ Q_ASSERT(i >= 0 && i < size()); return d->data[i]; }
+inline const QChar QString::operator[](int i) const
+{ Q_ASSERT(i >= 0 && i < size()); return d->data[i]; }
+inline const QChar QString::operator[](uint i) const
+{ Q_ASSERT(i < uint(size())); return d->data[i]; }
+inline bool QString::isEmpty() const
+{ return d->size == 0; }
+inline const QChar *QString::unicode() const
+{ return reinterpret_cast<const QChar*>(d->data); }
+inline const QChar *QString::data() const
+{ return reinterpret_cast<const QChar*>(d->data); }
+inline QChar *QString::data()
+{ detach(); return reinterpret_cast<QChar*>(d->data); }
+inline const QChar *QString::constData() const
+{ return reinterpret_cast<const QChar*>(d->data); }
+inline void QString::detach()
+{ if (d->ref != 1 || d->data != d->array) realloc(); }
+inline bool QString::isDetached() const
+{ return d->ref == 1; }
+inline QString &QString::operator=(const QLatin1String &s)
+{
+ *this = fromLatin1(s.latin1());
+ return *this;
+}
+inline void QString::clear()
+{ if (!isNull()) *this = QString(); }
+inline QString::QString(const QString &other) : d(other.d)
+{ Q_ASSERT(&other != this); d->ref.ref(); }
+inline int QString::capacity() const
+{ return d->alloc; }
+inline QString &QString::setNum(short n, int base)
+{ return setNum(qlonglong(n), base); }
+inline QString &QString::setNum(ushort n, int base)
+{ return setNum(qulonglong(n), base); }
+inline QString &QString::setNum(int n, int base)
+{ return setNum(qlonglong(n), base); }
+inline QString &QString::setNum(uint n, int base)
+{ return setNum(qulonglong(n), base); }
+inline QString &QString::setNum(long n, int base)
+{ return setNum(qlonglong(n), base); }
+inline QString &QString::setNum(ulong n, int base)
+{ return setNum(qulonglong(n), base); }
+inline QString &QString::setNum(float n, char f, int prec)
+{ return setNum(double(n),f,prec); }
+inline QString QString::arg(int a, int fieldWidth, int base, const QChar &fillChar) const
+{ return arg(qlonglong(a), fieldWidth, base, fillChar); }
+inline QString QString::arg(uint a, int fieldWidth, int base, const QChar &fillChar) const
+{ return arg(qulonglong(a), fieldWidth, base, fillChar); }
+inline QString QString::arg(long a, int fieldWidth, int base, const QChar &fillChar) const
+{ return arg(qlonglong(a), fieldWidth, base, fillChar); }
+inline QString QString::arg(ulong a, int fieldWidth, int base, const QChar &fillChar) const
+{ return arg(qulonglong(a), fieldWidth, base, fillChar); }
+inline QString QString::arg(short a, int fieldWidth, int base, const QChar &fillChar) const
+{ return arg(qlonglong(a), fieldWidth, base, fillChar); }
+inline QString QString::arg(ushort a, int fieldWidth, int base, const QChar &fillChar) const
+{ return arg(qulonglong(a), fieldWidth, base, fillChar); }
+inline QString QString::arg(const QString &a1, const QString &a2) const
+{ const QString *args[2] = { &a1, &a2 }; return multiArg(2, args); }
+inline QString QString::arg(const QString &a1, const QString &a2, const QString &a3) const
+{ const QString *args[3] = { &a1, &a2, &a3 }; return multiArg(3, args); }
+inline QString QString::arg(const QString &a1, const QString &a2, const QString &a3,
+ const QString &a4) const
+{ const QString *args[4] = { &a1, &a2, &a3, &a4 }; return multiArg(4, args); }
+inline QString QString::arg(const QString &a1, const QString &a2, const QString &a3,
+ const QString &a4, const QString &a5) const
+{ const QString *args[5] = { &a1, &a2, &a3, &a4, &a5 }; return multiArg(5, args); }
+inline QString QString::arg(const QString &a1, const QString &a2, const QString &a3,
+ const QString &a4, const QString &a5, const QString &a6) const
+{ const QString *args[6] = { &a1, &a2, &a3, &a4, &a5, &a6 }; return multiArg(6, args); }
+inline QString QString::arg(const QString &a1, const QString &a2, const QString &a3,
+ const QString &a4, const QString &a5, const QString &a6,
+ const QString &a7) const
+{ const QString *args[7] = { &a1, &a2, &a3, &a4, &a5, &a6, &a7 }; return multiArg(7, args); }
+inline QString QString::arg(const QString &a1, const QString &a2, const QString &a3,
+ const QString &a4, const QString &a5, const QString &a6,
+ const QString &a7, const QString &a8) const
+{ const QString *args[8] = { &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8 }; return multiArg(8, args); }
+inline QString QString::arg(const QString &a1, const QString &a2, const QString &a3,
+ const QString &a4, const QString &a5, const QString &a6,
+ const QString &a7, const QString &a8, const QString &a9) const
+{ const QString *args[9] = { &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8, &a9 }; return multiArg(9, args); }
+
+inline QString QString::section(QChar asep, int astart, int aend, SectionFlags aflags) const
+{ return section(QString(asep), astart, aend, aflags); }
+
+
+class Q_CORE_EXPORT QCharRef {
+ QString &s;
+ int i;
+ inline QCharRef(QString &str, int idx)
+ : s(str),i(idx) {}
+ friend class QString;
+public:
+
+ // most QChar operations repeated here
+
+ // all this is not documented: We just say "like QChar" and let it be.
+ inline operator QChar() const
+ { return i < s.d->size ? s.d->data[i] : 0; }
+ inline QCharRef &operator=(const QChar &c)
+ { if (i >= s.d->size) s.expand(i); else s.detach();
+ s.d->data[i] = c.unicode(); return *this; }
+
+ // An operator= for each QChar cast constructors
+#ifndef QT_NO_CAST_FROM_ASCII
+ inline QT_ASCII_CAST_WARN QCharRef &operator=(char c)
+ { return operator=(QChar::fromAscii(c)); }
+ inline QT_ASCII_CAST_WARN QCharRef &operator=(uchar c)
+ { return operator=(QChar::fromAscii(c)); }
+#endif
+ inline QCharRef &operator=(const QCharRef &c) { return operator=(QChar(c)); }
+ inline QCharRef &operator=(ushort rc) { return operator=(QChar(rc)); }
+ inline QCharRef &operator=(short rc) { return operator=(QChar(rc)); }
+ inline QCharRef &operator=(uint rc) { return operator=(QChar(rc)); }
+ inline QCharRef &operator=(int rc) { return operator=(QChar(rc)); }
+
+ // each function...
+ inline bool isNull() const { return QChar(*this).isNull(); }
+ inline bool isPrint() const { return QChar(*this).isPrint(); }
+ inline bool isPunct() const { return QChar(*this).isPunct(); }
+ inline bool isSpace() const { return QChar(*this).isSpace(); }
+ inline bool isMark() const { return QChar(*this).isMark(); }
+ inline bool isLetter() const { return QChar(*this).isLetter(); }
+ inline bool isNumber() const { return QChar(*this).isNumber(); }
+ inline bool isLetterOrNumber() { return QChar(*this).isLetterOrNumber(); }
+ inline bool isDigit() const { return QChar(*this).isDigit(); }
+ inline bool isLower() const { return QChar(*this).isLower(); }
+ inline bool isUpper() const { return QChar(*this).isUpper(); }
+ inline bool isTitleCase() const { return QChar(*this).isTitleCase(); }
+
+ inline int digitValue() const { return QChar(*this).digitValue(); }
+ QChar toLower() const { return QChar(*this).toLower(); }
+ QChar toUpper() const { return QChar(*this).toUpper(); }
+ QChar toTitleCase () const { return QChar(*this).toTitleCase(); }
+
+ QChar::Category category() const { return QChar(*this).category(); }
+ QChar::Direction direction() const { return QChar(*this).direction(); }
+ QChar::Joining joining() const { return QChar(*this).joining(); }
+ bool hasMirrored() const { return QChar(*this).hasMirrored(); }
+ QChar mirroredChar() const { return QChar(*this).mirroredChar(); }
+ QString decomposition() const { return QChar(*this).decomposition(); }
+ QChar::Decomposition decompositionTag() const { return QChar(*this).decompositionTag(); }
+ uchar combiningClass() const { return QChar(*this).combiningClass(); }
+
+ QChar::UnicodeVersion unicodeVersion() const { return QChar(*this).unicodeVersion(); }
+
+ inline uchar cell() const { return QChar(*this).cell(); }
+ inline uchar row() const { return QChar(*this).row(); }
+ inline void setCell(uchar cell);
+ inline void setRow(uchar row);
+
+#ifdef Q_COMPILER_MANGLES_RETURN_TYPE
+ const char toAscii() const { return QChar(*this).toAscii(); }
+ const char toLatin1() const { return QChar(*this).toLatin1(); }
+ const ushort unicode() const { return QChar(*this).unicode(); }
+#else
+ char toAscii() const { return QChar(*this).toAscii(); }
+ char toLatin1() const { return QChar(*this).toLatin1(); }
+ ushort unicode() const { return QChar(*this).unicode(); }
+#endif
+ ushort& unicode() { return s.data()[i].unicode(); }
+
+#ifdef QT3_SUPPORT
+ inline QT3_SUPPORT bool mirrored() const { return hasMirrored(); }
+ inline QT3_SUPPORT QChar lower() const { return QChar(*this).toLower(); }
+ inline QT3_SUPPORT QChar upper() const { return QChar(*this).toUpper(); }
+#ifdef Q_COMPILER_MANGLES_RETURN_TYPE
+ const QT3_SUPPORT char latin1() const { return QChar(*this).toLatin1(); }
+ const QT3_SUPPORT char ascii() const { return QChar(*this).toAscii(); }
+#else
+ QT3_SUPPORT char latin1() const { return QChar(*this).toLatin1(); }
+ QT3_SUPPORT char ascii() const { return QChar(*this).toAscii(); }
+#endif
+#endif
+};
+
+inline void QCharRef::setRow(uchar arow) { QChar(*this).setRow(arow); }
+inline void QCharRef::setCell(uchar acell) { QChar(*this).setCell(acell); }
+
+
+inline QString::QString() : d(&shared_null) { d->ref.ref(); }
+inline QString::~QString() { if (!d->ref.deref()) free(d); }
+inline void QString::reserve(int asize) { if (d->ref != 1 || asize > d->alloc) realloc(asize); d->capacity = 1;}
+inline QString &QString::setUtf16(const ushort *autf16, int asize)
+{ return setUnicode(reinterpret_cast<const QChar *>(autf16), asize); }
+inline QCharRef QString::operator[](int i)
+{ Q_ASSERT(i >= 0); return QCharRef(*this, i); }
+inline QCharRef QString::operator[](uint i)
+{ return QCharRef(*this, i); }
+inline QString::iterator QString::begin()
+{ detach(); return reinterpret_cast<QChar*>(d->data); }
+inline QString::const_iterator QString::begin() const
+{ return reinterpret_cast<const QChar*>(d->data); }
+inline QString::const_iterator QString::constBegin() const
+{ return reinterpret_cast<const QChar*>(d->data); }
+inline QString::iterator QString::end()
+{ detach(); return reinterpret_cast<QChar*>(d->data + d->size); }
+inline QString::const_iterator QString::end() const
+{ return reinterpret_cast<const QChar*>(d->data + d->size); }
+inline QString::const_iterator QString::constEnd() const
+{ return reinterpret_cast<const QChar*>(d->data + d->size); }
+inline QBool QString::contains(const QString &s, Qt::CaseSensitivity cs) const
+{ return QBool(indexOf(s, 0, cs) != -1); }
+inline QBool QString::contains(QChar c, Qt::CaseSensitivity cs) const
+{ return QBool(indexOf(c, 0, cs) != -1); }
+
+
+inline bool operator==(QString::Null, QString::Null) { return true; }
+inline bool operator==(QString::Null, const QString &s) { return s.isNull(); }
+inline bool operator==(const QString &s, QString::Null) { return s.isNull(); }
+inline bool operator!=(QString::Null, QString::Null) { return false; }
+inline bool operator!=(QString::Null, const QString &s) { return !s.isNull(); }
+inline bool operator!=(const QString &s, QString::Null) { return !s.isNull(); }
+
+#ifndef QT_NO_CAST_FROM_ASCII
+inline bool qStringComparisonHelper(const QString &s1, const char *s2)
+{
+# ifndef QT_NO_TEXTCODEC
+ if (QString::codecForCStrings) return (s1 == QString::fromAscii(s2));
+# endif
+ return (s1 == QLatin1String(s2));
+}
+inline bool QString::operator==(const char *s) const
+{ return qStringComparisonHelper(*this, s); }
+inline bool QString::operator!=(const char *s) const
+{ return !qStringComparisonHelper(*this, s); }
+inline bool QString::operator<(const char *s) const
+{ return *this < QString::fromAscii(s); }
+inline bool QString::operator>(const char *s) const
+{ return *this > QString::fromAscii(s); }
+inline bool QString::operator<=(const char *s) const
+{ return *this <= QString::fromAscii(s); }
+inline bool QString::operator>=(const char *s) const
+{ return *this >= QString::fromAscii(s); }
+
+inline QT_ASCII_CAST_WARN bool operator==(const char *s1, const QString &s2)
+{ return qStringComparisonHelper(s2, s1); }
+inline QT_ASCII_CAST_WARN bool operator!=(const char *s1, const QString &s2)
+{ return !qStringComparisonHelper(s2, s1); }
+inline QT_ASCII_CAST_WARN bool operator<(const char *s1, const QString &s2)
+{ return (QString::fromAscii(s1) < s2); }
+inline QT_ASCII_CAST_WARN bool operator>(const char *s1, const QString &s2)
+{ return (QString::fromAscii(s1) > s2); }
+inline QT_ASCII_CAST_WARN bool operator<=(const char *s1, const QString &s2)
+{ return (QString::fromAscii(s1) <= s2); }
+inline QT_ASCII_CAST_WARN bool operator>=(const char *s1, const QString &s2)
+{ return (QString::fromAscii(s1) >= s2); }
+
+inline QT_ASCII_CAST_WARN bool operator==(const char *s1, const QLatin1String &s2)
+{ return QString::fromAscii(s1) == s2; }
+inline QT_ASCII_CAST_WARN bool operator!=(const char *s1, const QLatin1String &s2)
+{ return QString::fromAscii(s1) != s2; }
+inline QT_ASCII_CAST_WARN bool operator<(const char *s1, const QLatin1String &s2)
+{ return (QString::fromAscii(s1) < s2); }
+inline QT_ASCII_CAST_WARN bool operator>(const char *s1, const QLatin1String &s2)
+{ return (QString::fromAscii(s1) > s2); }
+inline QT_ASCII_CAST_WARN bool operator<=(const char *s1, const QLatin1String &s2)
+{ return (QString::fromAscii(s1) <= s2); }
+inline QT_ASCII_CAST_WARN bool operator>=(const char *s1, const QLatin1String &s2)
+{ return (QString::fromAscii(s1) >= s2); }
+
+inline bool operator==(const QLatin1String &s1, const QLatin1String &s2)
+{ return (qstrcmp(s1.latin1(), s2.latin1()) == 0); }
+inline bool operator!=(const QLatin1String &s1, const QLatin1String &s2)
+{ return (qstrcmp(s1.latin1(), s2.latin1()) != 0); }
+inline bool operator<(const QLatin1String &s1, const QLatin1String &s2)
+{ return (qstrcmp(s1.latin1(), s2.latin1()) < 0); }
+inline bool operator<=(const QLatin1String &s1, const QLatin1String &s2)
+{ return (qstrcmp(s1.latin1(), s2.latin1()) <= 0); }
+inline bool operator>(const QLatin1String &s1, const QLatin1String &s2)
+{ return (qstrcmp(s1.latin1(), s2.latin1()) > 0); }
+inline bool operator>=(const QLatin1String &s1, const QLatin1String &s2)
+{ return (qstrcmp(s1.latin1(), s2.latin1()) >= 0); }
+
+
+inline bool QString::operator==(const QByteArray &s) const
+{ return qStringComparisonHelper(*this, s.constData()); }
+inline bool QString::operator!=(const QByteArray &s) const
+{ return !qStringComparisonHelper(*this, s.constData()); }
+
+inline bool QByteArray::operator==(const QString &s) const
+{ return qStringComparisonHelper(s, constData()); }
+inline bool QByteArray::operator!=(const QString &s) const
+{ return !qStringComparisonHelper(s, constData()); }
+inline bool QByteArray::operator<(const QString &s) const
+{ return QString::fromAscii(constData(), size()) < s; }
+inline bool QByteArray::operator>(const QString &s) const
+{ return QString::fromAscii(constData(), size()) > s; }
+inline bool QByteArray::operator<=(const QString &s) const
+{ return QString::fromAscii(constData(), size()) <= s; }
+inline bool QByteArray::operator>=(const QString &s) const
+{ return QString::fromAscii(constData(), size()) >= s; }
+#endif // QT_NO_CAST_FROM_ASCII
+
+#ifndef QT_NO_CAST_TO_ASCII
+inline QByteArray &QByteArray::append(const QString &s)
+{ return append(s.toAscii()); }
+inline QByteArray &QByteArray::insert(int i, const QString &s)
+{ return insert(i, s.toAscii()); }
+inline QByteArray &QByteArray::replace(char c, const QString &after)
+{ return replace(c, after.toAscii()); }
+inline QByteArray &QByteArray::replace(const QString &before, const char *after)
+{ return replace(before.toAscii(), after); }
+inline QByteArray &QByteArray::replace(const QString &before, const QByteArray &after)
+{ return replace(before.toAscii(), after); }
+inline QByteArray &QByteArray::operator+=(const QString &s)
+{ return operator+=(s.toAscii()); }
+inline int QByteArray::indexOf(const QString &s, int from) const
+{ return indexOf(s.toAscii(), from); }
+inline int QByteArray::lastIndexOf(const QString &s, int from) const
+{ return lastIndexOf(s.toAscii(), from); }
+# ifdef QT3_SUPPORT
+inline int QByteArray::find(const QString &s, int from) const
+{ return indexOf(s.toAscii(), from); }
+inline int QByteArray::findRev(const QString &s, int from) const
+{ return lastIndexOf(s.toAscii(), from); }
+# endif // QT3_SUPPORT
+#endif // QT_NO_CAST_TO_ASCII
+
+inline const QString operator+(const QString &s1, const QString &s2)
+{ QString t(s1); t += s2; return t; }
+inline const QString operator+(const QString &s1, QChar s2)
+{ QString t(s1); t += s2; return t; }
+inline const QString operator+(QChar s1, const QString &s2)
+{ QString t(s1); t += s2; return t; }
+#ifndef QT_NO_CAST_FROM_ASCII
+inline QT_ASCII_CAST_WARN const QString operator+(const QString &s1, const char *s2)
+{ QString t(s1); t += QString::fromAscii(s2); return t; }
+inline QT_ASCII_CAST_WARN const QString operator+(const char *s1, const QString &s2)
+{ QString t = QString::fromAscii(s1); t += s2; return t; }
+inline QT_ASCII_CAST_WARN const QString operator+(char c, const QString &s)
+{ QString t = s; t.prepend(QChar::fromAscii(c)); return t; }
+inline QT_ASCII_CAST_WARN const QString operator+(const QString &s, char c)
+{ QString t = s; t += QChar::fromAscii(c); return t; }
+inline QT_ASCII_CAST_WARN const QString operator+(const QByteArray &ba, const QString &s)
+{ QString t = QString::fromAscii(ba.constData(), qstrnlen(ba.constData(), ba.size())); t += s; return t; }
+inline QT_ASCII_CAST_WARN const QString operator+(const QString &s, const QByteArray &ba)
+{ QString t(s); t += QString::fromAscii(ba.constData(), qstrnlen(ba.constData(), ba.size())); return t; }
+#endif
+
+#ifndef QT_NO_STL
+inline std::string QString::toStdString() const
+{ const QByteArray asc = toAscii(); return std::string(asc.constData(), asc.length()); }
+
+inline QString QString::fromStdString(const std::string &s)
+{ return fromAscii(s.data(), int(s.size())); }
+
+# ifndef QT_NO_STL_WCHAR
+inline QStdWString QString::toStdWString() const
+{
+ QStdWString str;
+ str.resize(length());
+
+#if defined(_MSC_VER) && _MSC_VER >= 1400
+ // VS2005 crashes if the string is empty
+ if (!length())
+ return str;
+#endif
+
+ str.resize(toWCharArray(&(*str.begin())));
+ return str;
+}
+inline QString QString::fromStdWString(const QStdWString &s)
+{ return fromWCharArray(s.data(), int(s.size())); }
+# endif
+#endif
+
+#ifdef QT3_SUPPORT
+inline QChar &QString::ref(uint i)
+{
+ if (int(i) > d->size || d->ref != 1)
+ resize(qMax(int(i), d->size));
+ return reinterpret_cast<QChar&>(d->data[i]);
+}
+#endif
+
+#ifndef QT_NO_DATASTREAM
+Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QString &);
+Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QString &);
+#endif
+
+#ifdef QT3_SUPPORT
+class QConstString : public QString
+{
+public:
+ inline QT3_SUPPORT_CONSTRUCTOR QConstString(const QChar *aUnicode, int aSize)
+ :QString(aUnicode, aSize){} // cannot use fromRawData() due to changed semantics
+ inline QT3_SUPPORT const QString &string() const { return *this; }
+};
+#endif
+
+Q_DECLARE_TYPEINFO(QString, Q_MOVABLE_TYPE);
+Q_DECLARE_SHARED(QString)
+Q_DECLARE_OPERATORS_FOR_FLAGS(QString::SectionFlags)
+
+#if defined(Q_OS_WIN32) || defined(Q_OS_WINCE)
+extern Q_CORE_EXPORT QByteArray qt_winQString2MB(const QString& s, int len=-1);
+extern Q_CORE_EXPORT QByteArray qt_winQString2MB(const QChar *ch, int len);
+extern Q_CORE_EXPORT QString qt_winMB2QString(const char* mb, int len=-1);
+#endif
+
+
+class Q_CORE_EXPORT QStringRef {
+ const QString *m_string;
+ int m_position;
+ int m_size;
+public:
+ inline QStringRef():m_string(0), m_position(0), m_size(0){}
+ inline QStringRef(const QString *string, int position, int size);
+ inline QStringRef(const QString *string);
+ inline QStringRef(const QStringRef &other)
+ :m_string(other.m_string), m_position(other.m_position), m_size(other.m_size)
+ {}
+
+ inline ~QStringRef(){}
+ inline const QString *string() const { return m_string; }
+ inline int position() const { return m_position; }
+ inline int size() const { return m_size; }
+ inline int count() const { return m_size; }
+ inline int length() const { return m_size; }
+
+ inline QStringRef &operator=(const QStringRef &other) {
+ m_string = other.m_string; m_position = other.m_position;
+ m_size = other.m_size; return *this;
+ }
+
+ inline QStringRef &operator=(const QString *string);
+
+ inline const QChar *unicode() const {
+ if (!m_string)
+ return reinterpret_cast<const QChar *>(QString::shared_null.data);
+ return m_string->unicode() + m_position;
+ }
+ inline const QChar *data() const { return unicode(); }
+ inline const QChar *constData() const { return unicode(); }
+
+ inline void clear() { m_string = 0; m_position = m_size = 0; }
+ QString toString() const;
+ inline bool isEmpty() const { return m_size == 0; }
+ inline bool isNull() const { return m_string == 0 || m_string->isNull(); }
+
+ QStringRef appendTo(QString *string) const;
+
+ inline const QChar at(int i) const
+ { Q_ASSERT(i >= 0 && i < size()); return m_string->at(i + m_position); }
+
+ int compare(const QString &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
+ int compare(const QStringRef &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
+ int compare(QLatin1String s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
+ static int compare(const QStringRef &s1, const QString &s2,
+ Qt::CaseSensitivity = Qt::CaseSensitive);
+ static int compare(const QStringRef &s1, const QStringRef &s2,
+ Qt::CaseSensitivity = Qt::CaseSensitive);
+ static int compare(const QStringRef &s1, QLatin1String s2,
+ Qt::CaseSensitivity cs = Qt::CaseSensitive);
+
+ int localeAwareCompare(const QString &s) const;
+ int localeAwareCompare(const QStringRef &s) const;
+ static int localeAwareCompare(const QStringRef &s1, const QString &s2);
+ static int localeAwareCompare(const QStringRef &s1, const QStringRef &s2);
+};
+
+inline QStringRef &QStringRef::operator=(const QString *aString)
+{ m_string = aString; m_position = 0; m_size = aString?aString->size():0; return *this; }
+
+inline QStringRef::QStringRef(const QString *aString, int aPosition, int aSize)
+ :m_string(aString), m_position(aPosition), m_size(aSize){}
+
+inline QStringRef::QStringRef(const QString *aString)
+ :m_string(aString), m_position(0), m_size(aString?aString->size() : 0){}
+
+Q_CORE_EXPORT bool operator==(const QStringRef &s1,const QStringRef &s2);
+inline bool operator!=(const QStringRef &s1,const QStringRef &s2)
+{ return !(s1 == s2); }
+Q_CORE_EXPORT bool operator==(const QString &s1,const QStringRef &s2);
+inline bool operator!=(const QString &s1,const QStringRef &s2)
+{ return !(s1 == s2); }
+inline bool operator==(const QStringRef &s1,const QString &s2)
+{ return s2 == s1; }
+inline bool operator!=(const QStringRef &s1,const QString &s2)
+{ return s2 != s1; }
+Q_CORE_EXPORT bool operator==(const QLatin1String &s1, const QStringRef &s2);
+inline bool operator!=(const QLatin1String &s1,const QStringRef &s2)
+{ return !(s1 == s2); }
+inline bool operator==(const QStringRef &s1,const QLatin1String &s2)
+{ return s2 == s1; }
+inline bool operator!=(const QStringRef &s1,const QLatin1String &s2)
+{ return s2 != s1; }
+
+Q_CORE_EXPORT bool operator<(const QStringRef &s1,const QStringRef &s2);
+inline bool operator>(const QStringRef &s1, const QStringRef &s2)
+{ return s2 < s1; }
+inline bool operator<=(const QStringRef &s1, const QStringRef &s2)
+{ return !(s1 > s2); }
+inline bool operator>=(const QStringRef &s1, const QStringRef &s2)
+{ return !(s1 < s2); }
+
+inline bool qStringComparisonHelper(const QStringRef &s1, const char *s2)
+{
+# ifndef QT_NO_TEXTCODEC
+ if (QString::codecForCStrings) return (s1 == QString::fromAscii(s2));
+# endif
+ return (s1 == QLatin1String(s2));
+}
+
+inline QT_ASCII_CAST_WARN bool operator==(const char *s1, const QStringRef &s2)
+{ return qStringComparisonHelper(s2, s1); }
+inline QT_ASCII_CAST_WARN bool operator==(const QStringRef &s1, const char *s2)
+{ return qStringComparisonHelper(s1, s2); }
+inline QT_ASCII_CAST_WARN bool operator!=(const char *s1, const QStringRef &s2)
+{ return !qStringComparisonHelper(s2, s1); }
+inline QT_ASCII_CAST_WARN bool operator!=(const QStringRef &s1, const char *s2)
+{ return !qStringComparisonHelper(s1, s2); }
+
+inline int QString::compare(const QStringRef &s, Qt::CaseSensitivity cs) const
+{ return QString::compare_helper(constData(), length(), s.constData(), s.length(), cs); }
+inline int QString::compare(const QString &s1, const QStringRef &s2, Qt::CaseSensitivity cs)
+{ return QString::compare_helper(s1.constData(), s1.length(), s2.constData(), s2.length(), cs); }
+inline int QStringRef::compare(const QString &s, Qt::CaseSensitivity cs) const
+{ return QString::compare_helper(constData(), length(), s.constData(), s.length(), cs); }
+inline int QStringRef::compare(const QStringRef &s, Qt::CaseSensitivity cs) const
+{ return QString::compare_helper(constData(), length(), s.constData(), s.length(), cs); }
+inline int QStringRef::compare(QLatin1String s, Qt::CaseSensitivity cs) const
+{ return QString::compare_helper(constData(), length(), s, cs); }
+inline int QStringRef::compare(const QStringRef &s1, const QString &s2, Qt::CaseSensitivity cs)
+{ return QString::compare_helper(s1.constData(), s1.length(), s2.constData(), s2.length(), cs); }
+inline int QStringRef::compare(const QStringRef &s1, const QStringRef &s2, Qt::CaseSensitivity cs)
+{ return QString::compare_helper(s1.constData(), s1.length(), s2.constData(), s2.length(), cs); }
+inline int QStringRef::compare(const QStringRef &s1, QLatin1String s2, Qt::CaseSensitivity cs)
+{ return QString::compare_helper(s1.constData(), s1.length(), s2, cs); }
+
+inline int QString::localeAwareCompare(const QStringRef &s) const
+{ return localeAwareCompare_helper(constData(), length(), s.constData(), s.length()); }
+inline int QString::localeAwareCompare(const QString& s1, const QStringRef& s2)
+{ return localeAwareCompare_helper(s1.constData(), s1.length(), s2.constData(), s2.length()); }
+inline int QStringRef::localeAwareCompare(const QString &s) const
+{ return QString::localeAwareCompare_helper(constData(), length(), s.constData(), s.length()); }
+inline int QStringRef::localeAwareCompare(const QStringRef &s) const
+{ return QString::localeAwareCompare_helper(constData(), length(), s.constData(), s.length()); }
+inline int QStringRef::localeAwareCompare(const QStringRef &s1, const QString &s2)
+{ return QString::localeAwareCompare_helper(s1.constData(), s1.length(), s2.constData(), s2.length()); }
+inline int QStringRef::localeAwareCompare(const QStringRef &s1, const QStringRef &s2)
+{ return QString::localeAwareCompare_helper(s1.constData(), s1.length(), s2.constData(), s2.length()); }
+
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QSTRING_H
diff --git a/src/corelib/tools/qstringlist.cpp b/src/corelib/tools/qstringlist.cpp
new file mode 100644
index 0000000000..386321f13e
--- /dev/null
+++ b/src/corelib/tools/qstringlist.cpp
@@ -0,0 +1,673 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qstringlist.h>
+#include <qset.h>
+
+QT_BEGIN_NAMESPACE
+
+/*! \typedef QStringListIterator
+ \relates QStringList
+
+ The QStringListIterator type definition provides a Java-style const
+ iterator for QStringList.
+
+ QStringList provides both \l{Java-style iterators} and
+ \l{STL-style iterators}. The Java-style const iterator is simply
+ a type definition for QListIterator<QString>.
+
+ \sa QMutableStringListIterator, QStringList::const_iterator
+*/
+
+/*! \typedef QMutableStringListIterator
+ \relates QStringList
+
+ The QStringListIterator type definition provides a Java-style
+ non-const iterator for QStringList.
+
+ QStringList provides both \l{Java-style iterators} and
+ \l{STL-style iterators}. The Java-style non-const iterator is
+ simply a type definition for QMutableListIterator<QString>.
+
+ \sa QStringListIterator, QStringList::iterator
+*/
+
+/*!
+ \class QStringList
+ \brief The QStringList class provides a list of strings.
+
+ \ingroup tools
+ \ingroup shared
+ \ingroup text
+ \mainclass
+ \reentrant
+
+ QStringList inherits from QList<QString>. Like QList, QStringList is
+ \l{implicitly shared}. It provides fast index-based access as well as fast
+ insertions and removals. Passing string lists as value parameters is both
+ fast and safe.
+
+ All of QList's functionality also applies to QStringList. 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
+ QStringList. In addition, QStringList provides a few convenience
+ functions that make handling lists of strings easier:
+
+ \tableofcontents
+
+ \section1 Adding strings
+
+ Strings can be added to a list using the \l
+ {QList::append()}{append()}, \l
+ {QList::operator+=()}{operator+=()} and \l
+ {QStringList::operator<<()}{operator<<()} functions. For example:
+
+ \snippet doc/src/snippets/qstringlist/main.cpp 0
+
+ \section1 Iterating over the strings
+
+ To iterate over a list, you can either use index positions or
+ QList's Java-style and STL-style iterator types:
+
+ Indexing:
+
+ \snippet doc/src/snippets/qstringlist/main.cpp 1
+
+ Java-style iterator:
+
+ \snippet doc/src/snippets/qstringlist/main.cpp 2
+
+ STL-style iterator:
+
+ \snippet doc/src/snippets/qstringlist/main.cpp 3
+
+ The QStringListIterator class is simply a type definition for
+ QListIterator<QString>. QStringList also provide the
+ QMutableStringListIterator class which is a type definition for
+ QMutableListIterator<QString>.
+
+ \section1 Manipulating the strings
+
+ QStringList provides several functions allowing you to manipulate
+ the contents of a list. You can concatenate all the strings in a
+ string list into a single string (with an optional separator)
+ using the join() function. For example:
+
+ \snippet doc/src/snippets/qstringlist/main.cpp 4
+
+ To break up a string into a string list, use the QString::split()
+ function:
+
+ \snippet doc/src/snippets/qstringlist/main.cpp 6
+
+ The argument to split can be a single character, a string, or a
+ QRegExp.
+
+ In addition, the \l {QStringList::operator+()}{operator+()}
+ function allows you to concatenate two string lists into one. To
+ sort a string list, use the sort() function.
+
+ QString list also provides the filter() function which lets you
+ to extract a new list which contains only those strings which
+ contain a particular substring (or match a particular regular
+ expression):
+
+ \snippet doc/src/snippets/qstringlist/main.cpp 7
+
+ The contains() function tells you whether the list contains a
+ given string, while the indexOf() function returns the index of
+ the first occurrence of the given string. The lastIndexOf()
+ function on the other hand, returns the index of the last
+ occurrence of the string.
+
+ Finally, the replaceInStrings() function calls QString::replace()
+ on each string in the string list in turn. For example:
+
+ \snippet doc/src/snippets/qstringlist/main.cpp 8
+
+ \sa QString
+*/
+
+/*!
+ \fn QStringList::QStringList()
+
+ Constructs an empty string list.
+*/
+
+/*!
+ \fn QStringList::QStringList(const QString &str)
+
+ Constructs a string list that contains the given string, \a
+ str. Longer lists are easily created like this:
+
+ \snippet doc/src/snippets/qstringlist/main.cpp 9
+
+ \sa append()
+*/
+
+/*!
+ \fn QStringList::QStringList(const QStringList &other)
+
+ Constructs a copy of the \a other string list.
+
+ This operation takes \l{constant time} because QStringList is
+ \l{implicitly shared}, making the process of returning a
+ QStringList from a function very fast. If a shared instance is
+ modified, it will be copied (copy-on-write), and that takes
+ \l{linear time}.
+
+ \sa operator=()
+*/
+
+/*!
+ \fn QStringList::QStringList(const QList<QString> &other)
+
+ Constructs a copy of \a other.
+
+ This operation takes \l{constant time}, because QStringList is
+ \l{implicitly shared}. This makes returning a QStringList from a
+ function very fast. If a shared instance is modified, it will be
+ copied (copy-on-write), and that takes \l{linear time}.
+
+ \sa operator=()
+*/
+
+/*!
+ \fn void QStringList::sort()
+
+ Sorts the list of strings in ascending order (case sensitively).
+
+ Sorting is performed using Qt's qSort() algorithm,
+ which operates in \l{linear-logarithmic time}, i.e. O(\e{n} log \e{n}).
+
+ If you want to sort your strings in an arbitrary order, consider
+ using the QMap class. For example, you could use a QMap<QString,
+ QString> to create a case-insensitive ordering (e.g. with the keys
+ being lower-case versions of the strings, and the values being the
+ strings), or a QMap<int, QString> to sort the strings by some
+ integer index.
+
+ \sa qSort()
+*/
+void QtPrivate::QStringList_sort(QStringList *that)
+{
+ qSort(*that);
+}
+
+
+#ifdef QT3_SUPPORT
+/*!
+ \fn QStringList QStringList::split(const QChar &sep, const QString &str, bool allowEmptyEntries)
+
+ \overload
+
+ This version of the function uses a QChar as separator.
+
+ \sa join() QString::section()
+*/
+
+/*!
+ \fn QStringList QStringList::split(const QString &sep, const QString &str, bool allowEmptyEntries)
+
+ \overload
+
+ This version of the function uses a QString as separator.
+
+ \sa join() QString::section()
+*/
+#ifndef QT_NO_REGEXP
+/*!
+ \fn QStringList QStringList::split(const QRegExp &sep, const QString &str, bool allowEmptyEntries)
+
+ Use QString::split(\a sep, QString::SkipEmptyParts) or
+ QString::split(\a sep, QString::KeepEmptyParts) instead.
+
+ Be aware that the QString::split()'s return value is a
+ QStringList that always contains at least one element, even if \a
+ str is empty.
+
+ \sa join() QString::section()
+*/
+#endif
+#endif // QT3_SUPPORT
+
+/*!
+ \fn QStringList QStringList::filter(const QString &str, Qt::CaseSensitivity cs) const
+
+ Returns a list of all the strings containing the substring \a str.
+
+ If \a cs is \l Qt::CaseSensitive (the default), the string
+ comparison is case sensitive; otherwise the comparison is case
+ insensitive.
+
+ \snippet doc/src/snippets/qstringlist/main.cpp 5
+ \snippet doc/src/snippets/qstringlist/main.cpp 10
+
+ This is equivalent to
+
+ \snippet doc/src/snippets/qstringlist/main.cpp 11
+ \snippet doc/src/snippets/qstringlist/main.cpp 12
+
+ \sa contains()
+*/
+QStringList QtPrivate::QStringList_filter(const QStringList *that, const QString &str,
+ Qt::CaseSensitivity cs)
+{
+ QStringMatcher matcher(str, cs);
+ QStringList res;
+ for (int i = 0; i < that->size(); ++i)
+ if (matcher.indexIn(that->at(i)) != -1)
+ res << that->at(i);
+ return res;
+}
+
+
+/*!
+ \fn QBool QStringList::contains(const QString &str, Qt::CaseSensitivity cs) const
+
+ Returns true if the list contains the string \a str; otherwise
+ returns false. The search is case insensitive if \a cs is
+ Qt::CaseInsensitive; the search is case sensitive by default.
+
+ \sa indexOf(), lastIndexOf(), QString::contains()
+ */
+QBool QtPrivate::QStringList_contains(const QStringList *that, const QString &str,
+ Qt::CaseSensitivity cs)
+{
+ for (int i = 0; i < that->size(); ++i) {
+ const QString & string = that->at(i);
+ if (string.length() == str.length() && str.compare(string, cs) == 0)
+ return QBool(true);
+ }
+ return QBool(false);
+}
+
+#ifndef QT_NO_REGEXP
+/*!
+ \fn QStringList QStringList::filter(const QRegExp &rx) const
+
+ \overload
+
+ Returns a list of all the strings that match the regular
+ expression \a rx.
+*/
+QStringList QtPrivate::QStringList_filter(const QStringList *that, const QRegExp &rx)
+{
+ QStringList res;
+ for (int i = 0; i < that->size(); ++i)
+ if (that->at(i).contains(rx))
+ res << that->at(i);
+ return res;
+}
+#endif
+
+/*!
+ \fn QStringList &QStringList::replaceInStrings(const QString &before, const QString &after, Qt::CaseSensitivity cs)
+
+ Returns a string list where every string has had the \a before
+ text replaced with the \a after text wherever the \a before text
+ is found. The \a before text is matched case-sensitively or not
+ depending on the \a cs flag.
+
+ For example:
+
+ \snippet doc/src/snippets/qstringlist/main.cpp 5
+ \snippet doc/src/snippets/qstringlist/main.cpp 13
+
+ \sa QString::replace()
+*/
+void QtPrivate::QStringList_replaceInStrings(QStringList *that, const QString &before,
+ const QString &after, Qt::CaseSensitivity cs)
+{
+ for (int i = 0; i < that->size(); ++i)
+ (*that)[i].replace(before, after, cs);
+}
+
+
+#ifndef QT_NO_REGEXP
+/*!
+ \fn QStringList &QStringList::replaceInStrings(const QRegExp &rx, const QString &after)
+ \overload
+
+ Replaces every occurrence of the regexp \a rx, in each of the
+ string lists's strings, with \a after. Returns a reference to the
+ string list.
+
+ For example:
+
+ \snippet doc/src/snippets/qstringlist/main.cpp 5
+ \snippet doc/src/snippets/qstringlist/main.cpp 14
+
+ For regular expressions that contain \l{capturing parentheses},
+ occurrences of \bold{\\1}, \bold{\\2}, ..., in \a after are
+ replaced with \a{rx}.cap(1), \a{rx}.cap(2), ...
+
+ For example:
+
+ \snippet doc/src/snippets/qstringlist/main.cpp 5
+ \snippet doc/src/snippets/qstringlist/main.cpp 15
+*/
+void QtPrivate::QStringList_replaceInStrings(QStringList *that, const QRegExp &rx, const QString &after)
+{
+ for (int i = 0; i < that->size(); ++i)
+ (*that)[i].replace(rx, after);
+}
+#endif
+
+/*!
+ \fn QString QStringList::join(const QString &separator) const
+
+ Joins all the string list's strings into a single string with each
+ element separated by the the given \a separator (which can be an
+ empty string).
+
+ \sa QString::split()
+*/
+QString QtPrivate::QStringList_join(const QStringList *that, const QString &sep)
+{
+ QString res;
+ for (int i = 0; i < that->size(); ++i) {
+ if (i)
+ res += sep;
+ res += that->at(i);
+ }
+ return res;
+}
+
+/*!
+ \fn QStringList QStringList::operator+(const QStringList &other) const
+
+ Returns a string list that is the concatenation of this string
+ list with the \a other string list.
+
+ \sa append()
+*/
+
+/*!
+ \fn QStringList &QStringList::operator<<(const QString &str)
+
+ Appends the given string, \a str, to this string list and returns
+ a reference to the string list.
+
+ \sa append()
+*/
+
+/*!
+ \fn QStringList &QStringList::operator<<(const QStringList &other)
+
+ \overload
+
+ Appends the \a other string list to the string list and returns a reference to
+ the latter string list.
+*/
+
+#ifndef QT_NO_DATASTREAM
+/*!
+ \fn QDataStream &operator>>(QDataStream &in, QStringList &list)
+ \relates QStringList
+
+ Reads a string list from the given \a in stream into the specified
+ \a list.
+
+ \sa {Format of the QDataStream Operators}
+*/
+
+/*!
+ \fn QDataStream &operator<<(QDataStream &out, const QStringList &list)
+ \relates QStringList
+
+ Writes the given string \a list to the specified \a out stream.
+
+ \sa {Format of the QDataStream Operators}
+*/
+#endif // QT_NO_DATASTREAM
+
+/*!
+ \fn QStringList QStringList::grep(const QString &str, bool cs = true) const
+
+ Use filter() instead.
+*/
+
+/*!
+ \fn QStringList QStringList::grep(const QRegExp &rx) const
+
+ Use filter() instead.
+*/
+
+/*!
+ \fn QStringList &QStringList::gres(const QString &before, const QString &after, bool cs = true)
+
+ Use replaceInStrings() instead.
+*/
+
+/*!
+ \fn QStringList &QStringList::gres(const QRegExp &rx, const QString &after)
+
+ Use replaceInStrings() instead.
+*/
+
+/*!
+ \fn Iterator QStringList::fromLast()
+
+ Use end() instead.
+
+ \oldcode
+ QStringList::Iterator i = list.fromLast();
+ \newcode
+ QStringList::Iterator i = list.isEmpty() ? list.end() : --list.end();
+ \endcode
+*/
+
+/*!
+ \fn ConstIterator QStringList::fromLast() const
+
+ Use end() instead.
+
+ \oldcode
+ QStringList::ConstIterator i = list.fromLast();
+ \newcode
+ QStringList::ConstIterator i = list.isEmpty() ? list.end() : --list.end();
+ \endcode
+*/
+
+
+#ifndef QT_NO_REGEXP
+static int indexOfMutating(const QStringList *that, QRegExp &rx, int from)
+{
+ if (from < 0)
+ from = qMax(from + that->size(), 0);
+ for (int i = from; i < that->size(); ++i) {
+ if (rx.exactMatch(that->at(i)))
+ return i;
+ }
+ return -1;
+}
+
+static int lastIndexOfMutating(const QStringList *that, QRegExp &rx, int from)
+{
+ if (from < 0)
+ from += that->size();
+ else if (from >= that->size())
+ from = that->size() - 1;
+ for (int i = from; i >= 0; --i) {
+ if (rx.exactMatch(that->at(i)))
+ return i;
+ }
+ return -1;
+}
+
+/*!
+ \fn int QStringList::indexOf(const QRegExp &rx, int from) const
+
+ Returns the index position of the first exact match of \a rx in
+ the list, searching forward from index position \a from. Returns
+ -1 if no item matched.
+
+ By default, this function is case sensitive.
+
+ \sa lastIndexOf(), contains(), QRegExp::exactMatch()
+*/
+int QtPrivate::QStringList_indexOf(const QStringList *that, const QRegExp &rx, int from)
+{
+ QRegExp rx2(rx);
+ return indexOfMutating(that, rx2, from);
+}
+
+/*!
+ \fn int QStringList::indexOf(QRegExp &rx, int from) const
+ \overload indexOf()
+ \since 4.5
+
+ Returns the index position of the first exact match of \a rx in
+ the list, searching forward from index position \a from. Returns
+ -1 if no item matched.
+
+ By default, this function is case sensitive.
+
+ If an item matched, the \a rx regular expression will contain the
+ matched objects (see QRegExp::matchedLength, QRegExp::cap).
+
+ \sa lastIndexOf(), contains(), QRegExp::exactMatch()
+*/
+int QtPrivate::QStringList_indexOf(const QStringList *that, QRegExp &rx, int from)
+{
+ return indexOfMutating(that, rx, from);
+}
+
+/*!
+ \fn int QStringList::lastIndexOf(const QRegExp &rx, int from) const
+
+ Returns the index position of the last exact match of \a rx in
+ the list, searching backward from index position \a from. If \a
+ from is -1 (the default), the search starts at the last item.
+ Returns -1 if no item matched.
+
+ By default, this function is case sensitive.
+
+ \sa indexOf(), contains(), QRegExp::exactMatch()
+*/
+int QtPrivate::QStringList_lastIndexOf(const QStringList *that, const QRegExp &rx, int from)
+{
+ QRegExp rx2(rx);
+ return lastIndexOfMutating(that, rx2, from);
+}
+
+/*!
+ \fn int QStringList::lastIndexOf(QRegExp &rx, int from) const
+ \overload lastIndexOf()
+ \since 4.5
+
+ Returns the index position of the last exact match of \a rx in
+ the list, searching backward from index position \a from. If \a
+ from is -1 (the default), the search starts at the last item.
+ Returns -1 if no item matched.
+
+ By default, this function is case sensitive.
+
+ If an item matched, the \a rx regular expression will contain the
+ matched objects (see QRegExp::matchedLength, QRegExp::cap).
+
+ \sa indexOf(), contains(), QRegExp::exactMatch()
+*/
+int QtPrivate::QStringList_lastIndexOf(const QStringList *that, QRegExp &rx, int from)
+{
+ return lastIndexOfMutating(that, rx, from);
+}
+#endif
+
+/*!
+ \fn int QStringList::indexOf(const QString &value, int from = 0) const
+
+ Returns the index position of the first occurrence of \a value in
+ the list, searching forward from index position \a from. Returns
+ -1 if no item matched.
+
+ By default, this function is case sensitive.
+
+ \sa lastIndexOf(), contains(), QList::indexOf()
+*/
+
+/*!
+ \fn int QStringList::lastIndexOf(const QString &value, int from = -1) const
+
+ Returns the index position of the last occurrence of \a value in
+ the list, searching backward from index position \a from. If \a
+ from is -1 (the default), the search starts at the last item.
+ Returns -1 if no item matched.
+
+ By default, this function is case sensitive.
+
+ \sa indexOf(), QList::lastIndexOf()
+*/
+
+/*!
+ \fn int QStringList::removeDuplicates()
+
+ \since 4.5
+
+ This function removes duplicate entries from a list.
+ The entries do not have to be sorted. They will retain their
+ original order.
+
+ Returns the number of removed entries.
+*/
+int QtPrivate::QStringList_removeDuplicates(QStringList *that)
+{
+ int n = that->size();
+ int j = 0;
+ QSet<QString> seen;
+ seen.reserve(n);
+ for (int i = 0; i < n; ++i) {
+ const QString &s = that->at(i);
+ if (seen.contains(s))
+ continue;
+ seen.insert(s);
+ if (j != i)
+ (*that)[j] = s;
+ ++j;
+ }
+ if (n != j)
+ that->erase(that->begin() + j, that->end());
+ return n - j;
+}
+
+QT_END_NAMESPACE
diff --git a/src/corelib/tools/qstringlist.h b/src/corelib/tools/qstringlist.h
new file mode 100644
index 0000000000..37f7ff2b92
--- /dev/null
+++ b/src/corelib/tools/qstringlist.h
@@ -0,0 +1,259 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSTRINGLIST_H
+#define QSTRINGLIST_H
+
+#include <QtCore/qalgorithms.h>
+#include <QtCore/qdatastream.h>
+#include <QtCore/qlist.h>
+#include <QtCore/qregexp.h>
+#include <QtCore/qstring.h>
+#include <QtCore/qstringmatcher.h>
+#ifdef QT_INCLUDE_COMPAT
+#include <Qt3Support/q3valuelist.h>
+#endif
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Core)
+
+class QRegExp;
+
+typedef QListIterator<QString> QStringListIterator;
+typedef QMutableListIterator<QString> QMutableStringListIterator;
+
+class QStringList : public QList<QString>
+{
+public:
+ inline QStringList() { }
+ inline explicit QStringList(const QString &i) { append(i); }
+ inline QStringList(const QStringList &l) : QList<QString>(l) { }
+ inline QStringList(const QList<QString> &l) : QList<QString>(l) { }
+
+ inline void sort();
+ inline int removeDuplicates();
+
+ inline QString join(const QString &sep) const;
+
+ inline QStringList filter(const QString &str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
+ inline QBool contains(const QString &str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
+
+ inline QStringList &replaceInStrings(const QString &before, const QString &after, Qt::CaseSensitivity cs = Qt::CaseSensitive);
+
+ inline QStringList operator+(const QStringList &other) const
+ { QStringList n = *this; n += other; return n; }
+ inline QStringList &operator<<(const QString &str)
+ { append(str); return *this; }
+ inline QStringList &operator<<(const QStringList &l)
+ { *this += l; return *this; }
+
+#ifndef QT_NO_REGEXP
+ inline QStringList filter(const QRegExp &rx) const;
+ inline QStringList &replaceInStrings(const QRegExp &rx, const QString &after);
+ inline int indexOf(const QRegExp &rx, int from = 0) const;
+ inline int lastIndexOf(const QRegExp &rx, int from = -1) const;
+ inline int indexOf(QRegExp &rx, int from = 0) const;
+ inline int lastIndexOf(QRegExp &rx, int from = -1) const;
+#endif
+#if !defined(Q_NO_USING_KEYWORD)
+ using QList<QString>::indexOf;
+ using QList<QString>::lastIndexOf;
+#else
+ inline int indexOf(const QString &str, int from = 0) const
+ { return QList<QString>::indexOf(str, from); }
+ inline int lastIndexOf(const QString &str, int from = -1) const
+ { return QList<QString>::lastIndexOf(str, from); }
+#endif
+#ifdef QT3_SUPPORT
+ static inline QT3_SUPPORT QStringList split(const QString &sep, const QString &str, bool allowEmptyEntries = false);
+ static inline QT3_SUPPORT QStringList split(const QChar &sep, const QString &str, bool allowEmptyEntries = false);
+ inline QT3_SUPPORT QStringList grep(const QString &str, bool cs = true) const
+ { return filter(str, cs ? Qt::CaseSensitive : Qt::CaseInsensitive); }
+
+#ifndef QT_NO_REGEXP
+ static inline QT3_SUPPORT QStringList split(const QRegExp &sep, const QString &str, bool allowEmptyEntries = false);
+ inline QT3_SUPPORT QStringList grep(const QRegExp &rx) const { return filter(rx); }
+ inline QT3_SUPPORT QStringList &gres(const QRegExp &rx, const QString &after)
+ { return replaceInStrings(rx, after); }
+#endif
+ inline QT3_SUPPORT QStringList &gres(const QString &before, const QString &after, bool cs = true)
+ { return replaceInStrings(before, after, cs ? Qt::CaseSensitive : Qt::CaseInsensitive); }
+
+ inline Iterator QT3_SUPPORT fromLast() { return (isEmpty() ? end() : --end()); }
+ inline ConstIterator QT3_SUPPORT fromLast() const { return (isEmpty() ? end() : --end()); }
+#endif
+};
+
+namespace QtPrivate {
+ void Q_CORE_EXPORT QStringList_sort(QStringList *that);
+ int Q_CORE_EXPORT QStringList_removeDuplicates(QStringList *that);
+ QString Q_CORE_EXPORT QStringList_join(const QStringList *that, const QString &sep);
+ QStringList Q_CORE_EXPORT QStringList_filter(const QStringList *that, const QString &str,
+ Qt::CaseSensitivity cs);
+
+ QBool Q_CORE_EXPORT QStringList_contains(const QStringList *that, const QString &str, Qt::CaseSensitivity cs);
+ void Q_CORE_EXPORT QStringList_replaceInStrings(QStringList *that, const QString &before, const QString &after,
+ Qt::CaseSensitivity cs);
+
+#ifndef QT_NO_REGEXP
+ void Q_CORE_EXPORT QStringList_replaceInStrings(QStringList *that, const QRegExp &rx, const QString &after);
+ QStringList Q_CORE_EXPORT QStringList_filter(const QStringList *that, const QRegExp &re);
+ int Q_CORE_EXPORT QStringList_indexOf(const QStringList *that, const QRegExp &rx, int from);
+ int Q_CORE_EXPORT QStringList_lastIndexOf(const QStringList *that, const QRegExp &rx, int from);
+ int Q_CORE_EXPORT QStringList_indexOf(const QStringList *that, QRegExp &rx, int from);
+ int Q_CORE_EXPORT QStringList_lastIndexOf(const QStringList *that, QRegExp &rx, int from);
+#endif
+}
+
+inline void QStringList::sort()
+{
+ QtPrivate::QStringList_sort(this);
+}
+
+inline int QStringList::removeDuplicates()
+{
+ return QtPrivate::QStringList_removeDuplicates(this);
+}
+
+inline QString QStringList::join(const QString &sep) const
+{
+ return QtPrivate::QStringList_join(this, sep);
+}
+
+inline QStringList QStringList::filter(const QString &str, Qt::CaseSensitivity cs) const
+{
+ return QtPrivate::QStringList_filter(this, str, cs);
+}
+
+inline QBool QStringList::contains(const QString &str, Qt::CaseSensitivity cs) const
+{
+ return QtPrivate::QStringList_contains(this, str, cs);
+}
+
+inline QStringList &QStringList::replaceInStrings(const QString &before, const QString &after, Qt::CaseSensitivity cs)
+{
+ QtPrivate::QStringList_replaceInStrings(this, before, after, cs);
+ return *this;
+}
+
+#ifndef QT_NO_REGEXP
+inline QStringList &QStringList::replaceInStrings(const QRegExp &rx, const QString &after)
+{
+ QtPrivate::QStringList_replaceInStrings(this, rx, after);
+ return *this;
+}
+
+inline QStringList QStringList::filter(const QRegExp &rx) const
+{
+ return QtPrivate::QStringList_filter(this, rx);
+}
+
+inline int QStringList::indexOf(const QRegExp &rx, int from) const
+{
+ return QtPrivate::QStringList_indexOf(this, rx, from);
+}
+
+inline int QStringList::lastIndexOf(const QRegExp &rx, int from) const
+{
+ return QtPrivate::QStringList_lastIndexOf(this, rx, from);
+}
+
+inline int QStringList::indexOf(QRegExp &rx, int from) const
+{
+ return QtPrivate::QStringList_indexOf(this, rx, from);
+}
+
+inline int QStringList::lastIndexOf(QRegExp &rx, int from) const
+{
+ return QtPrivate::QStringList_lastIndexOf(this, rx, from);
+}
+#endif
+
+
+#ifdef QT3_SUPPORT
+inline QStringList QStringList::split(const QChar &sep, const QString &str, bool allowEmptyEntries)
+{
+ if (str.isEmpty())
+ return QStringList();
+ return str.split(sep, allowEmptyEntries ? QString::KeepEmptyParts
+ : QString::SkipEmptyParts);
+}
+
+inline QStringList QStringList::split(const QString &sep, const QString &str, bool allowEmptyEntries)
+{
+ if (str.isEmpty())
+ return QStringList();
+ return str.split(sep, allowEmptyEntries ? QString::KeepEmptyParts
+ : QString::SkipEmptyParts);
+}
+
+#ifndef QT_NO_REGEXP
+inline QStringList QStringList::split(const QRegExp &sep, const QString &str, bool allowEmptyEntries)
+{
+ if (str.isEmpty())
+ return QStringList();
+ return str.split(sep, allowEmptyEntries ? QString::KeepEmptyParts
+ : QString::SkipEmptyParts);
+}
+#endif // QT_NO_REGEXP
+
+#endif // QT3_SUPPORT
+
+
+#ifndef QT_NO_DATASTREAM
+inline QDataStream &operator>>(QDataStream &in, QStringList &list)
+{
+ return operator>>(in, static_cast<QList<QString> &>(list));
+}
+inline QDataStream &operator<<(QDataStream &out, const QStringList &list)
+{
+ return operator<<(out, static_cast<const QList<QString> &>(list));
+}
+#endif // QT_NO_DATASTREAM
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QSTRINGLIST_H
diff --git a/src/corelib/tools/qstringmatcher.cpp b/src/corelib/tools/qstringmatcher.cpp
new file mode 100644
index 0000000000..badc4c6115
--- /dev/null
+++ b/src/corelib/tools/qstringmatcher.cpp
@@ -0,0 +1,323 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qstringmatcher.h"
+#include "qunicodetables_p.h"
+
+QT_BEGIN_NAMESPACE
+
+static void bm_init_skiptable(const ushort *uc, int len, uchar *skiptable, Qt::CaseSensitivity cs)
+{
+ int l = qMin(len, 255);
+ memset(skiptable, l, 256*sizeof(uchar));
+ uc += len - l;
+ if (cs == Qt::CaseSensitive) {
+ while (l--) {
+ skiptable[*uc & 0xff] = l;
+ uc++;
+ }
+ } else {
+ const ushort *start = uc;
+ while (l--) {
+ skiptable[foldCase(uc, start) & 0xff] = l;
+ uc++;
+ }
+ }
+}
+
+static inline int bm_find(const ushort *uc, uint l, int index, const ushort *puc, uint pl,
+ const uchar *skiptable, Qt::CaseSensitivity cs)
+{
+ if (pl == 0)
+ return index > (int)l ? -1 : index;
+ const uint pl_minus_one = pl - 1;
+
+ register const ushort *current = uc + index + pl_minus_one;
+ const ushort *end = uc + l;
+ if (cs == Qt::CaseSensitive) {
+ while (current < end) {
+ uint skip = skiptable[*current & 0xff];
+ 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 - uc) - pl_minus_one;
+
+ // 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) & 0xff] == pl)
+ skip = pl - skip;
+ else
+ skip = 1;
+ }
+ if (current > end - skip)
+ break;
+ current += skip;
+ }
+ } else {
+ while (current < end) {
+ uint skip = skiptable[foldCase(current, uc) & 0xff];
+ if (!skip) {
+ // possible match
+ while (skip < pl) {
+ if (foldCase(current - skip, uc) != foldCase(puc + pl_minus_one - skip, puc))
+ break;
+ skip++;
+ }
+ if (skip > pl_minus_one) // we have a match
+ return (current - uc) - pl_minus_one;
+ // 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[foldCase(current - skip, uc) & 0xff] == pl)
+ skip = pl - skip;
+ else
+ skip = 1;
+ }
+ if (current > end - skip)
+ break;
+ current += skip;
+ }
+ }
+ return -1; // not found
+}
+
+/*!
+ \class QStringMatcher
+ \brief The QStringMatcher class holds a sequence of characters that
+ can be quickly matched in a Unicode string.
+
+ \ingroup tools
+ \ingroup text
+
+ This class is useful when you have a sequence of \l{QChar}s that
+ you want to repeatedly match against some strings (perhaps in a
+ loop), or when you want to search for the same sequence of
+ characters multiple times in the same string. Using a matcher
+ object and indexIn() is faster than matching a plain QString with
+ QString::indexOf() if repeated matching takes place. This class
+ offers no benefit if you are doing one-off string matches.
+
+ Create the QStringMatcher with the QString you want to search
+ for. Then call indexIn() on the QString that you want to search.
+
+ \sa QString, QByteArrayMatcher, QRegExp
+*/
+
+/*!
+ Constructs an empty string matcher that won't match anything.
+ Call setPattern() to give it a pattern to match.
+*/
+QStringMatcher::QStringMatcher()
+ : d_ptr(0), q_cs(Qt::CaseSensitive)
+{
+ qMemSet(q_data, 0, sizeof(q_data));
+}
+
+/*!
+ Constructs a string matcher that will search for \a pattern, with
+ case sensitivity \a cs.
+
+ Call indexIn() to perform a search.
+*/
+QStringMatcher::QStringMatcher(const QString &pattern, Qt::CaseSensitivity cs)
+ : d_ptr(0), q_pattern(pattern), q_cs(cs)
+{
+ p.uc = pattern.unicode();
+ p.len = pattern.size();
+ bm_init_skiptable((const ushort *)p.uc, p.len, p.q_skiptable, cs);
+}
+
+/*!
+ \fn QStringMatcher::QStringMatcher(const QChar *uc, int length, Qt::CaseSensitivity cs)
+ \since 4.5
+
+ Constructs a string matcher that will search for the pattern referred to
+ by \a uc with the given \a length and case sensitivity specified by \a cs.
+*/
+QStringMatcher::QStringMatcher(const QChar *uc, int len, Qt::CaseSensitivity cs)
+ : d_ptr(0), q_cs(cs)
+{
+ p.uc = uc;
+ p.len = len;
+ bm_init_skiptable((const ushort *)p.uc, len, p.q_skiptable, cs);
+}
+
+/*!
+ Copies the \a other string matcher to this string matcher.
+*/
+QStringMatcher::QStringMatcher(const QStringMatcher &other)
+ : d_ptr(0)
+{
+ operator=(other);
+}
+
+/*!
+ Destroys the string matcher.
+*/
+QStringMatcher::~QStringMatcher()
+{
+}
+
+/*!
+ Assigns the \a other string matcher to this string matcher.
+*/
+QStringMatcher &QStringMatcher::operator=(const QStringMatcher &other)
+{
+ if (this != &other) {
+ q_pattern = other.q_pattern;
+ q_cs = other.q_cs;
+ qMemCopy(q_data, other.q_data, sizeof(q_data));
+ }
+ return *this;
+}
+
+/*!
+ Sets the string that this string matcher will search for to \a
+ pattern.
+
+ \sa pattern(), setCaseSensitivity(), indexIn()
+*/
+void QStringMatcher::setPattern(const QString &pattern)
+{
+ q_pattern = pattern;
+ p.uc = pattern.unicode();
+ p.len = pattern.size();
+ bm_init_skiptable((const ushort *)pattern.unicode(), pattern.size(), p.q_skiptable, q_cs);
+}
+
+/*!
+ \fn QString QStringMatcher::pattern() const
+
+ Returns the string pattern that this string matcher will search
+ for.
+
+ \sa setPattern()
+*/
+
+QString QStringMatcher::pattern() const
+{
+ if (!q_pattern.isEmpty())
+ return q_pattern;
+ return QString(p.uc, p.len);
+}
+
+/*!
+ Sets the case sensitivity setting of this string matcher to \a
+ cs.
+
+ \sa caseSensitivity(), setPattern(), indexIn()
+*/
+void QStringMatcher::setCaseSensitivity(Qt::CaseSensitivity cs)
+{
+ if (cs == q_cs)
+ return;
+ bm_init_skiptable((const ushort *)q_pattern.unicode(), q_pattern.size(), p.q_skiptable, cs);
+ q_cs = cs;
+}
+
+/*!
+ Searches the string \a str from character position \a from
+ (default 0, i.e. from the first character), for the string
+ 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.
+
+ \sa setPattern(), setCaseSensitivity()
+*/
+int QStringMatcher::indexIn(const QString &str, int from) const
+{
+ if (from < 0)
+ from = 0;
+ return bm_find((const ushort *)str.unicode(), str.size(), from,
+ (const ushort *)p.uc, p.len,
+ p.q_skiptable, q_cs);
+}
+
+/*!
+ \since 4.5
+
+ Searches the string starting at \a str (of length \a length) from
+ character position \a from (default 0, i.e. from the first
+ character), for the string 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.
+
+ \sa setPattern(), setCaseSensitivity()
+*/
+int QStringMatcher::indexIn(const QChar *str, int length, int from) const
+{
+ if (from < 0)
+ from = 0;
+ return bm_find((const ushort *)str, length, from,
+ (const ushort *)p.uc, p.len,
+ p.q_skiptable, q_cs);
+}
+
+/*!
+ \fn Qt::CaseSensitivity QStringMatcher::caseSensitivity() const
+
+ Returns the case sensitivity setting for this string matcher.
+
+ \sa setCaseSensitivity()
+*/
+
+/*!
+ \internal
+*/
+
+int qFindStringBoyerMoore(
+ const QChar *haystack, int haystackLen, int haystackOffset,
+ const QChar *needle, int needleLen, Qt::CaseSensitivity cs)
+{
+ uchar skiptable[256];
+ bm_init_skiptable((const ushort *)needle, needleLen, skiptable, cs);
+ if (haystackOffset < 0)
+ haystackOffset = 0;
+ return bm_find((const ushort *)haystack, haystackLen, haystackOffset,
+ (const ushort *)needle, needleLen, skiptable, cs);
+}
+
+QT_END_NAMESPACE
diff --git a/src/corelib/tools/qstringmatcher.h b/src/corelib/tools/qstringmatcher.h
new file mode 100644
index 0000000000..26fe0dc432
--- /dev/null
+++ b/src/corelib/tools/qstringmatcher.h
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSTRINGMATCHER_H
+#define QSTRINGMATCHER_H
+
+#include <QtCore/qstring.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Core)
+
+class QStringMatcherPrivate;
+
+class Q_CORE_EXPORT QStringMatcher
+{
+public:
+ QStringMatcher();
+ QStringMatcher(const QString &pattern,
+ Qt::CaseSensitivity cs = Qt::CaseSensitive);
+ QStringMatcher(const QChar *uc, int len,
+ Qt::CaseSensitivity cs = Qt::CaseSensitive);
+ QStringMatcher(const QStringMatcher &other);
+ ~QStringMatcher();
+
+ QStringMatcher &operator=(const QStringMatcher &other);
+
+ void setPattern(const QString &pattern);
+ void setCaseSensitivity(Qt::CaseSensitivity cs);
+
+ int indexIn(const QString &str, int from = 0) const;
+ int indexIn(const QChar *str, int length, int from = 0) const;
+ QString pattern() const;
+ inline Qt::CaseSensitivity caseSensitivity() const { return q_cs; }
+
+private:
+ QStringMatcherPrivate *d_ptr;
+ QString q_pattern;
+ Qt::CaseSensitivity q_cs;
+#ifdef Q_CC_RVCT
+// explicitely allow anonymous unions for RVCT to prevent compiler warnings
+#pragma anon_unions
+#endif
+ union {
+ uint q_data[256];
+ struct {
+ uchar q_skiptable[256];
+ const QChar *uc;
+ int len;
+ } p;
+ };
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QSTRINGMATCHER_H
diff --git a/src/corelib/tools/qtextboundaryfinder.cpp b/src/corelib/tools/qtextboundaryfinder.cpp
new file mode 100644
index 0000000000..bc9b675324
--- /dev/null
+++ b/src/corelib/tools/qtextboundaryfinder.cpp
@@ -0,0 +1,476 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "private/qharfbuzz_p.h"
+#include <QtCore/qtextboundaryfinder.h>
+#include <QtCore/qvarlengtharray.h>
+#include <private/qunicodetables_p.h>
+#include <qdebug.h>
+
+QT_BEGIN_NAMESPACE
+
+class QTextBoundaryFinderPrivate
+{
+public:
+ HB_CharAttributes attributes[1];
+};
+
+static void init(QTextBoundaryFinder::BoundaryType type, const QChar *chars, int length, HB_CharAttributes *attributes)
+{
+ QVarLengthArray<HB_ScriptItem> scriptItems;
+
+ const ushort *string = reinterpret_cast<const ushort *>(chars);
+ const ushort *unicode = string;
+ // correctly assign script, isTab and isObject to the script analysis
+ const ushort *uc = unicode;
+ const ushort *e = uc + length;
+ int script = QUnicodeTables::Common;
+ int lastScript = QUnicodeTables::Common;
+ const ushort *start = uc;
+ while (uc < e) {
+ int s = QUnicodeTables::script(*uc);
+ if (s != QUnicodeTables::Inherited)
+ script = s;
+ if (*uc == QChar::ObjectReplacementCharacter || *uc == QChar::LineSeparator || *uc == 9)
+ script = QUnicodeTables::Common;
+ if (script != lastScript) {
+ if (uc != start) {
+ HB_ScriptItem item;
+ item.pos = start - string;
+ item.length = uc - start;
+ item.script = (HB_Script)lastScript;
+ item.bidiLevel = 0; // ### what's the proper value?
+ scriptItems.append(item);
+ start = uc;
+ }
+ lastScript = script;
+ }
+ ++uc;
+ }
+ if (uc != start) {
+ HB_ScriptItem item;
+ item.pos = start - string;
+ item.length = uc - start;
+ item.script = (HB_Script)lastScript;
+ item.bidiLevel = 0; // ### what's the proper value?
+ scriptItems.append(item);
+ }
+
+ qGetCharAttributes(string, length, scriptItems.data(), scriptItems.count(), attributes);
+ if (type == QTextBoundaryFinder::Word)
+ HB_GetWordBoundaries(string, length, scriptItems.data(), scriptItems.count(), attributes);
+ else if (type == QTextBoundaryFinder::Sentence)
+ HB_GetSentenceBoundaries(string, length, scriptItems.data(), scriptItems.count(), attributes);
+}
+
+/*! \class QTextBoundaryFinder
+
+ \brief The QTextBoundaryFinder class provides a way of finding Unicode text boundaries in a string.
+
+ \since 4.4
+ \ingroup tools
+ \ingroup shared
+ \ingroup text
+ \reentrant
+
+ QTextBoundaryFinder allows to find Unicode text boundaries in a
+ string, similar to the Unicode text boundary specification (see
+ http://www.unicode.org/reports/tr29/tr29-11.html).
+
+ QTextBoundaryFinder can operate on a QString in four possible
+ modes depending on the value of \a BoundaryType.
+
+ Units of Unicode characters that make up what the user thinks of
+ as a character or basic unit of the language are here called
+ Grapheme clusters. The two unicode characters 'A' + diaeresis do
+ for example form one grapheme cluster as the user thinks of them
+ as one character, yet it is in this case represented by two
+ unicode code points.
+
+ Word boundaries are there to locate the start and end of what a
+ language considers to be a word.
+
+ Line break boundaries give possible places where a line break
+ might happen and sentence boundaries will show the beginning and
+ end of whole sentences.
+*/
+
+/*!
+ \enum QTextBoundaryFinder::BoundaryType
+
+ \value Grapheme Finds a grapheme which is the smallest boundary. It
+ including letters, punctation marks, numerals and more.
+ \value Word Finds a word.
+ \value Line Finds possible positions for breaking the text into multiple
+ lines.
+ \value Sentence Finds sentence boundaries. These include periods, question
+ marks etc.
+*/
+
+/*!
+ \enum QTextBoundaryFinder::BoundaryReason
+
+ \value NotAtBoundary The boundary finder is not at a boundary position.
+ \value StartWord The boundary finder is at the start of a word.
+ \value EndWord The boundary finder is at the end of a word.
+*/
+
+/*!
+ Constructs an invalid QTextBoundaryFinder object.
+*/
+QTextBoundaryFinder::QTextBoundaryFinder()
+ : t(Grapheme)
+ , chars(0)
+ , length(0)
+ , freePrivate(true)
+ , d(0)
+{
+}
+
+/*!
+ Copies the QTextBoundaryFinder object, \a other.
+*/
+QTextBoundaryFinder::QTextBoundaryFinder(const QTextBoundaryFinder &other)
+ : t(other.t)
+ , s(other.s)
+ , chars(other.chars)
+ , length(other.length)
+ , pos(other.pos)
+ , freePrivate(true)
+{
+ d = (QTextBoundaryFinderPrivate *) malloc(length*sizeof(HB_CharAttributes));
+ memcpy(d, other.d, length*sizeof(HB_CharAttributes));
+}
+
+/*!
+ Assigns the object, \a other, to another QTextBoundaryFinder object.
+*/
+QTextBoundaryFinder &QTextBoundaryFinder::operator=(const QTextBoundaryFinder &other)
+{
+ if (&other == this)
+ return *this;
+
+ t = other.t;
+ s = other.s;
+ chars = other.chars;
+ length = other.length;
+ pos = other.pos;
+ freePrivate = true;
+
+ d = (QTextBoundaryFinderPrivate *) realloc(d, length*sizeof(HB_CharAttributes));
+ memcpy(d, other.d, length*sizeof(HB_CharAttributes));
+
+ return *this;
+}
+
+/*!
+ Destructs the QTextBoundaryFinder object.
+*/
+QTextBoundaryFinder::~QTextBoundaryFinder()
+{
+ if (freePrivate)
+ free(d);
+}
+
+/*!
+ Creates a QTextBoundaryFinder object of \a type operating on \a string.
+*/
+QTextBoundaryFinder::QTextBoundaryFinder(BoundaryType type, const QString &string)
+ : t(type)
+ , s(string)
+ , chars(string.unicode())
+ , length(string.length())
+ , pos(0)
+ , freePrivate(true)
+{
+ d = (QTextBoundaryFinderPrivate *) malloc(length*sizeof(HB_CharAttributes));
+ init(t, chars, length, d->attributes);
+}
+
+/*!
+ Creates a QTextBoundaryFinder object of \a type operating on \a chars
+ with \a length.
+
+ \a buffer is an optional working buffer of size \a bufferSize you can pass to
+ the QTextBoundaryFinder. If the buffer is large enough to hold the working
+ data required, it will use this instead of allocating its own buffer.
+
+ \warning QTextBoundaryFinder does not create a copy of \a chars. It is the
+ application programmer's responsability to ensure the array is allocated for
+ as long as the QTextBoundaryFinder object stays alive. The same applies to
+ \a buffer.
+*/
+QTextBoundaryFinder::QTextBoundaryFinder(BoundaryType type, const QChar *chars, int length, unsigned char *buffer, int bufferSize)
+ : t(type)
+ , chars(chars)
+ , length(length)
+ , pos(0)
+{
+ if (buffer && (uint)bufferSize >= length*sizeof(HB_CharAttributes)) {
+ d = (QTextBoundaryFinderPrivate *)buffer;
+ freePrivate = false;
+ } else {
+ d = (QTextBoundaryFinderPrivate *) malloc(length*sizeof(HB_CharAttributes));
+ freePrivate = true;
+ }
+ init(t, chars, length, d->attributes);
+}
+
+/*!
+ Moves the finder to the start of the string. This is equivalent to setPosition(0).
+
+ \sa setPosition(), position()
+*/
+void QTextBoundaryFinder::toStart()
+{
+ pos = 0;
+}
+
+/*!
+ Moves the finder to the end of the string. This is equivalent to setPosition(string.length()).
+
+ \sa setPosition(), position()
+*/
+void QTextBoundaryFinder::toEnd()
+{
+ pos = length;
+}
+
+/*!
+ Returns the current position of the QTextBoundaryFinder.
+
+ The range is from 0 (the beginning of the string) to the length of
+ the string inclusive.
+
+ \sa setPosition()
+*/
+int QTextBoundaryFinder::position() const
+{
+ return pos;
+}
+
+/*!
+ Sets the current position of the QTextBoundaryFinder to \a position.
+
+ If \a position is out of bounds, it will be bound to only valid
+ positions. In this case, valid positions are from 0 to the length of
+ the string inclusive.
+
+ \sa position()
+*/
+void QTextBoundaryFinder::setPosition(int position)
+{
+ pos = qBound(0, position, length);
+}
+
+/*! \fn QTextBoundaryFinder::BoundaryType QTextBoundaryFinder::type() const
+
+ Returns the type of the QTextBoundaryFinder.
+*/
+
+/*! \fn bool QTextBoundaryFinder::isValid() const
+
+ Returns true if the text boundary finder is valid; otherwise returns false.
+ A default QTextBoundaryFinder is invalid.
+*/
+
+/*!
+ Returns the string the QTextBoundaryFinder object operates on.
+*/
+QString QTextBoundaryFinder::string() const
+{
+ if (chars == s.unicode() && length == s.length())
+ return s;
+ return QString(chars, length);
+}
+
+
+/*!
+ Moves the QTextBoundaryFinder to the next boundary position and returns that position.
+
+ Returns -1 is there is no next boundary.
+*/
+int QTextBoundaryFinder::toNextBoundary()
+{
+ if (!d) {
+ pos = -1;
+ return pos;
+ }
+
+ if (pos < 0 || pos >= length) {
+ pos = -1;
+ return pos;
+ }
+ ++pos;
+ if (pos == length)
+ return pos;
+
+ switch(t) {
+ case Grapheme:
+ while (pos < length && !d->attributes[pos].charStop)
+ ++pos;
+ break;
+ case Word:
+ while (pos < length && !d->attributes[pos].wordBoundary)
+ ++pos;
+ break;
+ case Sentence:
+ while (pos < length && !d->attributes[pos].sentenceBoundary)
+ ++pos;
+ break;
+ case Line:
+ while (pos < length && d->attributes[pos].lineBreakType < HB_Break)
+ ++pos;
+ break;
+ }
+
+ return pos;
+}
+
+/*!
+ Moves the QTextBoundaryFinder to the previous boundary position and returns that position.
+
+ Returns -1 is there is no previous boundary.
+*/
+int QTextBoundaryFinder::toPreviousBoundary()
+{
+ if (!d) {
+ pos = -1;
+ return pos;
+ }
+
+ if (pos <= 0 || pos > length) {
+ pos = -1;
+ return pos;
+ }
+ --pos;
+ if (pos == 0)
+ return pos;
+
+ switch(t) {
+ case Grapheme:
+ while (pos > 0 && !d->attributes[pos].charStop)
+ --pos;
+ break;
+ case Word:
+ while (pos > 0 && !d->attributes[pos].wordBoundary)
+ --pos;
+ break;
+ case Sentence:
+ while (pos > 0 && !d->attributes[pos].sentenceBoundary)
+ --pos;
+ break;
+ case Line:
+ while (pos > 0 && d->attributes[pos].lineBreakType < HB_Break)
+ --pos;
+ break;
+ }
+
+ return pos;
+}
+
+/*!
+ Returns true if the object's position() is currently at a valid text boundary.
+*/
+bool QTextBoundaryFinder::isAtBoundary() const
+{
+ if (!d || pos < 0)
+ return false;
+
+ if (pos == length)
+ return true;
+
+ switch(t) {
+ case Grapheme:
+ return d->attributes[pos].charStop;
+ case Word:
+ return d->attributes[pos].wordBoundary;
+ case Line:
+ return d->attributes[pos].lineBreakType >= HB_Break;
+ case Sentence:
+ return d->attributes[pos].sentenceBoundary;
+ }
+ return false;
+}
+
+/*!
+ Returns the reasons for the boundary finder to have chosen the current position as a boundary.
+*/
+QTextBoundaryFinder::BoundaryReasons QTextBoundaryFinder::boundaryReasons() const
+{
+ if (!d)
+ return NotAtBoundary;
+ if (! isAtBoundary())
+ return NotAtBoundary;
+ if (pos == 0) {
+ if (d->attributes[pos].whiteSpace)
+ return NotAtBoundary;
+ return StartWord;
+ }
+ if (pos >= length - 1) {
+ if (d->attributes[length-1].whiteSpace)
+ return NotAtBoundary;
+ return EndWord;
+ }
+
+ BoundaryReasons answer;
+ const bool nextIsSpace = d->attributes[pos + 1].whiteSpace;
+ const bool prevIsSpace = d->attributes[pos - 1].whiteSpace;
+
+ if (d->attributes[pos].whiteSpace)
+ answer = EndWord;
+ else if (!prevIsSpace) {
+ answer = StartWord;
+ answer |= EndWord;
+ }
+
+ if (prevIsSpace)
+ answer |= StartWord;
+ if (nextIsSpace)
+ answer |= EndWord;
+ if (answer == 0) {
+ answer = StartWord;
+ answer |= EndWord;
+ }
+
+ return answer;
+}
+
+QT_END_NAMESPACE
diff --git a/src/corelib/tools/qtextboundaryfinder.h b/src/corelib/tools/qtextboundaryfinder.h
new file mode 100644
index 0000000000..095e2909ec
--- /dev/null
+++ b/src/corelib/tools/qtextboundaryfinder.h
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTEXTBOUNDARYFINDER_H
+#define QTEXTBOUNDARYFINDER_H
+
+#include <QtCore/qchar.h>
+#include <QtCore/qstring.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Core)
+
+class QTextBoundaryFinderPrivate;
+
+class Q_CORE_EXPORT QTextBoundaryFinder
+{
+public:
+ QTextBoundaryFinder();
+ QTextBoundaryFinder(const QTextBoundaryFinder &other);
+ QTextBoundaryFinder &operator=(const QTextBoundaryFinder &other);
+ ~QTextBoundaryFinder();
+
+ enum BoundaryType {
+ Grapheme,
+ Word,
+ Line,
+ Sentence
+ };
+
+ enum BoundaryReason {
+ NotAtBoundary = 0,
+ StartWord = 1,
+ EndWord = 2
+ //Hyphen
+ };
+ Q_DECLARE_FLAGS( BoundaryReasons, BoundaryReason )
+
+ QTextBoundaryFinder(BoundaryType type, const QString &string);
+ QTextBoundaryFinder(BoundaryType type, const QChar *chars, int length, unsigned char *buffer = 0, int bufferSize = 0);
+
+ inline bool isValid() const { return d; }
+
+ inline BoundaryType type() const { return t; }
+ QString string() const;
+
+ void toStart();
+ void toEnd();
+ int position() const;
+ void setPosition(int position);
+
+ int toNextBoundary();
+ int toPreviousBoundary();
+
+ bool isAtBoundary() const;
+ BoundaryReasons boundaryReasons() const;
+
+private:
+ BoundaryType t;
+ QString s;
+ const QChar *chars;
+ int length;
+ int pos;
+ uint freePrivate : 1;
+ uint unused : 31;
+ QTextBoundaryFinderPrivate *d;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
+
diff --git a/src/corelib/tools/qtimeline.cpp b/src/corelib/tools/qtimeline.cpp
new file mode 100644
index 0000000000..2979a090b1
--- /dev/null
+++ b/src/corelib/tools/qtimeline.cpp
@@ -0,0 +1,773 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtimeline.h"
+
+#include <private/qobject_p.h>
+#include <QtCore/qdatetime.h>
+#include <QtCore/qcoreevent.h>
+#include <QtCore/qmath.h>
+
+QT_BEGIN_NAMESPACE
+
+static const qreal pi = qreal(3.14159265359);
+static const qreal halfPi = pi / qreal(2.0);
+
+
+static inline qreal qt_sinProgress(qreal value)
+{
+ return qSin((value * pi) - halfPi) / 2 + qreal(0.5);
+}
+
+static inline qreal qt_smoothBeginEndMixFactor(qreal value)
+{
+ return qMin(qMax(1 - value * 2 + qreal(0.3), qreal(0.0)), qreal(1.0));
+}
+
+class QTimeLinePrivate : public QObjectPrivate
+{
+ Q_DECLARE_PUBLIC(QTimeLine)
+public:
+ inline QTimeLinePrivate()
+ : startTime(0), duration(1000), startFrame(0), endFrame(0),
+ updateInterval(1000 / 25),
+ totalLoopCount(1), currentLoopCount(0), currentTime(0), timerId(0),
+ direction(QTimeLine::Forward), curveShape(QTimeLine::EaseInOutCurve),
+ state(QTimeLine::NotRunning)
+ { }
+
+ int startTime;
+ int duration;
+ int startFrame;
+ int endFrame;
+ int updateInterval;
+ int totalLoopCount;
+ int currentLoopCount;
+
+ int currentTime;
+ int elapsedTime;
+ int timerId;
+ QTime timer;
+
+ QTimeLine::Direction direction;
+ QTimeLine::CurveShape curveShape;
+ QTimeLine::State state;
+ inline void setState(QTimeLine::State newState)
+ {
+ Q_Q(QTimeLine);
+ if (newState != state)
+ emit q->stateChanged(state = newState);
+ }
+
+ void setCurrentTime(int msecs);
+};
+
+/*!
+ \internal
+*/
+void QTimeLinePrivate::setCurrentTime(int msecs)
+{
+ Q_Q(QTimeLine);
+
+ qreal lastValue = q->currentValue();
+ int lastFrame = q->currentFrame();
+
+ // Determine if we are looping.
+ int elapsed = (direction == QTimeLine::Backward) ? (-msecs + duration) : msecs;
+ int loopCount = elapsed / duration;
+
+ bool looping = (loopCount != currentLoopCount);
+#ifdef QTIMELINE_DEBUG
+ qDebug() << "QTimeLinePrivate::setCurrentTime:" << msecs << duration << "with loopCount" << loopCount
+ << "currentLoopCount" << currentLoopCount
+ << "looping" << looping;
+#endif
+ if (looping)
+ currentLoopCount = loopCount;
+
+ // Normalize msecs to be between 0 and duration, inclusive.
+ currentTime = elapsed % duration;
+ if (direction == QTimeLine::Backward)
+ currentTime = duration - currentTime;
+
+ // Check if we have reached the end of loopcount.
+ bool finished = false;
+ if (totalLoopCount && currentLoopCount >= totalLoopCount) {
+ finished = true;
+ currentTime = (direction == QTimeLine::Backward) ? 0 : duration;
+ currentLoopCount = totalLoopCount - 1;
+ }
+
+ int currentFrame = q->frameForTime(currentTime);
+#ifdef QTIMELINE_DEBUG
+ qDebug() << "QTimeLinePrivate::setCurrentTime: frameForTime" << currentTime << currentFrame;
+#endif
+ if (lastValue != q->currentValue())
+ emit q->valueChanged(q->currentValue());
+ if (lastFrame != currentFrame) {
+ const int transitionframe = (direction == QTimeLine::Forward ? endFrame : startFrame);
+ if (looping && !finished && transitionframe != currentFrame) {
+#ifdef QTIMELINE_DEBUG
+ qDebug() << "QTimeLinePrivate::setCurrentTime: transitionframe";
+#endif
+ emit q->frameChanged(transitionframe);
+ }
+#ifdef QTIMELINE_DEBUG
+ else {
+ QByteArray reason;
+ if (!looping)
+ reason += " not looping";
+ if (finished) {
+ if (!reason.isEmpty())
+ reason += " and";
+ reason += " finished";
+ }
+ if (transitionframe == currentFrame) {
+ if (!reason.isEmpty())
+ reason += " and";
+ reason += " transitionframe is equal to currentFrame: " + QByteArray::number(currentFrame);
+ }
+ qDebug("QTimeLinePrivate::setCurrentTime: not transitionframe because %s", reason.constData());
+ }
+#endif
+ emit q->frameChanged(currentFrame);
+ }
+ if (finished && state == QTimeLine::Running) {
+ q->stop();
+ emit q->finished();
+ }
+}
+
+/*!
+ \class QTimeLine
+ \brief The QTimeLine class provides a timeline for controlling animations.
+ \since 4.2
+ \ingroup multimedia
+
+ It's most commonly used to animate a GUI control by calling a slot
+ periodically. You can construct a timeline by passing its duration in
+ milliseconds to QTimeLine's constructor. The timeline's duration describes
+ for how long the animation will run. Then you set a suitable frame range
+ by calling setFrameRange(). Finally connect the frameChanged() signal to a
+ suitable slot in the widget you wish to animate (e.g., setValue() in
+ QProgressBar). When you proceed to calling start(), QTimeLine will enter
+ Running state, and start emitting frameChanged() at regular intervals,
+ causing your widget's connected property's value to grow from the lower
+ end to the upper and of your frame range, at a steady rate. You can
+ specify the update interval by calling setUpdateInterval(). When done,
+ QTimeLine enters NotRunning state, and emits finished().
+
+ Example:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qtimeline.cpp 0
+
+ You can also use QTimeLine with the
+ \l{Graphics View}{Graphics View framework} for
+ animations. The QGraphicsItemAnimation class implements animation
+ of \l{QGraphicsItem}{QGraphicsItems} with a timeline.
+
+ By default the timeline runs once, from the beginning and towards the end,
+ upon which you must call start() again to restart from the beginning. To
+ make the timeline loop, you can call setLoopCount(), passing the number of
+ times the timeline should run before finishing. The direction can also be
+ changed, causing the timeline to run backward, by calling
+ setDirection(). You can also pause and unpause the timeline while it's
+ running by calling setPaused(). For interactive control, the
+ setCurrentTime() function is provided, which sets the time position of the
+ time line directly. Although most useful in NotRunning state, (e.g.,
+ connected to a valueChanged() signal in a QSlider,) this function can be
+ called at any time.
+
+ The frame interface is useful for standard widgets, but QTimeLine can be
+ used to control any type of animation. The heart of QTimeLine lies in the
+ valueForTime() function, which generates a \e value between 0 and 1 for a
+ given time. This value is typically used to describe the steps of an
+ animation, where 0 is the first step of an animation, and 1 is the last
+ step. When running, QTimeLine generates values between 0 and 1 by calling
+ valueForTime() and emitting valueChanged(). By default, valueForTime()
+ applies an interpolation algorithm to generate these value. You can choose
+ from a set of predefined timeline algorithms by calling
+ setCurveShape(). By default, QTimeLine uses the EaseInOut curve shape,
+ which provides a value that grows slowly, then grows steadily, and
+ finally grows slowly. For a custom timeline, you can reimplement
+ valueForTime(), in which case QTimeLine's curveShape property is ignored.
+
+ \sa QProgressBar, QProgressDialog, QGraphicsItemAnimation
+*/
+
+/*!
+ \enum QTimeLine::State
+
+ This enum describes the state of the timeline.
+
+ \value NotRunning The timeline is not running. This is the initial state
+ of QTimeLine, and the state QTimeLine reenters when finished. The current
+ time, frame and value remain unchanged until either setCurrentTime() is
+ called, or the timeline is started by calling start().
+
+ \value Paused The timeline is paused (i.e., temporarily
+ suspended). Calling setPaused(false) will resume timeline activity.
+
+ \value Running The timeline is running. While control is in the event
+ loop, QTimeLine will update its current time at regular intervals,
+ emitting valueChanged() and frameChanged() when appropriate.
+
+ \sa state(), stateChanged()
+*/
+
+/*!
+ \enum QTimeLine::Direction
+
+ This enum describes the direction of the timeline when in \l Running state.
+
+ \value Forward The current time of the timeline increases with time (i.e.,
+ moves from 0 and towards the end / duration).
+
+ \value Backward The current time of the timeline decreases with time (i.e.,
+ moves from the end / duration and towards 0).
+
+ \sa setDirection()
+*/
+
+/*!
+ \enum QTimeLine::CurveShape
+
+ This enum describes the default shape of QTimeLine's value curve. The
+ default, shape is EaseInOutCurve. The curve defines the relation
+ between the value and the timeline.
+
+ \value EaseInCurve The value starts growing slowly, then increases in speed.
+ \value EaseOutCurve The value starts growing steadily, then ends slowly.
+ \value EaseInOutCurve The value starts growing slowly, then runs steadily, then grows slowly again.
+ \value LinearCurve The value grows linearly (e.g., if the duration is 1000 ms,
+ the value at time 500 ms is 0.5).
+ \value SineCurve The value grows sinusoidally.
+ \value CosineCurve The value grows cosinusoidally.
+
+ \sa setCurveShape()
+*/
+
+/*!
+ \fn QTimeLine::valueChanged(qreal value)
+
+ QTimeLine emits this signal at regular intervals when in \l Running state,
+ but only if the current value changes. \a value is the current value. \a value is
+ a number between 0.0 and 1.0
+
+ \sa QTimeLine::setDuration(), QTimeLine::valueForTime(), QTimeLine::updateInterval
+*/
+
+/*!
+ \fn QTimeLine::frameChanged(int frame)
+
+ QTimeLine emits this signal at regular intervals when in \l Running state,
+ but only if the current frame changes. \a frame is the current frame number.
+
+ \sa QTimeLine::setFrameRange(), QTimeLine::updateInterval
+*/
+
+/*!
+ \fn QTimeLine::stateChanged(QTimeLine::State newState)
+
+ This signal is emitted whenever QTimeLine's state changes. The new state
+ is \a newState.
+*/
+
+/*!
+ \fn QTimeLine::finished()
+
+ This signal is emitted when QTimeLine finishes (i.e., reaches the end of
+ its time line), and does not loop.
+*/
+
+/*!
+ Constructs a timeline with a duration of \a duration milliseconds. \a
+ parent is passed to QObject's constructor. The default duration is 1000
+ milliseconds.
+ */
+QTimeLine::QTimeLine(int duration, QObject *parent)
+ : QObject(*new QTimeLinePrivate, parent)
+{
+ setDuration(duration);
+}
+
+/*!
+ Destroys the timeline.
+ */
+QTimeLine::~QTimeLine()
+{
+ Q_D(QTimeLine);
+
+ if (d->state == Running)
+ stop();
+}
+
+/*!
+ Returns the state of the timeline.
+
+ \sa start(), setPaused(), stop()
+*/
+QTimeLine::State QTimeLine::state() const
+{
+ Q_D(const QTimeLine);
+ return d->state;
+}
+
+/*!
+ \property QTimeLine::loopCount
+ \brief the number of times the timeline should loop before it's finished.
+
+ A loop count of of 0 means that the timeline will loop forever.
+
+ By default, this property contains a value of 1.
+*/
+int QTimeLine::loopCount() const
+{
+ Q_D(const QTimeLine);
+ return d->totalLoopCount;
+}
+void QTimeLine::setLoopCount(int count)
+{
+ Q_D(QTimeLine);
+ d->totalLoopCount = count;
+}
+
+/*!
+ \property QTimeLine::direction
+ \brief the direction of the timeline when QTimeLine is in \l Running
+ state.
+
+ This direction indicates whether the time moves from 0 towards the
+ timeline duration, or from the value of the duration and towards 0 after
+ start() has been called.
+
+ By default, this property is set to \l Forward.
+*/
+QTimeLine::Direction QTimeLine::direction() const
+{
+ Q_D(const QTimeLine);
+ return d->direction;
+}
+void QTimeLine::setDirection(Direction direction)
+{
+ Q_D(QTimeLine);
+ d->direction = direction;
+ d->startTime = d->currentTime;
+ d->timer.start();
+}
+
+/*!
+ \property QTimeLine::duration
+ \brief the total duration of the timeline in milliseconds.
+
+ By default, this value is 1000 (i.e., 1 second), but you can change this
+ by either passing a duration to QTimeLine's constructor, or by calling
+ setDuration(). The duration must be larger than 0.
+*/
+int QTimeLine::duration() const
+{
+ Q_D(const QTimeLine);
+ return d->duration;
+}
+void QTimeLine::setDuration(int duration)
+{
+ Q_D(QTimeLine);
+ if (duration <= 0) {
+ qWarning("QTimeLine::setDuration: cannot set duration <= 0");
+ return;
+ }
+ d->duration = duration;
+}
+
+/*!
+ Returns the start frame, which is the frame corresponding to the start of
+ the timeline (i.e., the frame for which the current value is 0).
+
+ \sa setStartFrame(), setFrameRange()
+*/
+int QTimeLine::startFrame() const
+{
+ Q_D(const QTimeLine);
+ return d->startFrame;
+}
+
+/*!
+ Sets the start frame, which is the frame corresponding to the start of the
+ timeline (i.e., the frame for which the current value is 0), to \a frame.
+
+ \sa startFrame(), endFrame(), setFrameRange()
+*/
+void QTimeLine::setStartFrame(int frame)
+{
+ Q_D(QTimeLine);
+ d->startFrame = frame;
+}
+
+/*!
+ Returns the end frame, which is the frame corresponding to the end of the
+ timeline (i.e., the frame for which the current value is 1).
+
+ \sa setEndFrame(), setFrameRange()
+*/
+int QTimeLine::endFrame() const
+{
+ Q_D(const QTimeLine);
+ return d->endFrame;
+}
+
+/*!
+ Sets the end frame, which is the frame corresponding to the end of the
+ timeline (i.e., the frame for which the current value is 1), to \a frame.
+
+ \sa endFrame(), startFrame(), setFrameRange()
+*/
+void QTimeLine::setEndFrame(int frame)
+{
+ Q_D(QTimeLine);
+ d->endFrame = frame;
+}
+
+/*!
+ Sets the timeline's frame counter to start at \a startFrame, and end and
+ \a endFrame. For each time value, QTimeLine will find the corresponding
+ frame when you call currentFrame() or frameForTime() by interpolating,
+ using the return value of valueForTime().
+
+ When in Running state, QTimeLine also emits the frameChanged() signal when
+ the frame changes.
+
+ \sa startFrame(), endFrame(), start(), currentFrame()
+*/
+void QTimeLine::setFrameRange(int startFrame, int endFrame)
+{
+ Q_D(QTimeLine);
+ d->startFrame = startFrame;
+ d->endFrame = endFrame;
+}
+
+/*!
+ \property QTimeLine::updateInterval
+ \brief the time in milliseconds between each time QTimeLine updates its
+ current time.
+
+ When updating the current time, QTimeLine will emit valueChanged() if the
+ current value changed, and frameChanged() if the frame changed.
+
+ By default, the interval is 40 ms, which corresponds to a rate of 25
+ updates per second.
+*/
+int QTimeLine::updateInterval() const
+{
+ Q_D(const QTimeLine);
+ return d->updateInterval;
+}
+void QTimeLine::setUpdateInterval(int interval)
+{
+ Q_D(QTimeLine);
+ d->updateInterval = interval;
+}
+
+/*!
+ \property QTimeLine::curveShape
+ \brief the shape of the timeline curve.
+
+ The curve shape describes the relation between the time and value for the
+ base implementation of valueForTime().
+
+ If you have reimplemented valueForTime(), this value is ignored.
+
+ By default, this property is set to \l EaseInOutCurve.
+
+ \sa valueForTime()
+*/
+QTimeLine::CurveShape QTimeLine::curveShape() const
+{
+ Q_D(const QTimeLine);
+ return d->curveShape;
+}
+void QTimeLine::setCurveShape(CurveShape shape)
+{
+ Q_D(QTimeLine);
+ d->curveShape = shape;
+}
+
+/*!
+ \property QTimeLine::currentTime
+ \brief the current time of the time line.
+
+ When QTimeLine is in Running state, this value is updated continuously as
+ a function of the duration and direction of the timeline. Otherwise, it is
+ value that was current when stop() was called last, or the value set by
+ setCurrentTime().
+
+ By default, this property contains a value of 0.
+*/
+int QTimeLine::currentTime() const
+{
+ Q_D(const QTimeLine);
+ return d->currentTime;
+}
+void QTimeLine::setCurrentTime(int msec)
+{
+ Q_D(QTimeLine);
+ d->startTime = 0;
+ d->currentLoopCount = 0;
+ d->timer.restart();
+ d->setCurrentTime(msec);
+}
+
+/*!
+ Returns the frame corresponding to the current time.
+
+ \sa currentTime(), frameForTime(), setFrameRange()
+*/
+int QTimeLine::currentFrame() const
+{
+ Q_D(const QTimeLine);
+ return frameForTime(d->currentTime);
+}
+
+/*!
+ Returns the value corresponding to the current time.
+
+ \sa valueForTime(), currentFrame()
+*/
+qreal QTimeLine::currentValue() const
+{
+ Q_D(const QTimeLine);
+ return valueForTime(d->currentTime);
+}
+
+/*!
+ Returns the frame corresponding to the time \a msec. This value is
+ calculated using a linear interpolation of the start and end frame, based
+ on the value returned by valueForTime().
+
+ \sa valueForTime(), setFrameRange()
+*/
+int QTimeLine::frameForTime(int msec) const
+{
+ Q_D(const QTimeLine);
+ if (d->direction == Forward)
+ return d->startFrame + int((d->endFrame - d->startFrame) * valueForTime(msec));
+ return d->startFrame + qCeil((d->endFrame - d->startFrame) * valueForTime(msec));
+}
+
+/*!
+ Returns the timeline value for the time \a msec. The returned value, which
+ varies depending on the curve shape, is always between 0 and 1. If \a msec
+ is 0, the default implementation always returns 0.
+
+ Reimplement this function to provide a custom curve shape for your
+ timeline.
+
+ \sa CurveShape, frameForTime()
+*/
+qreal QTimeLine::valueForTime(int msec) const
+{
+ Q_D(const QTimeLine);
+ msec = qMin(qMax(msec, 0), d->duration);
+
+ // Simple linear interpolation
+ qreal value = msec / qreal(d->duration);
+
+ switch (d->curveShape) {
+ case EaseInOutCurve:
+ value = qt_sinProgress(value);
+ break;
+ // SmoothBegin blends Smooth and Linear Interpolation.
+ // Progress 0 - 0.3 : Smooth only
+ // Progress 0.3 - ~ 0.5 : Mix of Smooth and Linear
+ // Progress ~ 0.5 - 1 : Linear only
+ case EaseInCurve: {
+ const qreal sinProgress = qt_sinProgress(value);
+ const qreal linearProgress = value;
+ const qreal mix = qt_smoothBeginEndMixFactor(value);
+ value = sinProgress * mix + linearProgress * (1 - mix);
+ break;
+ }
+ case EaseOutCurve: {
+ const qreal sinProgress = qt_sinProgress(value);
+ const qreal linearProgress = value;
+ const qreal mix = qt_smoothBeginEndMixFactor(1 - value);
+ value = sinProgress * mix + linearProgress * (1 - mix);
+ break;
+ }
+ case SineCurve:
+ value = (qSin(((msec * pi * 2) / d->duration) - pi/2) + 1) / 2;
+ break;
+ case CosineCurve:
+ value = (qCos(((msec * pi * 2) / d->duration) - pi/2) + 1) / 2;
+ break;
+ default:
+ break;
+ }
+
+ return value;
+}
+
+/*!
+ Starts the timeline. QTimeLine will enter Running state, and once it
+ enters the event loop, it will update its current time, frame and value at
+ regular intervals. The default interval is 40 ms (i.e., 25 times per
+ second). You can change the update interval by calling
+ setUpdateInterval().
+
+ If you want to resume a stopped timeline without restarting, you can call
+ resume() instead.
+
+ \sa resume(), updateInterval(), frameChanged(), valueChanged()
+*/
+void QTimeLine::start()
+{
+ Q_D(QTimeLine);
+ if (d->timerId) {
+ qWarning("QTimeLine::start: already running");
+ return;
+ }
+ int curTime = d->currentTime;
+ if (curTime == d->duration && d->direction == Forward)
+ curTime = 0;
+ else if (curTime == 0 && d->direction == Backward)
+ curTime = d->duration;
+ d->timerId = startTimer(d->updateInterval);
+ d->startTime = curTime;
+ d->currentLoopCount = 0;
+ d->timer.start();
+ d->setState(Running);
+ d->setCurrentTime(curTime);
+}
+
+/*!
+ Resumes the timeline from the current time. QTimeLine will reenter Running
+ state, and once it enters the event loop, it will update its current time,
+ frame and value at regular intervals.
+
+ In contrast to start(), this function does not restart the timeline before
+ is resumes.
+
+ \sa start(), updateInterval(), frameChanged(), valueChanged()
+*/
+void QTimeLine::resume()
+{
+ Q_D(QTimeLine);
+ if (d->timerId) {
+ qWarning("QTimeLine::resume: already running");
+ return;
+ }
+ d->timerId = startTimer(d->updateInterval);
+ d->startTime = d->currentTime;
+ d->timer.start();
+ d->setState(Running);
+}
+
+/*!
+ Stops the timeline, causing QTimeLine to enter NotRunning state.
+
+ \sa start()
+*/
+void QTimeLine::stop()
+{
+ Q_D(QTimeLine);
+ if (d->timerId)
+ killTimer(d->timerId);
+ d->setState(NotRunning);
+ d->timerId = 0;
+}
+
+/*!
+ If \a paused is true, the timeline is paused, causing QTimeLine to enter
+ Paused state. No updates will be signaled until either start() or
+ setPaused(false) is called. If \a paused is false, the timeline is resumed
+ and continues where it left.
+
+ \sa state(), start()
+*/
+void QTimeLine::setPaused(bool paused)
+{
+ Q_D(QTimeLine);
+ if (d->state == NotRunning) {
+ qWarning("QTimeLine::setPaused: Not running");
+ return;
+ }
+ if (paused && d->state != Paused) {
+ d->startTime = d->currentTime;
+ killTimer(d->timerId);
+ d->timerId = 0;
+ d->setState(Paused);
+ } else if (!paused && d->state == Paused) {
+ d->timerId = startTimer(d->updateInterval);
+ d->setState(Running);
+ }
+}
+
+/*!
+ Toggles the direction of the timeline. If the direction was Forward, it
+ becomes Backward, and vice verca.
+
+ \sa setDirection()
+*/
+void QTimeLine::toggleDirection()
+{
+ Q_D(QTimeLine);
+ setDirection(d->direction == Forward ? Backward : Forward);
+}
+
+/*!
+ \reimp
+*/
+void QTimeLine::timerEvent(QTimerEvent *event)
+{
+ Q_D(QTimeLine);
+ if (event->timerId() != d->timerId) {
+ event->ignore();
+ return;
+ }
+ event->accept();
+
+ if (d->direction == Forward) {
+ d->setCurrentTime(d->startTime + d->timer.elapsed());
+ } else {
+ d->setCurrentTime(d->startTime - d->timer.elapsed());
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/corelib/tools/qtimeline.h b/src/corelib/tools/qtimeline.h
new file mode 100644
index 0000000000..18c39804fe
--- /dev/null
+++ b/src/corelib/tools/qtimeline.h
@@ -0,0 +1,142 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTIMELINE_H
+#define QTIMELINE_H
+
+#include <QtCore/qobject.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Core)
+
+class QTimeLinePrivate;
+class Q_CORE_EXPORT QTimeLine : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(int duration READ duration WRITE setDuration)
+ Q_PROPERTY(int updateInterval READ updateInterval WRITE setUpdateInterval)
+ Q_PROPERTY(int currentTime READ currentTime WRITE setCurrentTime)
+ Q_PROPERTY(Direction direction READ direction WRITE setDirection)
+ Q_PROPERTY(int loopCount READ loopCount WRITE setLoopCount)
+ Q_PROPERTY(CurveShape curveShape READ curveShape WRITE setCurveShape)
+public:
+ enum State {
+ NotRunning,
+ Paused,
+ Running
+ };
+ enum Direction {
+ Forward,
+ Backward
+ };
+ enum CurveShape {
+ EaseInCurve,
+ EaseOutCurve,
+ EaseInOutCurve,
+ LinearCurve,
+ SineCurve,
+ CosineCurve
+ };
+
+ explicit QTimeLine(int duration = 1000, QObject *parent = 0);
+ virtual ~QTimeLine();
+
+ State state() const;
+
+ int loopCount() const;
+ void setLoopCount(int count);
+
+ Direction direction() const;
+ void setDirection(Direction direction);
+
+ int duration() const;
+ void setDuration(int duration);
+
+ int startFrame() const;
+ void setStartFrame(int frame);
+ int endFrame() const;
+ void setEndFrame(int frame);
+ void setFrameRange(int startFrame, int endFrame);
+
+ int updateInterval() const;
+ void setUpdateInterval(int interval);
+
+ CurveShape curveShape() const;
+ void setCurveShape(CurveShape shape);
+
+ int currentTime() const;
+ int currentFrame() const;
+ qreal currentValue() const;
+
+ int frameForTime(int msec) const;
+ virtual qreal valueForTime(int msec) const;
+
+public Q_SLOTS:
+ void start();
+ void resume();
+ void stop();
+ void setPaused(bool paused);
+ void setCurrentTime(int msec);
+ void toggleDirection();
+
+Q_SIGNALS:
+ void valueChanged(qreal x);
+ void frameChanged(int);
+ void stateChanged(QTimeLine::State newState);
+ void finished();
+
+protected:
+ void timerEvent(QTimerEvent *event);
+
+private:
+ Q_DISABLE_COPY(QTimeLine)
+ Q_DECLARE_PRIVATE(QTimeLine)
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
+
diff --git a/src/corelib/tools/qtools_p.h b/src/corelib/tools/qtools_p.h
new file mode 100644
index 0000000000..574928e7b1
--- /dev/null
+++ b/src/corelib/tools/qtools_p.h
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTOOLS_P_H
+#define QTOOLS_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/qglobal.h"
+
+QT_BEGIN_NAMESPACE
+
+// implemented in qbytearray.cpp
+int Q_CORE_EXPORT qAllocMore(int alloc, int extra);
+
+QT_END_NAMESPACE
+
+#endif // QTOOLS_P_H
diff --git a/src/corelib/tools/qunicodetables.cpp b/src/corelib/tools/qunicodetables.cpp
new file mode 100644
index 0000000000..0cfa26aaf7
--- /dev/null
+++ b/src/corelib/tools/qunicodetables.cpp
@@ -0,0 +1,9404 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/* This file is autogenerated from the Unicode 5.0 database. Do not edit */
+
+QT_BEGIN_NAMESPACE
+
+static const unsigned short uc_property_trie[] = {
+ // 0x11000
+
+ 6256, 6288, 6320, 6352, 6384, 6416, 6448, 6480,
+ 6512, 6544, 6576, 6608, 6640, 6672, 6704, 6736,
+ 6768, 6800, 6832, 6864, 6896, 6928, 6960, 6992,
+ 7024, 7056, 7088, 7120, 7152, 7184, 7216, 7248,
+ 7280, 7312, 7344, 6512, 7376, 6512, 7408, 7440,
+ 7472, 7504, 7536, 7568, 7600, 7632, 7664, 7696,
+ 7728, 7760, 7792, 7824, 7856, 7888, 7920, 7952,
+ 7984, 8016, 8048, 8080, 8112, 8144, 8176, 8208,
+ 8240, 8240, 8240, 8240, 8240, 8240, 8240, 8240,
+ 8272, 8304, 8336, 8368, 8400, 8432, 8464, 8496,
+ 8528, 8560, 8592, 8624, 8656, 8688, 8720, 8752,
+ 8400, 8784, 8816, 8848, 8880, 8912, 8944, 8976,
+ 9008, 9040, 9072, 9104, 9136, 9168, 9200, 9232,
+ 9136, 9264, 9296, 9104, 9328, 9360, 9392, 9424,
+ 9456, 9488, 9520, 9552, 9584, 9616, 9648, 9552,
+ 9680, 9712, 9744, 9776, 9808, 9840, 9872, 9552,
+
+ 9904, 9936, 9968, 9552, 9552, 10000, 10032, 10064,
+ 10096, 10096, 10128, 10160, 10160, 10192, 10224, 10256,
+ 10288, 10320, 10352, 10320, 10384, 10416, 10448, 10480,
+ 10512, 10320, 10544, 10576, 10608, 10320, 10320, 10640,
+ 10672, 10320, 10320, 10320, 10320, 10320, 10320, 10320,
+ 10320, 10320, 10320, 10320, 10320, 10320, 10320, 10320,
+ 10320, 10320, 10320, 10704, 10736, 10320, 10320, 10768,
+ 10800, 10832, 10864, 10896, 9904, 10928, 10960, 10992,
+ 11024, 10320, 11056, 11088, 10320, 11120, 9552, 9552,
+ 11152, 11184, 11216, 11248, 11280, 11312, 11344, 11376,
+ 11408, 9552, 9552, 9552, 9552, 9552, 9552, 9552,
+ 11440, 11472, 11504, 11536, 9552, 9552, 9552, 9552,
+ 9552, 9552, 9552, 9552, 9552, 9552, 9552, 9552,
+ 11568, 11600, 11632, 11664, 11696, 11728, 11760, 11792,
+ 6512, 6512, 6512, 6512, 11824, 6512, 6512, 11856,
+ 11888, 11920, 11952, 11984, 12016, 12048, 12080, 12112,
+
+ 12144, 12176, 12208, 12240, 12272, 12304, 12336, 12368,
+ 12400, 12432, 12464, 12496, 12528, 12560, 12592, 12624,
+ 12656, 12688, 12720, 12752, 12784, 12816, 12848, 12880,
+ 12912, 12944, 12976, 13008, 13040, 13072, 13104, 13136,
+ 13168, 13200, 13232, 13264, 13296, 13328, 13360, 13392,
+ 13168, 13168, 13168, 13168, 13424, 13456, 13488, 13520,
+ 13552, 13168, 13168, 13584, 13616, 13648, 9552, 9552,
+ 13680, 13712, 13744, 13776, 13808, 13840, 13872, 13904,
+ 13936, 13936, 13936, 13936, 13936, 13936, 13936, 13936,
+ 13968, 13968, 13968, 13968, 14000, 14032, 14064, 14096,
+ 13968, 14128, 13968, 14160, 14192, 14224, 14256, 14288,
+ 14320, 14352, 9552, 9552, 9552, 9552, 9552, 9552,
+ 14384, 14416, 14448, 14480, 14512, 14512, 14512, 14544,
+ 14576, 14608, 14640, 14672, 14704, 14736, 14736, 9552,
+ 14768, 9552, 9552, 9552, 14800, 14832, 14832, 14864,
+ 14832, 14832, 14832, 14832, 14832, 14832, 14896, 14928,
+
+ 14960, 14992, 15024, 15056, 15088, 15120, 15152, 15184,
+ 15216, 15248, 15280, 15280, 15312, 15344, 15376, 15408,
+ 15440, 15472, 15504, 15536, 15472, 15568, 15600, 15632,
+ 15664, 15664, 15664, 15696, 15664, 15664, 15728, 15760,
+ 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792,
+ 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792,
+ 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792,
+ 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792,
+ 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792,
+ 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792,
+ 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792,
+ 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792,
+ 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792,
+ 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792,
+ 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792,
+ 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792,
+
+ 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792,
+ 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792,
+ 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792,
+ 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792,
+ 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792,
+ 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792,
+ 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792,
+ 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792,
+ 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792,
+ 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792,
+ 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792,
+ 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792,
+ 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792,
+ 15792, 15792, 15792, 15792, 15792, 15824, 11376, 11376,
+ 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856,
+ 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856,
+
+ 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856,
+ 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856,
+ 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856,
+ 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856,
+ 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856,
+ 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856,
+ 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856,
+ 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856,
+ 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856,
+ 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856,
+ 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856,
+ 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856,
+ 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856,
+ 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856,
+ 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856,
+ 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856,
+
+ 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856,
+ 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856,
+ 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856,
+ 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856,
+ 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856,
+ 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856,
+ 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856,
+ 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856,
+ 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856,
+ 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856,
+ 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856,
+ 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856,
+ 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856,
+ 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856,
+ 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856,
+ 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856,
+
+ 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856,
+ 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856,
+ 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856,
+ 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856,
+ 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856,
+ 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856,
+ 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856,
+ 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856,
+ 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856,
+ 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856,
+ 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856,
+ 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856,
+ 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856,
+ 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856,
+ 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856,
+ 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856,
+
+ 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856,
+ 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856,
+ 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856,
+ 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856,
+ 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856,
+ 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856,
+ 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856,
+ 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856,
+ 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856,
+ 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856,
+ 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856,
+ 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856,
+ 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856,
+ 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856,
+ 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856,
+ 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856,
+
+ 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856,
+ 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856,
+ 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856,
+ 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856,
+ 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856,
+ 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856,
+ 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856,
+ 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856,
+ 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856,
+ 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856,
+ 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856,
+ 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856,
+ 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856,
+ 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856,
+ 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856,
+ 15856, 15856, 15856, 15856, 15856, 15888, 9552, 9552,
+
+ 15920, 15952, 15952, 15952, 15952, 15952, 15952, 15952,
+ 15952, 15952, 15952, 15952, 15952, 15952, 15952, 15952,
+ 15952, 15952, 15952, 15952, 15952, 15952, 15952, 15952,
+ 15952, 15952, 15952, 15952, 15952, 15952, 15952, 15952,
+ 15952, 15952, 15952, 15952, 15984, 16016, 16048, 9552,
+ 9552, 9552, 9552, 9552, 9552, 9552, 9552, 9552,
+ 9552, 9552, 9552, 9552, 9552, 9552, 9552, 9552,
+ 16080, 16112, 9552, 9552, 9552, 9552, 9552, 9552,
+ 16144, 16176, 16208, 16240, 9552, 9552, 9552, 9552,
+ 9552, 9552, 9552, 9552, 9552, 9552, 9552, 9552,
+ 9552, 9552, 9552, 9552, 9552, 9552, 9552, 9552,
+ 9552, 9552, 9552, 9552, 9552, 9552, 9552, 9552,
+ 16272, 16304, 16336, 16368, 16400, 16432, 16464, 16272,
+ 16304, 16336, 16368, 16400, 16432, 16464, 16272, 16304,
+ 16336, 16368, 16400, 16432, 16464, 16272, 16304, 16336,
+ 16368, 16400, 16432, 16464, 16272, 16304, 16336, 16368,
+
+ 16400, 16432, 16464, 16272, 16304, 16336, 16368, 16400,
+ 16432, 16464, 16272, 16304, 16336, 16368, 16400, 16432,
+ 16464, 16272, 16304, 16336, 16368, 16400, 16432, 16464,
+ 16272, 16304, 16336, 16368, 16400, 16432, 16464, 16272,
+ 16304, 16336, 16368, 16400, 16432, 16464, 16272, 16304,
+ 16336, 16368, 16400, 16432, 16464, 16272, 16304, 16336,
+ 16368, 16400, 16432, 16464, 16272, 16304, 16336, 16368,
+ 16400, 16432, 16464, 16272, 16304, 16336, 16368, 16400,
+ 16432, 16464, 16272, 16304, 16336, 16368, 16400, 16432,
+ 16464, 16272, 16304, 16336, 16368, 16400, 16432, 16464,
+ 16272, 16304, 16336, 16368, 16400, 16432, 16464, 16272,
+ 16304, 16336, 16368, 16400, 16432, 16464, 16272, 16304,
+ 16336, 16368, 16400, 16432, 16464, 16272, 16304, 16336,
+ 16368, 16400, 16432, 16464, 16272, 16304, 16336, 16368,
+ 16400, 16432, 16464, 16272, 16304, 16336, 16368, 16400,
+ 16432, 16464, 16272, 16304, 16336, 16368, 16400, 16432,
+
+ 16464, 16272, 16304, 16336, 16368, 16400, 16432, 16464,
+ 16272, 16304, 16336, 16368, 16400, 16432, 16464, 16272,
+ 16304, 16336, 16368, 16400, 16432, 16464, 16272, 16304,
+ 16336, 16368, 16400, 16432, 16464, 16272, 16304, 16336,
+ 16368, 16400, 16432, 16464, 16272, 16304, 16336, 16368,
+ 16400, 16432, 16464, 16272, 16304, 16336, 16368, 16400,
+ 16432, 16464, 16272, 16304, 16336, 16368, 16400, 16432,
+ 16464, 16272, 16304, 16336, 16368, 16400, 16432, 16464,
+ 16272, 16304, 16336, 16368, 16400, 16432, 16464, 16272,
+ 16304, 16336, 16368, 16400, 16432, 16464, 16272, 16304,
+ 16336, 16368, 16400, 16432, 16464, 16272, 16304, 16336,
+ 16368, 16400, 16432, 16464, 16272, 16304, 16336, 16368,
+ 16400, 16432, 16464, 16272, 16304, 16336, 16368, 16400,
+ 16432, 16464, 16272, 16304, 16336, 16368, 16400, 16432,
+ 16464, 16272, 16304, 16336, 16368, 16400, 16432, 16464,
+ 16272, 16304, 16336, 16368, 16400, 16432, 16464, 16272,
+
+ 16304, 16336, 16368, 16400, 16432, 16464, 16272, 16304,
+ 16336, 16368, 16400, 16432, 16464, 16272, 16304, 16336,
+ 16368, 16400, 16432, 16464, 16272, 16304, 16336, 16368,
+ 16400, 16432, 16464, 16272, 16304, 16336, 16368, 16400,
+ 16432, 16464, 16272, 16304, 16336, 16368, 16400, 16432,
+ 16464, 16272, 16304, 16336, 16368, 16400, 16432, 16464,
+ 16272, 16304, 16336, 16368, 16400, 16432, 16464, 16272,
+ 16304, 16336, 16368, 16400, 16432, 16496, 9552, 9552,
+ 16528, 16528, 16528, 16528, 16528, 16528, 16528, 16528,
+ 16528, 16528, 16528, 16528, 16528, 16528, 16528, 16528,
+ 16528, 16528, 16528, 16528, 16528, 16528, 16528, 16528,
+ 16528, 16528, 16528, 16528, 16528, 16528, 16528, 16528,
+ 16528, 16528, 16528, 16528, 16528, 16528, 16528, 16528,
+ 16528, 16528, 16528, 16528, 16528, 16528, 16528, 16528,
+ 16528, 16528, 16528, 16528, 16528, 16528, 16528, 16528,
+ 16528, 16528, 16528, 16528, 16528, 16528, 16528, 16528,
+
+ 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560,
+ 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560,
+ 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560,
+ 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560,
+ 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560,
+ 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560,
+ 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560,
+ 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560,
+ 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560,
+ 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560,
+ 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560,
+ 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560,
+ 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560,
+ 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560,
+ 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560,
+ 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560,
+
+ 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560,
+ 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560,
+ 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560,
+ 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560,
+ 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560,
+ 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560,
+ 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560,
+ 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560,
+ 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560,
+ 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856,
+ 15856, 16592, 16624, 16656, 16688, 16688, 16720, 9552,
+ 16752, 16784, 16816, 16848, 16848, 16880, 16912, 16848,
+ 16848, 16848, 16848, 16848, 16848, 16848, 16848, 16848,
+ 16848, 16944, 16976, 16848, 17008, 16848, 17040, 17072,
+ 17104, 17136, 17168, 17200, 16848, 16848, 16848, 17232,
+ 17264, 17296, 17328, 17360, 17392, 17424, 17456, 17488,
+
+ 17520, 17552, 17584, 9552, 17616, 17616, 17616, 17648,
+ 17680, 17712, 17744, 17776, 17808, 9552, 9552, 9552,
+ 9552, 9552, 9552, 9552, 9552, 9552, 9552, 9552,
+ 17840, 17872, 17904, 9552, 17936, 14640, 17968, 9552,
+ 18000, 18032, 18064, 17616, 18096, 18128, 9552, 9552,
+ 9552, 9552, 9552, 9552, 9552, 9552, 9552, 9552,
+ 9552, 9552, 9552, 9552, 9552, 9552, 9552, 9552,
+ 9552, 9552, 9552, 9552, 9552, 9552, 9552, 9552,
+ 18160, 18192, 8240, 8240, 8240, 8240, 8240, 8240,
+ 18224, 8240, 8240, 8240, 8240, 8240, 8240, 8240,
+ 18256, 18288, 18320, 8240, 8240, 8240, 8240, 8240,
+ 8240, 8240, 8240, 8240, 8240, 8240, 8240, 8240,
+ 8240, 8240, 8240, 8240, 8240, 8240, 8240, 8240,
+ 8240, 8240, 8240, 8240, 8240, 8240, 8240, 8240,
+ 8240, 8240, 8240, 8240, 8240, 8240, 8240, 8240,
+ 8240, 8240, 8240, 8240, 8240, 8240, 8240, 8240,
+
+ // 0x11000 - 0x110000
+
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18608, 18608, 18608, 18864, 19120, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 19376, 19632, 19888, 20144, 20400, 20656, 20912, 21168,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 21424,
+ 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680,
+ 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680,
+ 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680,
+ 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680,
+ 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680,
+ 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680,
+ 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680,
+ 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680,
+ 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680,
+ 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680,
+ 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680,
+ 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680,
+ 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680,
+ 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680,
+ 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680,
+ 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680,
+ 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680,
+ 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680,
+
+ 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680,
+ 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680,
+ 21680, 21680, 21680, 21680, 21680, 21680, 21936, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 21680, 21680, 22192, 18352, 18352, 18352, 18352, 21424,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 21424,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 21424,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 21424,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 21424,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 21424,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 21424,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 21424,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 21424,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 21424,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 21424,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 21424,
+ 22448, 22704, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352,
+ 18352, 18352, 18352, 18352, 18352, 18352, 18352, 21424,
+ 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960,
+ 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960,
+ 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960,
+ 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960,
+ 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960,
+ 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960,
+ 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960,
+ 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960,
+ 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960,
+ 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960,
+ 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960,
+ 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960,
+ 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960,
+ 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960,
+ 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960,
+ 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960,
+ 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960,
+ 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960,
+
+ 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960,
+ 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960,
+ 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960,
+ 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960,
+ 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960,
+ 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960,
+ 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960,
+ 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960,
+ 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960,
+ 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960,
+ 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960,
+ 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960,
+ 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960,
+ 22960, 22960, 22960, 22960, 22960, 22960, 22960, 23216,
+ 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960,
+ 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960,
+ 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960,
+ 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960,
+ 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960,
+ 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960,
+ 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960,
+ 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960,
+ 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960,
+ 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960,
+ 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960,
+ 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960,
+ 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960,
+ 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960,
+ 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960,
+ 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960,
+ 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960,
+ 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960,
+
+ 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960,
+ 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960,
+ 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960,
+ 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960,
+ 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960,
+ 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960,
+ 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960,
+ 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960,
+ 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960,
+ 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960,
+ 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960,
+ 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960,
+ 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960,
+ 22960, 22960, 22960, 22960, 22960, 22960, 22960, 23216,
+
+
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 1, 2, 3, 4, 5, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 6, 6, 6, 7,
+
+ 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 14, 18, 19, 20, 21, 22,
+ 23, 24, 25, 26, 27, 28, 29, 30,
+ 31, 32, 33, 34, 35, 36, 37, 9,
+
+ 14, 38, 38, 38, 38, 38, 38, 38,
+ 38, 38, 38, 38, 38, 38, 38, 38,
+ 38, 38, 38, 38, 38, 38, 38, 38,
+ 38, 38, 38, 39, 40, 41, 42, 43,
+
+ 42, 44, 44, 44, 44, 44, 44, 44,
+ 44, 44, 44, 44, 44, 44, 44, 44,
+ 44, 44, 44, 44, 44, 44, 44, 44,
+ 44, 44, 44, 39, 45, 41, 36, 0,
+
+ 0, 0, 0, 0, 0, 46, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 47, 14, 48, 12, 12, 12, 49, 49,
+ 42, 49, 50, 51, 36, 52, 49, 42,
+ 53, 54, 55, 56, 57, 58, 49, 59,
+ 42, 60, 50, 61, 62, 62, 62, 14,
+
+ 38, 38, 38, 38, 38, 38, 38, 38,
+ 38, 38, 38, 38, 38, 38, 38, 38,
+ 38, 38, 38, 38, 38, 38, 38, 36,
+ 38, 38, 38, 38, 38, 38, 38, 63,
+
+ 44, 44, 44, 44, 44, 44, 44, 44,
+ 44, 44, 44, 44, 44, 44, 44, 44,
+ 44, 44, 44, 44, 44, 44, 44, 36,
+ 44, 44, 44, 44, 44, 44, 44, 64,
+
+ 65, 66, 65, 66, 65, 66, 65, 66,
+ 65, 66, 65, 66, 65, 66, 65, 66,
+ 65, 66, 65, 66, 65, 66, 65, 66,
+ 65, 66, 65, 66, 65, 66, 65, 66,
+
+ 65, 66, 65, 66, 65, 66, 65, 66,
+ 65, 66, 65, 66, 65, 66, 65, 66,
+ 67, 68, 65, 66, 65, 66, 65, 66,
+ 50, 65, 66, 65, 66, 65, 66, 65,
+
+ 66, 65, 66, 65, 66, 65, 66, 65,
+ 66, 69, 65, 66, 65, 66, 65, 66,
+ 65, 66, 65, 66, 65, 66, 65, 66,
+ 65, 66, 65, 66, 65, 66, 65, 66,
+
+ 65, 66, 65, 66, 65, 66, 65, 66,
+ 65, 66, 65, 66, 65, 66, 65, 66,
+ 65, 66, 65, 66, 65, 66, 65, 66,
+ 70, 65, 66, 65, 66, 65, 66, 71,
+
+ 72, 73, 65, 66, 65, 66, 74, 65,
+ 66, 75, 75, 65, 66, 50, 76, 77,
+ 78, 65, 66, 75, 79, 80, 81, 82,
+ 65, 66, 83, 50, 81, 84, 85, 86,
+
+ 65, 66, 65, 66, 65, 66, 87, 65,
+ 66, 87, 50, 50, 65, 66, 87, 65,
+ 66, 88, 88, 65, 66, 65, 66, 89,
+ 65, 66, 50, 90, 65, 66, 50, 91,
+
+ 90, 90, 90, 90, 92, 93, 94, 92,
+ 93, 94, 92, 93, 94, 65, 66, 65,
+ 66, 65, 66, 65, 66, 65, 66, 65,
+ 66, 65, 66, 65, 66, 95, 65, 66,
+
+ 65, 66, 65, 66, 65, 66, 65, 66,
+ 65, 66, 65, 66, 65, 66, 65, 66,
+ 96, 92, 93, 94, 65, 66, 97, 98,
+ 99, 100, 65, 66, 65, 66, 65, 66,
+
+ 65, 66, 65, 66, 65, 66, 65, 66,
+ 65, 66, 65, 66, 65, 66, 65, 66,
+ 65, 66, 65, 66, 65, 66, 65, 66,
+ 99, 100, 99, 100, 99, 100, 99, 100,
+
+ 101, 102, 99, 100, 99, 100, 99, 100,
+ 99, 100, 99, 100, 99, 100, 99, 100,
+ 99, 100, 99, 100, 102, 102, 102, 103,
+ 103, 103, 104, 105, 106, 107, 108, 103,
+
+ 103, 105, 109, 110, 111, 112, 113, 109,
+ 113, 109, 113, 109, 113, 109, 113, 109,
+ 50, 50, 50, 114, 115, 50, 116, 116,
+ 50, 117, 50, 118, 50, 50, 50, 50,
+
+ 116, 50, 50, 119, 50, 50, 50, 50,
+ 120, 121, 50, 122, 50, 50, 50, 121,
+ 50, 50, 123, 50, 50, 124, 50, 50,
+ 50, 50, 50, 50, 50, 125, 50, 50,
+
+ 126, 50, 50, 126, 50, 50, 50, 50,
+ 126, 127, 128, 128, 129, 50, 50, 50,
+ 50, 50, 130, 50, 90, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50,
+
+ 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 131, 131, 131, 131, 131, 102, 102,
+ 132, 132, 132, 132, 132, 132, 132, 132,
+ 132, 133, 133, 134, 134, 134, 134, 134,
+
+ 132, 132, 42, 42, 42, 42, 133, 133,
+ 135, 133, 133, 133, 135, 133, 133, 133,
+ 134, 134, 42, 42, 42, 42, 42, 42,
+ 42, 42, 42, 42, 42, 42, 42, 136,
+
+ 132, 132, 132, 132, 132, 42, 42, 42,
+ 42, 42, 136, 136, 136, 136, 137, 138,
+ 138, 138, 138, 138, 138, 138, 138, 138,
+ 138, 138, 138, 138, 138, 138, 138, 138,
+
+ 139, 139, 139, 139, 139, 139, 139, 139,
+ 139, 139, 139, 139, 139, 139, 139, 139,
+ 139, 139, 139, 139, 139, 140, 141, 141,
+ 141, 141, 140, 142, 141, 141, 141, 141,
+
+ 141, 143, 143, 141, 141, 141, 141, 143,
+ 143, 141, 141, 141, 141, 141, 141, 141,
+ 141, 141, 141, 141, 144, 144, 144, 144,
+ 144, 141, 141, 141, 141, 139, 139, 139,
+
+ 139, 139, 139, 139, 139, 145, 146, 147,
+ 147, 147, 146, 146, 146, 147, 147, 148,
+ 149, 149, 149, 150, 150, 150, 150, 149,
+ 151, 152, 152, 153, 154, 155, 155, 156,
+
+ 157, 157, 158, 159, 159, 159, 159, 159,
+ 159, 159, 159, 159, 159, 159, 159, 159,
+ 160, 160, 160, 160, 42, 42, 160, 160,
+ 160, 160, 132, 161, 161, 161, 34, 160,
+
+ 160, 160, 160, 160, 42, 42, 162, 14,
+ 163, 163, 163, 160, 164, 160, 165, 165,
+ 166, 38, 38, 38, 38, 38, 38, 38,
+ 38, 38, 38, 38, 38, 38, 38, 38,
+
+ 38, 38, 160, 38, 38, 38, 38, 38,
+ 38, 38, 38, 38, 167, 168, 168, 168,
+ 169, 44, 44, 44, 44, 44, 44, 44,
+ 44, 44, 44, 44, 44, 44, 44, 44,
+
+ 44, 44, 170, 44, 44, 44, 44, 44,
+ 44, 44, 44, 44, 171, 172, 172, 160,
+ 173, 174, 175, 175, 175, 176, 177, 131,
+ 178, 179, 65, 100, 65, 100, 65, 100,
+
+ 65, 100, 65, 66, 65, 66, 65, 66,
+ 65, 66, 65, 66, 65, 66, 65, 66,
+ 180, 181, 182, 50, 183, 184, 185, 186,
+ 187, 188, 186, 187, 103, 189, 189, 189,
+
+ 190, 191, 191, 191, 191, 191, 191, 191,
+ 191, 191, 191, 191, 191, 190, 191, 191,
+ 38, 38, 38, 38, 38, 38, 38, 38,
+ 38, 38, 38, 38, 38, 38, 38, 38,
+
+ 38, 38, 38, 38, 38, 38, 38, 38,
+ 38, 38, 38, 38, 38, 38, 38, 38,
+ 44, 44, 44, 44, 44, 44, 44, 44,
+ 44, 44, 44, 44, 44, 44, 44, 44,
+
+ 44, 44, 44, 44, 44, 44, 44, 44,
+ 44, 44, 44, 44, 44, 44, 44, 44,
+ 192, 181, 181, 181, 181, 181, 181, 181,
+ 181, 181, 181, 181, 181, 192, 181, 181,
+
+ 65, 66, 193, 139, 139, 139, 139, 160,
+ 194, 194, 178, 179, 99, 100, 99, 100,
+ 65, 66, 65, 66, 65, 66, 65, 66,
+ 65, 66, 65, 66, 65, 66, 65, 66,
+
+ 195, 65, 66, 65, 66, 178, 179, 65,
+ 66, 178, 179, 65, 66, 178, 179, 196,
+ 65, 66, 65, 66, 65, 66, 65, 66,
+ 65, 66, 65, 66, 65, 66, 65, 66,
+
+ 65, 66, 65, 66, 65, 66, 65, 66,
+ 65, 66, 65, 66, 99, 100, 65, 66,
+ 65, 66, 65, 66, 65, 66, 105, 106,
+ 65, 66, 113, 109, 113, 109, 113, 109,
+
+ 178, 179, 178, 179, 178, 179, 178, 179,
+ 178, 179, 178, 179, 178, 179, 178, 179,
+ 113, 109, 113, 109, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 197, 197, 197, 197, 197, 197, 197,
+ 197, 197, 197, 197, 197, 197, 197, 197,
+
+ 197, 197, 197, 197, 197, 197, 197, 197,
+ 197, 197, 197, 197, 197, 197, 197, 197,
+ 197, 197, 197, 197, 197, 197, 197, 160,
+ 160, 134, 198, 198, 199, 198, 199, 198,
+
+ 160, 200, 200, 200, 200, 200, 200, 200,
+ 200, 200, 200, 200, 200, 200, 200, 200,
+ 200, 200, 200, 200, 200, 200, 200, 200,
+ 200, 200, 200, 200, 200, 200, 200, 200,
+
+ 200, 200, 200, 200, 200, 200, 200, 201,
+ 160, 202, 203, 160, 160, 160, 160, 160,
+ 204, 205, 206, 206, 206, 206, 205, 206,
+ 206, 206, 207, 205, 206, 206, 206, 206,
+
+ 206, 206, 152, 205, 205, 205, 205, 205,
+ 206, 206, 205, 206, 206, 207, 208, 206,
+ 209, 210, 211, 212, 213, 214, 215, 216,
+ 217, 218, 219, 220, 221, 222, 223, 224,
+
+ 225, 226, 227, 225, 206, 152, 228, 229,
+ 204, 204, 204, 204, 204, 204, 204, 204,
+ 230, 230, 230, 230, 230, 230, 230, 230,
+ 230, 230, 230, 230, 230, 230, 230, 230,
+
+ 230, 230, 230, 230, 230, 230, 230, 230,
+ 230, 230, 230, 204, 204, 204, 204, 204,
+ 230, 230, 230, 231, 232, 204, 204, 204,
+ 204, 204, 204, 204, 204, 204, 204, 204,
+
+ 233, 233, 233, 233, 234, 234, 234, 234,
+ 234, 234, 234, 235, 236, 237, 238, 238,
+ 149, 149, 149, 149, 149, 149, 234, 234,
+ 234, 234, 234, 239, 234, 234, 240, 241,
+
+ 234, 242, 243, 243, 243, 243, 244, 243,
+ 244, 243, 244, 244, 244, 244, 244, 243,
+ 243, 243, 243, 244, 244, 244, 244, 244,
+ 244, 244, 244, 234, 234, 234, 234, 234,
+
+ 245, 244, 244, 244, 244, 244, 244, 244,
+ 243, 244, 244, 246, 247, 248, 249, 250,
+ 251, 252, 253, 146, 146, 147, 150, 149,
+ 149, 153, 153, 153, 152, 153, 153, 234,
+
+ 254, 255, 256, 257, 258, 259, 260, 261,
+ 262, 263, 264, 265, 265, 266, 267, 267,
+ 268, 243, 243, 243, 242, 243, 243, 243,
+ 244, 244, 244, 244, 244, 244, 244, 244,
+
+ 244, 244, 244, 244, 244, 244, 244, 244,
+ 243, 243, 243, 243, 243, 243, 243, 243,
+ 243, 243, 243, 243, 243, 243, 243, 243,
+ 243, 243, 244, 244, 244, 244, 244, 244,
+
+ 244, 244, 244, 244, 244, 244, 244, 244,
+ 244, 244, 244, 244, 244, 244, 244, 244,
+ 244, 244, 244, 244, 244, 244, 244, 244,
+ 269, 269, 244, 244, 244, 244, 244, 269,
+
+ 243, 244, 244, 243, 243, 243, 243, 243,
+ 243, 243, 243, 243, 244, 243, 244, 270,
+ 244, 244, 243, 243, 241, 243, 139, 139,
+ 139, 139, 139, 139, 139, 271, 272, 139,
+
+ 139, 139, 139, 141, 139, 273, 273, 139,
+ 139, 49, 141, 139, 139, 141, 274, 274,
+ 23, 24, 25, 26, 27, 28, 29, 30,
+ 31, 32, 269, 269, 269, 275, 275, 276,
+
+ 277, 277, 277, 278, 278, 278, 278, 278,
+ 278, 278, 278, 278, 278, 278, 234, 279,
+ 270, 280, 269, 269, 269, 270, 270, 270,
+ 270, 270, 269, 269, 269, 269, 270, 269,
+
+ 269, 269, 269, 269, 269, 269, 269, 269,
+ 270, 269, 270, 269, 270, 276, 276, 274,
+ 146, 147, 146, 146, 147, 146, 146, 147,
+ 147, 147, 146, 147, 147, 146, 147, 146,
+
+ 146, 146, 147, 146, 147, 146, 147, 146,
+ 147, 146, 146, 234, 234, 274, 276, 276,
+ 281, 281, 281, 281, 281, 281, 281, 281,
+ 281, 282, 282, 282, 281, 281, 281, 281,
+
+ 281, 281, 281, 281, 281, 281, 281, 281,
+ 281, 281, 281, 282, 282, 281, 234, 234,
+ 234, 234, 234, 234, 234, 234, 234, 234,
+ 234, 234, 234, 234, 234, 234, 234, 234,
+
+ 283, 283, 283, 283, 283, 283, 283, 283,
+ 283, 283, 283, 283, 283, 283, 283, 283,
+ 283, 283, 283, 283, 283, 283, 283, 283,
+ 283, 283, 283, 283, 283, 283, 283, 283,
+
+ 283, 283, 283, 283, 283, 283, 284, 284,
+ 284, 284, 284, 284, 284, 284, 284, 284,
+ 284, 285, 234, 234, 234, 234, 234, 234,
+ 234, 234, 234, 234, 234, 234, 234, 234,
+
+ 286, 287, 288, 289, 290, 291, 292, 293,
+ 294, 295, 296, 296, 296, 296, 296, 296,
+ 296, 296, 296, 296, 296, 296, 296, 296,
+ 296, 296, 296, 296, 296, 296, 296, 296,
+
+ 296, 296, 296, 296, 296, 296, 296, 296,
+ 296, 296, 296, 297, 297, 297, 297, 297,
+ 297, 297, 298, 297, 299, 299, 300, 301,
+ 302, 303, 304, 204, 204, 204, 204, 204,
+
+ 204, 204, 204, 204, 204, 204, 204, 204,
+ 204, 204, 204, 204, 204, 204, 204, 204,
+ 204, 204, 204, 204, 204, 204, 204, 204,
+ 204, 204, 204, 204, 204, 204, 204, 204,
+
+ 160, 305, 305, 306, 307, 90, 90, 90,
+ 90, 90, 90, 90, 90, 90, 90, 90,
+ 90, 90, 90, 90, 90, 90, 90, 90,
+ 90, 90, 90, 90, 90, 90, 90, 90,
+
+ 90, 90, 90, 90, 90, 90, 90, 90,
+ 90, 90, 90, 90, 90, 90, 90, 90,
+ 90, 90, 90, 90, 90, 90, 90, 90,
+ 90, 90, 160, 160, 308, 90, 306, 306,
+
+ 306, 305, 305, 305, 305, 305, 305, 305,
+ 305, 306, 306, 306, 306, 309, 160, 160,
+ 90, 139, 141, 139, 139, 160, 160, 160,
+ 90, 90, 90, 90, 90, 90, 90, 90,
+
+ 90, 90, 305, 305, 310, 310, 311, 312,
+ 313, 314, 315, 316, 317, 318, 319, 320,
+ 198, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 321, 321, 322, 321, 321,
+
+ 160, 305, 306, 306, 160, 90, 90, 90,
+ 90, 90, 90, 90, 90, 160, 160, 90,
+ 90, 160, 160, 90, 90, 90, 90, 90,
+ 90, 90, 90, 90, 90, 90, 90, 90,
+
+ 90, 90, 90, 90, 90, 90, 90, 90,
+ 90, 160, 90, 90, 90, 90, 90, 90,
+ 90, 160, 90, 160, 160, 160, 90, 90,
+ 90, 90, 160, 160, 308, 307, 323, 306,
+
+ 306, 305, 305, 305, 305, 160, 160, 306,
+ 306, 160, 160, 306, 306, 309, 322, 160,
+ 160, 160, 160, 160, 160, 160, 160, 323,
+ 160, 160, 160, 160, 90, 90, 160, 90,
+
+ 90, 90, 305, 305, 160, 160, 311, 312,
+ 313, 314, 315, 316, 317, 318, 319, 320,
+ 90, 90, 12, 12, 324, 324, 324, 324,
+ 324, 324, 193, 160, 160, 160, 160, 160,
+
+ 160, 325, 305, 326, 160, 90, 90, 90,
+ 90, 90, 90, 160, 160, 160, 160, 90,
+ 90, 160, 160, 90, 90, 90, 90, 90,
+ 90, 90, 90, 90, 90, 90, 90, 90,
+
+ 90, 90, 90, 90, 90, 90, 90, 90,
+ 90, 160, 90, 90, 90, 90, 90, 90,
+ 90, 160, 90, 90, 160, 90, 90, 160,
+ 90, 90, 160, 160, 308, 160, 306, 306,
+
+ 306, 305, 305, 160, 160, 160, 160, 305,
+ 305, 160, 160, 305, 305, 309, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 90, 90, 90, 90, 160, 90, 160,
+
+ 160, 160, 160, 160, 160, 160, 311, 312,
+ 313, 314, 315, 316, 317, 318, 319, 320,
+ 305, 305, 90, 90, 90, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+
+ 160, 305, 305, 306, 160, 90, 90, 90,
+ 90, 90, 90, 90, 307, 90, 160, 90,
+ 90, 90, 160, 90, 90, 90, 90, 90,
+ 90, 90, 90, 90, 90, 90, 90, 90,
+
+ 90, 90, 90, 90, 90, 90, 90, 90,
+ 90, 160, 90, 90, 90, 90, 90, 90,
+ 90, 160, 90, 90, 160, 90, 90, 90,
+ 90, 90, 160, 160, 308, 90, 306, 306,
+
+ 306, 305, 305, 305, 305, 305, 160, 305,
+ 305, 306, 160, 306, 306, 309, 160, 160,
+ 90, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+
+ 90, 307, 325, 325, 160, 160, 311, 312,
+ 313, 314, 315, 316, 317, 318, 319, 320,
+ 160, 327, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+
+ 90, 90, 90, 90, 90, 90, 90, 90,
+ 90, 160, 90, 90, 90, 90, 90, 90,
+ 90, 160, 90, 90, 160, 307, 90, 90,
+ 90, 90, 160, 160, 308, 90, 323, 305,
+
+ 306, 305, 305, 305, 160, 160, 160, 306,
+ 306, 160, 160, 306, 306, 309, 160, 160,
+ 160, 160, 160, 160, 160, 160, 305, 323,
+ 160, 160, 160, 160, 90, 90, 160, 90,
+
+ 90, 90, 160, 160, 160, 160, 311, 312,
+ 313, 314, 315, 316, 317, 318, 319, 320,
+ 193, 307, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+
+ 160, 160, 305, 90, 160, 90, 90, 90,
+ 90, 90, 90, 160, 160, 160, 90, 90,
+ 90, 160, 90, 90, 90, 90, 160, 160,
+ 160, 90, 90, 160, 90, 160, 90, 90,
+
+ 160, 160, 160, 90, 90, 160, 160, 160,
+ 90, 90, 90, 160, 160, 160, 90, 90,
+ 90, 90, 90, 90, 90, 90, 322, 90,
+ 90, 90, 160, 160, 160, 160, 323, 306,
+
+ 305, 306, 306, 160, 160, 160, 306, 306,
+ 306, 160, 306, 306, 306, 309, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 323,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+
+ 160, 160, 160, 160, 160, 160, 328, 312,
+ 313, 314, 315, 316, 317, 318, 319, 320,
+ 324, 324, 324, 238, 238, 238, 238, 238,
+ 238, 327, 238, 160, 160, 160, 160, 160,
+
+ 160, 306, 306, 306, 160, 90, 90, 90,
+ 90, 90, 90, 90, 90, 160, 90, 90,
+ 90, 160, 90, 90, 90, 90, 90, 90,
+ 90, 90, 90, 90, 90, 90, 90, 90,
+
+ 90, 90, 90, 90, 90, 90, 90, 90,
+ 90, 160, 90, 90, 90, 90, 90, 90,
+ 90, 90, 90, 90, 160, 90, 90, 90,
+ 90, 90, 160, 160, 160, 160, 305, 305,
+
+ 305, 306, 306, 306, 306, 160, 305, 305,
+ 305, 160, 305, 305, 305, 309, 160, 160,
+ 160, 160, 160, 160, 160, 329, 330, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+
+ 90, 90, 160, 160, 160, 160, 311, 312,
+ 313, 314, 315, 316, 317, 318, 319, 320,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+
+ 160, 160, 306, 306, 160, 90, 90, 90,
+ 90, 90, 90, 90, 90, 160, 90, 90,
+ 90, 160, 90, 90, 90, 90, 90, 90,
+ 90, 90, 90, 90, 90, 90, 90, 90,
+
+ 90, 90, 90, 90, 90, 90, 90, 90,
+ 90, 160, 90, 90, 90, 90, 90, 90,
+ 90, 90, 90, 90, 160, 90, 90, 90,
+ 90, 90, 160, 160, 331, 307, 306, 332,
+
+ 306, 306, 323, 306, 306, 160, 332, 306,
+ 306, 160, 306, 306, 305, 309, 160, 160,
+ 160, 160, 160, 160, 160, 323, 323, 160,
+ 160, 160, 160, 160, 160, 160, 90, 160,
+
+ 90, 90, 333, 333, 160, 160, 311, 312,
+ 313, 314, 315, 316, 317, 318, 319, 320,
+ 160, 300, 300, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+
+ 90, 90, 90, 90, 90, 90, 90, 90,
+ 90, 160, 90, 90, 90, 90, 90, 90,
+ 90, 90, 90, 90, 90, 90, 90, 90,
+ 90, 90, 160, 160, 160, 160, 323, 306,
+
+ 306, 305, 305, 305, 160, 160, 306, 306,
+ 306, 160, 306, 306, 306, 309, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 323,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+
+ 160, 160, 334, 334, 160, 335, 335, 335,
+ 335, 335, 335, 335, 335, 335, 335, 335,
+ 335, 335, 335, 335, 335, 335, 335, 160,
+ 160, 160, 335, 335, 335, 335, 335, 335,
+
+ 335, 335, 335, 335, 335, 335, 335, 335,
+ 335, 335, 335, 335, 335, 335, 335, 335,
+ 335, 335, 160, 335, 335, 335, 335, 335,
+ 335, 335, 335, 335, 160, 335, 160, 160,
+
+ 335, 335, 335, 335, 335, 335, 335, 160,
+ 160, 160, 336, 160, 160, 160, 160, 337,
+ 334, 334, 284, 284, 284, 160, 284, 160,
+ 334, 334, 334, 334, 334, 334, 334, 337,
+
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 334, 334, 338, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+
+ 160, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 340, 339, 339, 340, 340, 340, 340,
+ 341, 341, 342, 160, 160, 160, 160, 12,
+
+ 339, 339, 339, 339, 339, 339, 343, 340,
+ 344, 344, 344, 344, 340, 340, 340, 198,
+ 311, 312, 313, 314, 315, 316, 317, 318,
+ 319, 320, 345, 345, 160, 160, 160, 160,
+
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+
+ 160, 339, 339, 160, 339, 160, 160, 339,
+ 339, 160, 339, 160, 160, 339, 160, 160,
+ 160, 160, 160, 160, 339, 339, 339, 339,
+ 160, 339, 339, 339, 339, 339, 339, 339,
+
+ 160, 339, 339, 339, 160, 339, 160, 339,
+ 160, 160, 339, 339, 160, 339, 339, 339,
+ 339, 340, 339, 339, 340, 340, 340, 340,
+ 346, 346, 160, 340, 340, 339, 160, 160,
+
+ 339, 339, 339, 339, 339, 160, 343, 160,
+ 347, 347, 347, 347, 340, 340, 160, 160,
+ 311, 312, 313, 314, 315, 316, 317, 318,
+ 319, 320, 160, 160, 339, 339, 160, 160,
+
+ 348, 349, 349, 349, 350, 351, 350, 350,
+ 352, 350, 350, 353, 352, 354, 354, 354,
+ 354, 354, 352, 355, 356, 355, 355, 355,
+ 205, 205, 355, 355, 355, 355, 355, 355,
+
+ 357, 358, 359, 360, 361, 362, 363, 364,
+ 365, 366, 367, 367, 367, 367, 367, 367,
+ 367, 367, 367, 367, 368, 205, 355, 205,
+ 355, 369, 370, 371, 370, 371, 372, 372,
+
+ 348, 348, 348, 348, 348, 348, 348, 348,
+ 160, 348, 348, 348, 348, 348, 348, 348,
+ 348, 348, 348, 348, 348, 348, 348, 348,
+ 348, 348, 348, 348, 348, 348, 348, 348,
+
+ 348, 348, 348, 348, 348, 348, 348, 348,
+ 348, 348, 335, 160, 160, 160, 160, 160,
+ 160, 373, 374, 375, 376, 375, 375, 375,
+ 375, 375, 374, 374, 374, 374, 375, 377,
+
+ 374, 375, 206, 206, 378, 353, 206, 206,
+ 348, 348, 348, 348, 160, 160, 160, 160,
+ 375, 375, 375, 375, 375, 375, 284, 375,
+ 160, 375, 375, 375, 375, 375, 375, 375,
+
+ 375, 375, 375, 375, 375, 375, 375, 375,
+ 375, 375, 375, 375, 375, 375, 284, 284,
+ 284, 375, 375, 375, 375, 375, 375, 375,
+ 284, 375, 284, 284, 284, 160, 379, 379,
+
+ 380, 380, 380, 380, 380, 380, 147, 380,
+ 380, 380, 380, 380, 380, 160, 160, 380,
+ 381, 381, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+
+ 382, 382, 382, 382, 382, 382, 382, 382,
+ 382, 382, 382, 382, 382, 382, 382, 382,
+ 382, 382, 382, 382, 382, 382, 382, 382,
+ 382, 382, 382, 382, 382, 382, 382, 382,
+
+ 382, 382, 160, 382, 382, 382, 382, 382,
+ 160, 382, 382, 160, 383, 384, 384, 384,
+ 384, 383, 384, 160, 160, 160, 384, 385,
+ 383, 386, 160, 160, 160, 160, 160, 160,
+
+ 387, 388, 389, 390, 391, 392, 393, 394,
+ 395, 396, 397, 397, 338, 338, 338, 338,
+ 382, 382, 382, 382, 382, 382, 383, 383,
+ 384, 384, 160, 160, 160, 160, 160, 160,
+
+ 398, 398, 398, 398, 398, 398, 398, 398,
+ 398, 398, 398, 398, 398, 398, 398, 398,
+ 398, 398, 398, 398, 398, 398, 398, 398,
+ 398, 398, 398, 398, 398, 398, 398, 398,
+
+ 398, 398, 398, 398, 398, 398, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 90, 90, 90, 90, 90, 90, 90, 90,
+ 90, 90, 90, 90, 90, 90, 90, 90,
+
+ 90, 90, 90, 90, 90, 90, 90, 90,
+ 90, 90, 90, 90, 90, 90, 90, 90,
+ 90, 90, 90, 90, 90, 90, 90, 399,
+ 399, 322, 322, 198, 400, 160, 160, 160,
+
+ 401, 401, 401, 401, 401, 401, 401, 401,
+ 401, 401, 401, 401, 401, 401, 401, 401,
+ 401, 401, 401, 401, 401, 401, 401, 401,
+ 401, 401, 401, 401, 401, 401, 401, 401,
+
+ 401, 401, 401, 401, 401, 401, 401, 401,
+ 401, 401, 401, 401, 401, 401, 401, 401,
+ 401, 401, 401, 401, 401, 401, 401, 401,
+ 401, 401, 160, 160, 160, 160, 160, 401,
+
+ 402, 402, 402, 402, 402, 402, 402, 402,
+ 402, 402, 402, 402, 402, 402, 402, 402,
+ 402, 402, 402, 402, 402, 402, 402, 402,
+ 402, 402, 402, 402, 402, 402, 402, 402,
+
+ 402, 402, 402, 160, 160, 160, 160, 160,
+ 403, 403, 403, 403, 403, 403, 403, 403,
+ 403, 403, 403, 403, 403, 403, 403, 403,
+ 403, 403, 403, 403, 403, 403, 403, 403,
+
+ 403, 403, 403, 403, 403, 403, 403, 403,
+ 403, 403, 403, 403, 403, 403, 403, 403,
+ 403, 403, 403, 403, 403, 403, 403, 403,
+ 403, 403, 403, 403, 403, 403, 403, 403,
+
+ 403, 403, 403, 403, 403, 403, 403, 403,
+ 403, 403, 403, 403, 403, 403, 403, 403,
+ 403, 403, 403, 403, 403, 403, 403, 403,
+ 403, 403, 160, 160, 160, 160, 160, 160,
+
+ 335, 335, 335, 335, 335, 335, 335, 322,
+ 335, 335, 335, 335, 335, 335, 335, 335,
+ 335, 335, 335, 335, 335, 335, 335, 335,
+ 335, 335, 335, 335, 335, 335, 335, 335,
+
+ 335, 335, 335, 335, 335, 335, 335, 335,
+ 335, 335, 335, 335, 335, 335, 335, 335,
+ 335, 335, 335, 335, 335, 335, 335, 335,
+ 335, 335, 335, 335, 335, 335, 335, 335,
+
+ 335, 335, 335, 335, 335, 335, 335, 322,
+ 335, 160, 335, 335, 335, 335, 160, 160,
+ 335, 335, 335, 335, 335, 335, 335, 160,
+ 335, 160, 335, 335, 335, 335, 160, 160,
+
+ 335, 335, 335, 335, 335, 335, 335, 322,
+ 335, 160, 335, 335, 335, 335, 160, 160,
+ 335, 335, 335, 335, 335, 335, 335, 335,
+ 335, 335, 335, 335, 335, 335, 335, 335,
+
+ 335, 335, 335, 335, 335, 335, 335, 335,
+ 335, 335, 335, 335, 335, 335, 335, 322,
+ 335, 160, 335, 335, 335, 335, 160, 160,
+ 335, 335, 335, 335, 335, 335, 335, 160,
+
+ 335, 160, 335, 335, 335, 335, 160, 160,
+ 335, 335, 335, 335, 335, 335, 335, 322,
+ 335, 335, 335, 335, 335, 335, 335, 160,
+ 335, 335, 335, 335, 335, 335, 335, 335,
+
+ 335, 335, 335, 335, 335, 335, 335, 335,
+ 335, 335, 335, 335, 335, 335, 335, 322,
+ 335, 335, 335, 335, 335, 335, 335, 335,
+ 335, 335, 335, 335, 335, 335, 335, 335,
+
+ 335, 335, 335, 335, 335, 335, 335, 335,
+ 335, 335, 335, 335, 335, 335, 335, 322,
+ 335, 160, 335, 335, 335, 335, 160, 160,
+ 335, 335, 335, 335, 335, 335, 335, 322,
+
+ 335, 335, 335, 335, 335, 335, 335, 322,
+ 335, 335, 335, 335, 335, 335, 335, 335,
+ 335, 335, 335, 335, 335, 335, 335, 335,
+ 335, 335, 335, 160, 160, 160, 160, 153,
+
+ 404, 405, 406, 338, 338, 338, 338, 406,
+ 406, 407, 408, 409, 410, 411, 412, 413,
+ 414, 415, 416, 416, 416, 416, 416, 416,
+ 416, 416, 416, 416, 416, 160, 160, 160,
+
+ 322, 322, 322, 322, 322, 322, 322, 322,
+ 322, 322, 322, 322, 322, 322, 322, 322,
+ 417, 417, 417, 417, 417, 417, 417, 417,
+ 417, 417, 160, 160, 160, 160, 160, 160,
+
+ 335, 335, 335, 335, 335, 335, 335, 335,
+ 335, 335, 335, 335, 335, 335, 335, 335,
+ 335, 335, 335, 335, 335, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+
+ 160, 335, 335, 335, 335, 335, 335, 335,
+ 335, 335, 335, 335, 335, 335, 335, 335,
+ 335, 335, 335, 335, 335, 335, 335, 335,
+ 335, 335, 335, 335, 335, 335, 335, 335,
+
+ 335, 335, 335, 335, 335, 335, 335, 335,
+ 335, 335, 335, 335, 335, 338, 406, 335,
+ 335, 335, 335, 335, 335, 335, 335, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+
+ 418, 335, 335, 335, 335, 335, 335, 335,
+ 335, 335, 335, 335, 335, 335, 335, 335,
+ 335, 335, 335, 335, 335, 335, 335, 335,
+ 335, 335, 335, 419, 420, 160, 160, 160,
+
+ 335, 335, 335, 335, 335, 335, 335, 335,
+ 335, 335, 335, 405, 405, 405, 421, 421,
+ 421, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+
+ 399, 399, 399, 399, 399, 399, 399, 399,
+ 399, 399, 399, 399, 399, 160, 399, 399,
+ 399, 399, 422, 422, 423, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+
+ 399, 399, 399, 399, 399, 399, 399, 399,
+ 399, 399, 399, 399, 399, 399, 399, 399,
+ 399, 399, 422, 422, 423, 424, 424, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+
+ 399, 399, 399, 399, 399, 399, 399, 399,
+ 399, 399, 399, 399, 399, 399, 399, 399,
+ 399, 399, 422, 422, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+
+ 399, 399, 399, 399, 399, 399, 399, 399,
+ 399, 399, 399, 399, 399, 160, 399, 399,
+ 399, 160, 422, 422, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+
+ 382, 382, 382, 382, 382, 382, 382, 382,
+ 382, 382, 382, 382, 382, 382, 382, 382,
+ 382, 382, 382, 382, 425, 425, 383, 384,
+ 384, 384, 384, 384, 384, 384, 383, 383,
+
+ 383, 383, 383, 383, 383, 383, 384, 383,
+ 383, 384, 384, 384, 384, 384, 384, 384,
+ 384, 384, 386, 384, 405, 405, 426, 427,
+ 405, 338, 405, 428, 382, 429, 160, 160,
+
+ 387, 388, 389, 390, 391, 392, 393, 394,
+ 395, 396, 160, 160, 160, 160, 160, 160,
+ 430, 430, 430, 430, 430, 430, 430, 430,
+ 430, 430, 160, 160, 160, 160, 160, 160,
+
+ 431, 431, 432, 433, 432, 432, 434, 431,
+ 432, 433, 431, 284, 284, 284, 435, 160,
+ 387, 388, 389, 390, 391, 392, 393, 394,
+ 395, 396, 160, 160, 160, 160, 160, 160,
+
+ 335, 335, 335, 137, 335, 335, 335, 335,
+ 335, 335, 335, 335, 335, 335, 335, 335,
+ 335, 335, 335, 335, 335, 335, 335, 335,
+ 335, 335, 335, 335, 335, 335, 335, 335,
+
+ 335, 335, 335, 335, 335, 335, 335, 335,
+ 335, 335, 335, 335, 335, 335, 335, 335,
+ 335, 335, 335, 335, 335, 335, 335, 335,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+
+ 335, 335, 335, 335, 335, 335, 335, 335,
+ 335, 436, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+
+ 307, 307, 307, 307, 307, 307, 307, 307,
+ 307, 307, 307, 307, 307, 307, 307, 307,
+ 307, 307, 307, 307, 307, 307, 307, 307,
+ 307, 307, 307, 307, 307, 160, 160, 160,
+
+ 325, 325, 325, 326, 326, 326, 326, 325,
+ 325, 437, 437, 437, 160, 160, 160, 160,
+ 326, 326, 325, 326, 326, 326, 326, 326,
+ 326, 438, 149, 150, 160, 160, 160, 160,
+
+ 238, 160, 160, 160, 439, 439, 440, 441,
+ 442, 443, 444, 445, 446, 447, 448, 449,
+ 450, 450, 450, 450, 450, 450, 450, 450,
+ 450, 450, 450, 450, 450, 450, 450, 450,
+
+ 450, 450, 450, 450, 450, 450, 450, 450,
+ 450, 450, 450, 450, 450, 450, 160, 160,
+ 450, 450, 450, 450, 450, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+
+ 451, 451, 451, 451, 451, 451, 451, 451,
+ 451, 451, 451, 451, 451, 451, 451, 451,
+ 451, 451, 451, 451, 451, 451, 451, 451,
+ 451, 451, 451, 451, 451, 451, 451, 451,
+
+ 451, 451, 451, 451, 451, 451, 451, 451,
+ 451, 451, 160, 160, 160, 160, 160, 160,
+ 452, 452, 452, 452, 452, 452, 452, 452,
+ 452, 452, 452, 452, 452, 452, 452, 452,
+
+ 452, 451, 451, 451, 451, 451, 451, 451,
+ 452, 452, 160, 160, 160, 160, 160, 160,
+ 328, 453, 454, 455, 456, 457, 458, 459,
+ 460, 461, 160, 160, 160, 160, 462, 462,
+
+ 238, 238, 238, 238, 238, 238, 238, 238,
+ 238, 238, 238, 238, 238, 238, 238, 238,
+ 238, 238, 238, 238, 238, 238, 238, 238,
+ 238, 238, 238, 238, 238, 238, 238, 238,
+
+ 322, 322, 322, 322, 322, 322, 322, 322,
+ 322, 322, 322, 322, 322, 322, 322, 322,
+ 322, 322, 322, 322, 322, 322, 322, 153,
+ 152, 463, 463, 463, 160, 160, 464, 465,
+
+ 333, 333, 333, 333, 466, 321, 321, 321,
+ 321, 321, 321, 321, 321, 321, 321, 321,
+ 321, 321, 321, 321, 321, 321, 321, 321,
+ 321, 321, 321, 321, 321, 321, 321, 321,
+
+ 321, 321, 321, 321, 321, 321, 321, 321,
+ 321, 321, 321, 321, 321, 321, 321, 321,
+ 321, 321, 321, 321, 467, 466, 333, 333,
+ 333, 333, 333, 466, 333, 466, 466, 466,
+
+ 466, 466, 333, 466, 468, 321, 321, 321,
+ 321, 321, 321, 321, 160, 160, 160, 160,
+ 469, 470, 471, 472, 473, 474, 475, 476,
+ 477, 478, 479, 479, 480, 480, 479, 479,
+
+ 480, 481, 481, 481, 481, 481, 481, 481,
+ 481, 481, 481, 297, 298, 297, 297, 297,
+ 297, 297, 297, 297, 481, 481, 481, 481,
+ 481, 481, 481, 481, 481, 160, 160, 160,
+
+ 102, 102, 102, 102, 102, 102, 102, 102,
+ 102, 102, 102, 102, 102, 102, 102, 102,
+ 102, 102, 102, 102, 102, 102, 102, 102,
+ 102, 102, 102, 102, 102, 102, 102, 102,
+
+ 102, 102, 102, 102, 102, 102, 102, 102,
+ 102, 102, 102, 102, 482, 482, 482, 482,
+ 482, 482, 482, 482, 482, 482, 482, 482,
+ 482, 482, 482, 482, 482, 482, 482, 482,
+
+ 482, 482, 482, 482, 482, 482, 482, 482,
+ 482, 482, 482, 482, 482, 482, 482, 482,
+ 482, 482, 482, 482, 482, 482, 482, 482,
+ 482, 482, 482, 482, 482, 482, 482, 482,
+
+ 482, 482, 102, 102, 102, 102, 102, 102,
+ 102, 102, 102, 102, 103, 103, 103, 103,
+ 103, 103, 103, 103, 103, 103, 103, 103,
+ 483, 103, 103, 103, 103, 484, 103, 103,
+
+ 103, 103, 103, 103, 103, 103, 103, 103,
+ 103, 103, 103, 103, 103, 103, 103, 103,
+ 103, 103, 103, 103, 103, 103, 103, 103,
+ 103, 103, 103, 483, 483, 483, 483, 483,
+
+ 483, 483, 483, 483, 483, 483, 483, 483,
+ 483, 483, 483, 483, 483, 483, 483, 483,
+ 483, 483, 483, 483, 483, 483, 483, 483,
+ 483, 483, 483, 483, 483, 483, 483, 483,
+
+ 153, 153, 152, 153, 297, 297, 297, 297,
+ 297, 297, 298, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 297, 298,
+
+ 65, 66, 65, 66, 65, 66, 65, 66,
+ 65, 66, 65, 66, 65, 66, 65, 66,
+ 65, 66, 65, 66, 65, 66, 485, 486,
+ 487, 488, 489, 490, 160, 160, 160, 160,
+
+ 65, 66, 65, 66, 65, 66, 65, 66,
+ 65, 66, 65, 66, 65, 66, 65, 66,
+ 65, 66, 65, 66, 65, 66, 65, 66,
+ 65, 66, 160, 160, 160, 160, 160, 160,
+
+ 491, 491, 491, 491, 491, 491, 491, 491,
+ 492, 492, 492, 492, 492, 492, 492, 492,
+ 491, 491, 491, 491, 491, 491, 160, 160,
+ 492, 492, 492, 492, 492, 492, 160, 160,
+
+ 491, 491, 491, 491, 491, 491, 491, 491,
+ 492, 492, 492, 492, 492, 492, 492, 492,
+ 491, 491, 491, 491, 491, 491, 491, 491,
+ 492, 492, 492, 492, 492, 492, 492, 492,
+
+ 491, 491, 491, 491, 491, 491, 160, 160,
+ 492, 492, 492, 492, 492, 492, 160, 160,
+ 493, 491, 494, 491, 495, 491, 496, 491,
+ 160, 492, 160, 492, 160, 492, 160, 492,
+
+ 491, 491, 491, 491, 491, 491, 491, 491,
+ 492, 492, 492, 492, 492, 492, 492, 492,
+ 497, 497, 498, 498, 498, 498, 499, 499,
+ 500, 500, 501, 501, 502, 502, 160, 160,
+
+ 503, 504, 505, 506, 507, 508, 509, 510,
+ 511, 512, 513, 514, 515, 516, 517, 518,
+ 519, 520, 521, 522, 523, 524, 525, 526,
+ 527, 528, 529, 530, 531, 532, 533, 534,
+
+ 535, 536, 537, 538, 539, 540, 541, 542,
+ 543, 544, 545, 546, 547, 548, 549, 550,
+ 491, 491, 551, 552, 553, 160, 554, 555,
+ 492, 492, 556, 556, 557, 42, 558, 42,
+
+ 42, 42, 559, 560, 561, 160, 562, 563,
+ 564, 564, 564, 564, 565, 42, 42, 42,
+ 491, 491, 566, 567, 160, 160, 568, 569,
+ 492, 492, 570, 570, 160, 42, 42, 42,
+
+ 491, 491, 571, 572, 573, 182, 574, 575,
+ 492, 492, 576, 576, 577, 42, 42, 42,
+ 160, 160, 578, 579, 580, 160, 581, 582,
+ 583, 583, 584, 584, 585, 42, 42, 160,
+
+ 586, 586, 586, 586, 586, 586, 586, 587,
+ 586, 586, 586, 588, 589, 590, 591, 592,
+ 593, 594, 593, 593, 595, 596, 14, 14,
+ 597, 598, 599, 600, 597, 601, 599, 600,
+
+ 14, 14, 14, 14, 602, 602, 602, 603,
+ 604, 605, 606, 607, 608, 609, 610, 611,
+ 13, 13, 13, 13, 13, 612, 612, 612,
+ 14, 597, 601, 14, 613, 613, 14, 43,
+
+ 43, 14, 14, 14, 614, 16, 17, 615,
+ 616, 616, 431, 431, 431, 431, 617, 617,
+ 617, 617, 185, 618, 619, 620, 621, 617,
+ 621, 621, 621, 621, 620, 621, 621, 622,
+
+ 623, 624, 624, 624, 160, 160, 160, 160,
+ 160, 160, 625, 625, 625, 625, 625, 625,
+ 626, 627, 160, 160, 628, 629, 630, 631,
+ 632, 633, 634, 634, 36, 16, 17, 50,
+
+ 626, 60, 55, 56, 628, 629, 630, 631,
+ 632, 633, 634, 634, 36, 16, 17, 160,
+ 483, 483, 483, 483, 483, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+
+ 12, 12, 12, 12, 12, 12, 12, 48,
+ 12, 12, 12, 635, 636, 428, 428, 428,
+ 637, 637, 638, 638, 638, 638, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 139, 139, 144, 144, 139, 139, 139, 139,
+ 144, 144, 144, 139, 139, 272, 272, 272,
+
+ 272, 139, 194, 194, 639, 640, 640, 159,
+ 641, 159, 640, 642, 298, 298, 298, 298,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+
+ 49, 49, 175, 643, 49, 49, 49, 175,
+ 49, 643, 50, 175, 175, 175, 50, 50,
+ 175, 175, 175, 50, 49, 175, 644, 49,
+ 49, 175, 175, 175, 175, 175, 49, 49,
+
+ 49, 49, 49, 49, 175, 49, 645, 49,
+ 175, 49, 646, 647, 175, 175, 648, 50,
+ 175, 175, 649, 175, 50, 90, 90, 90,
+ 90, 131, 650, 238, 103, 627, 651, 651,
+
+ 185, 185, 185, 185, 185, 651, 627, 627,
+ 627, 627, 652, 185, 417, 300, 653, 160,
+ 160, 160, 160, 62, 62, 62, 62, 62,
+ 62, 62, 62, 62, 62, 62, 62, 62,
+
+ 654, 654, 654, 654, 654, 654, 654, 654,
+ 654, 654, 654, 654, 654, 654, 654, 654,
+ 655, 655, 655, 655, 655, 655, 655, 655,
+ 655, 655, 655, 655, 655, 655, 655, 655,
+
+ 656, 656, 656, 99, 109, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 36, 36, 36, 36, 36, 49, 49, 49,
+ 49, 49, 36, 36, 49, 49, 49, 49,
+
+ 36, 49, 49, 36, 49, 49, 36, 49,
+ 49, 49, 49, 49, 49, 49, 36, 49,
+ 49, 49, 49, 49, 49, 49, 49, 49,
+ 49, 49, 49, 49, 49, 49, 49, 49,
+
+ 49, 49, 49, 49, 49, 49, 49, 49,
+ 49, 49, 49, 49, 49, 49, 36, 36,
+ 49, 49, 36, 49, 36, 49, 49, 49,
+ 49, 49, 49, 49, 49, 49, 49, 49,
+
+ 49, 49, 49, 49, 49, 49, 49, 49,
+ 49, 49, 49, 650, 650, 650, 650, 650,
+ 650, 650, 650, 650, 185, 185, 185, 185,
+ 185, 185, 185, 185, 185, 185, 185, 185,
+
+ 36, 36, 36, 36, 36, 36, 36, 36,
+ 657, 657, 657, 658, 658, 658, 36, 36,
+ 36, 36, 18, 54, 36, 659, 36, 36,
+ 36, 36, 36, 36, 36, 36, 36, 36,
+
+ 36, 36, 36, 36, 36, 36, 36, 36,
+ 36, 36, 36, 36, 36, 36, 36, 36,
+ 36, 36, 36, 36, 36, 36, 36, 36,
+ 36, 36, 36, 36, 660, 661, 36, 36,
+
+ 36, 36, 36, 662, 36, 36, 36, 36,
+ 36, 36, 36, 36, 36, 36, 36, 36,
+ 36, 36, 660, 661, 660, 661, 36, 36,
+ 36, 36, 36, 36, 36, 36, 36, 36,
+
+ 36, 36, 36, 36, 660, 661, 660, 661,
+ 660, 661, 660, 661, 36, 36, 660, 661,
+ 660, 661, 660, 661, 660, 661, 660, 661,
+ 660, 661, 660, 661, 660, 661, 660, 661,
+
+ 660, 661, 660, 661, 660, 661, 660, 661,
+ 660, 661, 660, 661, 36, 36, 36, 660,
+ 661, 660, 661, 36, 36, 36, 36, 36,
+ 663, 36, 36, 36, 36, 36, 36, 36,
+
+ 36, 36, 660, 661, 36, 36, 664, 36,
+ 665, 666, 36, 666, 36, 36, 36, 36,
+ 660, 661, 660, 661, 660, 661, 660, 661,
+ 36, 36, 36, 36, 36, 36, 36, 36,
+
+ 36, 36, 36, 36, 36, 36, 36, 36,
+ 36, 660, 661, 660, 661, 667, 36, 36,
+ 660, 661, 36, 36, 36, 36, 660, 661,
+ 660, 661, 660, 661, 660, 661, 660, 661,
+
+ 660, 661, 660, 661, 660, 661, 660, 661,
+ 660, 661, 660, 661, 660, 661, 36, 36,
+ 660, 661, 668, 668, 668, 185, 669, 669,
+ 185, 185, 670, 670, 670, 671, 671, 185,
+
+ 49, 650, 49, 49, 49, 49, 49, 49,
+ 660, 661, 660, 661, 49, 49, 49, 49,
+ 49, 49, 49, 49, 49, 49, 49, 49,
+ 49, 49, 49, 49, 49, 49, 49, 49,
+
+ 36, 36, 49, 49, 49, 49, 49, 49,
+ 49, 16, 17, 49, 49, 49, 49, 49,
+ 49, 49, 49, 49, 49, 49, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 650, 185, 650, 650, 650,
+
+ 650, 650, 650, 650, 650, 650, 650, 650,
+ 650, 650, 650, 650, 650, 650, 650, 650,
+ 650, 650, 650, 650, 650, 380, 650, 650,
+ 650, 650, 650, 185, 185, 185, 185, 185,
+
+ 185, 185, 185, 185, 185, 185, 185, 185,
+ 185, 185, 185, 185, 185, 185, 185, 185,
+ 185, 185, 185, 185, 652, 652, 652, 652,
+ 652, 652, 652, 652, 652, 652, 652, 652,
+
+ 652, 652, 652, 652, 652, 652, 652, 652,
+ 652, 652, 652, 652, 652, 652, 652, 238,
+ 238, 417, 417, 417, 417, 417, 417, 417,
+ 417, 417, 417, 417, 672, 672, 672, 672,
+
+ 672, 672, 300, 300, 300, 300, 300, 300,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+
+ 49, 49, 49, 49, 49, 49, 49, 49,
+ 49, 49, 49, 49, 49, 49, 49, 49,
+ 49, 49, 49, 49, 49, 49, 49, 49,
+ 49, 49, 49, 49, 49, 49, 49, 49,
+
+ 49, 49, 49, 49, 49, 650, 650, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+
+ 49, 49, 49, 49, 49, 49, 49, 49,
+ 49, 49, 49, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+
+ 673, 674, 675, 676, 677, 678, 679, 680,
+ 681, 62, 62, 62, 62, 62, 62, 62,
+ 62, 62, 62, 62, 673, 674, 675, 676,
+ 677, 678, 679, 680, 681, 62, 62, 62,
+
+ 62, 62, 62, 62, 62, 62, 62, 62,
+ 60, 55, 56, 628, 629, 630, 631, 632,
+ 633, 682, 682, 682, 682, 682, 682, 682,
+ 682, 682, 682, 682, 193, 193, 193, 193,
+
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 683, 683,
+ 683, 683, 683, 683, 683, 683, 683, 683,
+
+ 683, 683, 683, 683, 683, 683, 683, 683,
+ 683, 683, 683, 683, 683, 683, 683, 683,
+ 684, 684, 684, 684, 684, 684, 684, 684,
+ 684, 684, 684, 684, 684, 684, 684, 684,
+
+ 684, 684, 684, 684, 684, 684, 684, 684,
+ 684, 684, 685, 686, 686, 686, 686, 686,
+ 686, 686, 686, 686, 686, 687, 688, 689,
+ 690, 691, 692, 693, 694, 695, 686, 696,
+
+ 49, 49, 49, 49, 49, 49, 49, 49,
+ 49, 49, 49, 49, 49, 49, 49, 49,
+ 49, 49, 49, 49, 49, 49, 652, 652,
+ 652, 652, 652, 652, 652, 652, 652, 652,
+
+ 49, 49, 49, 49, 49, 49, 49, 49,
+ 49, 49, 49, 49, 49, 49, 49, 49,
+ 49, 49, 49, 49, 49, 49, 49, 36,
+ 49, 49, 49, 49, 49, 49, 49, 49,
+
+ 49, 36, 49, 49, 49, 49, 49, 49,
+ 49, 49, 49, 49, 49, 49, 49, 49,
+ 49, 49, 49, 49, 49, 49, 49, 49,
+ 49, 49, 49, 49, 49, 49, 49, 49,
+
+ 49, 49, 49, 49, 49, 49, 49, 49,
+ 49, 49, 49, 49, 49, 49, 49, 49,
+ 650, 650, 650, 650, 650, 650, 650, 650,
+ 185, 185, 185, 185, 185, 185, 185, 185,
+
+ 49, 49, 49, 49, 49, 49, 49, 49,
+ 49, 49, 49, 49, 49, 49, 49, 49,
+ 49, 49, 49, 49, 238, 238, 652, 652,
+ 417, 650, 49, 49, 49, 49, 49, 49,
+
+ 49, 49, 49, 49, 49, 49, 49, 49,
+ 49, 49, 49, 49, 49, 49, 49, 36,
+ 650, 650, 652, 652, 652, 652, 652, 652,
+ 652, 652, 652, 652, 652, 652, 417, 417,
+
+ 652, 652, 652, 652, 652, 652, 652, 652,
+ 652, 652, 238, 238, 238, 238, 238, 238,
+ 238, 238, 417, 417, 417, 417, 417, 417,
+ 417, 417, 417, 417, 417, 160, 160, 160,
+
+ 238, 238, 417, 417, 417, 417, 417, 417,
+ 417, 417, 417, 417, 404, 417, 417, 417,
+ 417, 417, 300, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+
+ 160, 49, 49, 49, 49, 160, 49, 49,
+ 49, 49, 160, 160, 49, 49, 49, 49,
+ 49, 49, 49, 49, 49, 49, 49, 49,
+ 49, 49, 49, 49, 49, 49, 49, 49,
+
+ 49, 49, 49, 49, 49, 49, 49, 49,
+ 160, 49, 49, 49, 49, 49, 49, 49,
+ 49, 49, 49, 49, 49, 49, 49, 49,
+ 49, 49, 49, 49, 49, 49, 49, 49,
+
+ 49, 49, 49, 49, 49, 49, 49, 49,
+ 49, 49, 49, 49, 160, 49, 160, 49,
+ 49, 49, 49, 160, 160, 160, 49, 160,
+ 49, 49, 49, 697, 697, 697, 697, 160,
+
+ 160, 49, 698, 698, 49, 49, 49, 49,
+ 699, 700, 699, 700, 699, 700, 699, 700,
+ 699, 700, 699, 700, 699, 700, 673, 674,
+ 675, 676, 677, 678, 679, 680, 681, 62,
+
+ 673, 674, 675, 676, 677, 678, 679, 680,
+ 681, 62, 673, 674, 675, 676, 677, 678,
+ 679, 680, 681, 62, 49, 160, 160, 160,
+ 49, 49, 49, 49, 49, 49, 49, 49,
+
+ 49, 49, 49, 49, 49, 49, 49, 49,
+ 49, 49, 49, 49, 49, 49, 49, 49,
+ 160, 49, 49, 49, 49, 49, 49, 49,
+ 49, 49, 49, 49, 49, 49, 49, 160,
+
+ 701, 701, 701, 702, 703, 704, 705, 672,
+ 672, 672, 672, 160, 160, 160, 160, 160,
+ 185, 185, 185, 185, 185, 706, 707, 185,
+ 185, 185, 185, 185, 185, 706, 707, 185,
+
+ 185, 185, 706, 707, 706, 707, 699, 700,
+ 699, 700, 699, 700, 160, 160, 160, 160,
+ 185, 185, 185, 185, 185, 185, 185, 185,
+ 185, 185, 185, 185, 185, 185, 185, 185,
+
+ 380, 380, 380, 380, 380, 380, 380, 380,
+ 380, 380, 380, 380, 380, 380, 380, 380,
+ 380, 380, 380, 380, 380, 380, 380, 380,
+ 380, 380, 380, 380, 380, 380, 380, 380,
+
+ 185, 185, 185, 185, 185, 185, 185, 185,
+ 185, 185, 185, 185, 185, 185, 185, 185,
+ 185, 185, 185, 185, 185, 185, 185, 185,
+ 185, 185, 185, 185, 185, 185, 185, 185,
+
+ 185, 185, 185, 699, 700, 699, 700, 699,
+ 700, 699, 700, 699, 700, 708, 709, 710,
+ 711, 699, 700, 699, 700, 699, 700, 699,
+ 700, 185, 185, 185, 185, 185, 185, 185,
+
+ 185, 185, 185, 185, 185, 185, 185, 185,
+ 185, 185, 185, 185, 185, 185, 185, 185,
+ 185, 185, 185, 185, 185, 185, 185, 185,
+ 712, 185, 185, 185, 185, 185, 185, 185,
+
+ 706, 707, 185, 185, 706, 707, 185, 185,
+ 185, 185, 185, 185, 185, 185, 185, 706,
+ 707, 706, 707, 185, 706, 707, 185, 185,
+ 699, 700, 699, 700, 185, 185, 185, 185,
+
+ 185, 185, 185, 185, 185, 185, 185, 185,
+ 185, 185, 185, 185, 185, 185, 185, 185,
+ 185, 185, 185, 185, 185, 713, 185, 185,
+ 706, 707, 185, 185, 699, 700, 185, 185,
+
+ 185, 185, 185, 185, 185, 185, 185, 185,
+ 185, 185, 185, 706, 707, 706, 707, 185,
+ 185, 185, 185, 185, 706, 707, 185, 185,
+ 185, 185, 185, 185, 706, 707, 185, 185,
+
+ 185, 185, 185, 185, 706, 707, 185, 185,
+ 185, 185, 185, 185, 185, 185, 185, 185,
+ 185, 185, 185, 185, 185, 185, 185, 185,
+ 185, 706, 707, 185, 185, 706, 707, 706,
+
+ 707, 706, 707, 706, 707, 185, 185, 185,
+ 185, 185, 185, 706, 707, 185, 185, 185,
+ 185, 706, 707, 706, 707, 706, 707, 706,
+ 707, 706, 707, 706, 707, 185, 185, 185,
+
+ 185, 706, 707, 185, 185, 185, 706, 707,
+ 706, 707, 706, 707, 706, 707, 185, 706,
+ 707, 185, 185, 706, 707, 185, 185, 185,
+ 185, 185, 185, 706, 707, 706, 707, 706,
+
+ 707, 706, 707, 706, 707, 706, 707, 185,
+ 185, 185, 185, 185, 185, 706, 707, 706,
+ 707, 706, 707, 706, 707, 706, 707, 185,
+ 185, 185, 185, 185, 185, 185, 714, 185,
+
+ 185, 185, 185, 715, 716, 715, 185, 185,
+ 185, 185, 185, 185, 706, 707, 185, 185,
+ 185, 185, 185, 185, 185, 185, 185, 706,
+ 707, 706, 707, 185, 185, 185, 185, 185,
+
+ 238, 238, 238, 238, 238, 238, 238, 238,
+ 238, 238, 238, 238, 238, 238, 417, 417,
+ 417, 417, 417, 417, 300, 300, 300, 300,
+ 300, 300, 300, 160, 160, 160, 160, 160,
+
+ 300, 300, 300, 300, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+
+ 717, 717, 717, 717, 717, 717, 717, 717,
+ 717, 717, 717, 717, 717, 717, 717, 717,
+ 717, 717, 717, 717, 717, 717, 717, 717,
+ 717, 717, 717, 717, 717, 717, 717, 717,
+
+ 717, 717, 717, 717, 717, 717, 717, 717,
+ 717, 717, 717, 717, 717, 717, 717, 160,
+ 718, 718, 718, 718, 718, 718, 718, 718,
+ 718, 718, 718, 718, 718, 718, 718, 718,
+
+ 718, 718, 718, 718, 718, 718, 718, 718,
+ 718, 718, 718, 718, 718, 718, 718, 718,
+ 718, 718, 718, 718, 718, 718, 718, 718,
+ 718, 718, 718, 718, 718, 718, 718, 160,
+
+ 113, 109, 719, 720, 721, 722, 723, 113,
+ 109, 113, 109, 113, 109, 160, 160, 160,
+ 160, 160, 160, 160, 724, 113, 109, 724,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+
+ 105, 106, 105, 106, 105, 106, 105, 106,
+ 105, 106, 105, 106, 105, 106, 105, 106,
+ 105, 106, 105, 106, 105, 106, 105, 106,
+ 105, 106, 105, 106, 105, 106, 105, 106,
+
+ 105, 106, 105, 106, 103, 417, 417, 417,
+ 417, 417, 417, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 621, 621, 621, 621, 725, 621, 621,
+
+ 726, 726, 726, 726, 726, 726, 726, 726,
+ 726, 726, 726, 726, 726, 726, 726, 726,
+ 726, 726, 726, 726, 726, 726, 726, 726,
+ 726, 726, 726, 726, 726, 726, 726, 726,
+
+ 726, 726, 726, 726, 726, 726, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 322, 322, 322, 322, 322, 322, 322, 322,
+ 322, 322, 322, 322, 322, 322, 322, 322,
+
+ 322, 322, 322, 322, 322, 322, 322, 322,
+ 322, 322, 322, 322, 322, 322, 322, 322,
+ 322, 322, 322, 322, 322, 322, 322, 322,
+ 322, 322, 322, 322, 322, 322, 322, 322,
+
+ 322, 322, 322, 322, 322, 322, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 400,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+
+ 322, 322, 322, 322, 322, 322, 322, 322,
+ 322, 322, 322, 322, 322, 322, 322, 322,
+ 322, 322, 322, 322, 322, 322, 322, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+
+ 322, 322, 322, 322, 322, 322, 322, 160,
+ 322, 322, 322, 322, 322, 322, 322, 160,
+ 322, 322, 322, 322, 322, 322, 322, 160,
+ 322, 322, 322, 322, 322, 322, 322, 160,
+
+ 727, 727, 728, 729, 728, 729, 727, 727,
+ 727, 728, 729, 727, 728, 729, 621, 621,
+ 621, 621, 621, 621, 621, 621, 620, 730,
+ 160, 160, 160, 160, 728, 729, 160, 160,
+
+ 731, 731, 731, 731, 731, 731, 731, 731,
+ 731, 731, 731, 731, 731, 731, 731, 731,
+ 731, 731, 731, 731, 731, 731, 731, 731,
+ 731, 731, 160, 731, 731, 731, 731, 731,
+
+ 731, 731, 731, 731, 731, 731, 731, 731,
+ 731, 731, 731, 731, 731, 731, 731, 731,
+ 731, 731, 731, 731, 731, 731, 731, 731,
+ 731, 731, 731, 731, 731, 731, 731, 731,
+
+ 731, 731, 731, 731, 731, 731, 731, 731,
+ 731, 731, 731, 731, 731, 731, 731, 731,
+ 731, 731, 731, 731, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+
+ 731, 731, 731, 731, 731, 731, 731, 731,
+ 731, 731, 731, 731, 731, 731, 731, 731,
+ 731, 731, 731, 731, 731, 731, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 731, 731, 731, 731, 731, 731, 731, 731,
+ 731, 731, 731, 731, 160, 160, 160, 160,
+
+ 732, 733, 734, 735, 736, 737, 738, 739,
+ 16, 17, 16, 17, 16, 17, 16, 17,
+ 16, 17, 736, 736, 16, 17, 16, 17,
+ 16, 17, 16, 17, 740, 16, 17, 741,
+
+ 736, 739, 739, 739, 739, 739, 739, 739,
+ 739, 739, 742, 743, 140, 744, 745, 745,
+ 746, 747, 747, 747, 747, 747, 736, 736,
+ 748, 748, 748, 749, 750, 751, 731, 736,
+
+ 160, 752, 738, 752, 738, 752, 738, 752,
+ 738, 752, 738, 738, 738, 738, 738, 738,
+ 738, 738, 738, 738, 738, 738, 738, 738,
+ 738, 738, 738, 738, 738, 738, 738, 738,
+
+ 738, 738, 738, 752, 738, 738, 738, 738,
+ 738, 738, 738, 738, 738, 738, 738, 738,
+ 738, 738, 738, 738, 738, 738, 738, 738,
+ 738, 738, 738, 738, 738, 738, 738, 738,
+
+ 738, 738, 738, 752, 738, 752, 738, 752,
+ 738, 738, 738, 738, 738, 738, 752, 738,
+ 738, 738, 738, 738, 738, 753, 753, 160,
+ 160, 754, 754, 755, 755, 756, 756, 757,
+
+ 758, 759, 760, 759, 760, 759, 760, 759,
+ 760, 759, 760, 760, 760, 760, 760, 760,
+ 760, 760, 760, 760, 760, 760, 760, 760,
+ 760, 760, 760, 760, 760, 760, 760, 760,
+
+ 760, 760, 760, 759, 760, 760, 760, 760,
+ 760, 760, 760, 760, 760, 760, 760, 760,
+ 760, 760, 760, 760, 760, 760, 760, 760,
+ 760, 760, 760, 760, 760, 760, 760, 760,
+
+ 760, 760, 760, 759, 760, 759, 760, 759,
+ 760, 760, 760, 760, 760, 760, 759, 760,
+ 760, 760, 760, 760, 760, 759, 759, 760,
+ 760, 760, 760, 761, 762, 762, 762, 763,
+
+ 160, 160, 160, 160, 160, 764, 764, 764,
+ 764, 764, 764, 764, 764, 764, 764, 764,
+ 764, 764, 764, 764, 764, 764, 764, 764,
+ 764, 764, 764, 764, 764, 764, 764, 764,
+
+ 764, 764, 764, 764, 764, 764, 764, 764,
+ 764, 764, 764, 764, 764, 160, 160, 160,
+ 160, 764, 764, 764, 764, 764, 764, 764,
+ 764, 764, 764, 764, 764, 764, 764, 764,
+
+ 764, 764, 764, 764, 764, 764, 764, 764,
+ 764, 764, 764, 764, 764, 764, 764, 764,
+ 764, 764, 764, 764, 764, 764, 764, 764,
+ 764, 764, 764, 764, 764, 764, 764, 764,
+
+ 764, 764, 764, 764, 764, 764, 764, 764,
+ 764, 764, 764, 764, 764, 764, 764, 160,
+ 765, 765, 766, 766, 766, 766, 765, 765,
+ 765, 765, 765, 765, 765, 765, 765, 765,
+
+ 767, 767, 767, 767, 767, 767, 767, 767,
+ 767, 767, 767, 767, 767, 767, 767, 767,
+ 767, 767, 767, 767, 767, 767, 767, 767,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+
+ 768, 768, 768, 768, 768, 768, 768, 768,
+ 768, 768, 768, 768, 768, 768, 768, 768,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 769, 769, 769, 769, 769, 769, 769, 769,
+ 769, 769, 769, 769, 769, 769, 769, 769,
+
+ 765, 765, 765, 765, 765, 765, 765, 765,
+ 765, 765, 765, 765, 765, 765, 765, 765,
+ 765, 765, 765, 765, 765, 765, 765, 765,
+ 765, 765, 765, 765, 765, 770, 770, 160,
+
+ 766, 766, 766, 766, 766, 766, 766, 766,
+ 766, 766, 765, 765, 765, 765, 765, 765,
+ 765, 765, 765, 765, 765, 765, 765, 765,
+ 765, 765, 765, 765, 765, 765, 765, 765,
+
+ 765, 765, 765, 765, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 770, 771, 771, 771, 771, 771, 771, 771,
+ 771, 771, 771, 771, 771, 771, 771, 771,
+
+ 765, 765, 765, 765, 765, 765, 765, 765,
+ 765, 765, 765, 765, 765, 765, 765, 765,
+ 765, 765, 765, 765, 765, 765, 765, 765,
+ 765, 765, 765, 765, 770, 770, 768, 765,
+
+ 765, 765, 765, 765, 765, 765, 765, 765,
+ 765, 765, 765, 765, 765, 765, 765, 765,
+ 765, 771, 771, 771, 771, 771, 771, 771,
+ 771, 771, 771, 771, 771, 771, 771, 771,
+
+ 765, 765, 765, 765, 765, 765, 765, 765,
+ 765, 765, 765, 765, 770, 770, 770, 770,
+ 765, 765, 765, 765, 765, 765, 765, 765,
+ 765, 765, 765, 765, 765, 765, 765, 765,
+
+ 765, 765, 765, 765, 765, 765, 765, 765,
+ 765, 765, 765, 765, 765, 765, 765, 765,
+ 765, 765, 765, 765, 765, 765, 765, 765,
+ 765, 765, 765, 765, 765, 765, 765, 160,
+
+ 765, 765, 765, 765, 765, 765, 765, 765,
+ 765, 765, 765, 765, 765, 765, 765, 765,
+ 765, 765, 765, 765, 765, 765, 765, 765,
+ 765, 765, 765, 765, 765, 765, 765, 765,
+
+ 765, 765, 765, 765, 765, 765, 765, 765,
+ 765, 765, 765, 765, 765, 765, 765, 765,
+ 765, 765, 765, 765, 765, 765, 765, 770,
+ 770, 770, 770, 765, 765, 765, 765, 765,
+
+ 765, 765, 765, 765, 765, 765, 765, 765,
+ 765, 765, 765, 765, 765, 765, 765, 765,
+ 765, 765, 765, 765, 765, 765, 765, 765,
+ 765, 765, 765, 765, 765, 765, 770, 770,
+
+ 765, 765, 765, 765, 765, 765, 765, 765,
+ 765, 765, 765, 765, 765, 765, 765, 765,
+ 765, 765, 765, 765, 765, 765, 765, 765,
+ 765, 765, 765, 765, 765, 765, 765, 770,
+
+ 772, 772, 772, 772, 772, 772, 772, 772,
+ 772, 772, 772, 772, 772, 772, 772, 772,
+ 772, 772, 772, 772, 772, 772, 772, 772,
+ 772, 772, 772, 772, 772, 772, 772, 772,
+
+ 772, 772, 772, 772, 772, 772, 772, 772,
+ 772, 772, 772, 772, 772, 772, 772, 772,
+ 772, 772, 772, 772, 772, 772, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+
+ 738, 738, 738, 738, 738, 738, 738, 738,
+ 738, 738, 738, 738, 738, 738, 738, 738,
+ 738, 738, 738, 738, 738, 738, 738, 738,
+ 738, 738, 738, 738, 738, 738, 738, 738,
+
+ 738, 738, 738, 738, 738, 738, 773, 773,
+ 773, 773, 773, 773, 773, 773, 773, 773,
+ 773, 773, 773, 773, 773, 773, 773, 773,
+ 773, 773, 773, 773, 160, 160, 160, 160,
+
+ 767, 767, 767, 767, 767, 767, 767, 767,
+ 767, 767, 767, 767, 767, 767, 767, 767,
+ 767, 767, 767, 767, 767, 774, 767, 767,
+ 767, 767, 767, 767, 767, 767, 767, 767,
+
+ 767, 767, 767, 767, 767, 767, 767, 767,
+ 767, 767, 767, 767, 767, 767, 767, 767,
+ 767, 767, 767, 767, 767, 767, 767, 767,
+ 767, 767, 767, 767, 767, 767, 767, 767,
+
+ 767, 767, 767, 767, 767, 767, 767, 767,
+ 767, 767, 767, 767, 767, 160, 160, 160,
+ 731, 731, 731, 731, 731, 731, 731, 731,
+ 731, 731, 731, 731, 731, 731, 731, 731,
+
+ 731, 731, 775, 775, 731, 731, 731, 731,
+ 731, 731, 731, 731, 731, 731, 731, 731,
+ 731, 731, 731, 731, 775, 731, 731, 731,
+ 731, 731, 731, 731, 731, 731, 731, 731,
+
+ 731, 775, 731, 731, 731, 775, 731, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+
+ 776, 776, 776, 776, 776, 776, 776, 776,
+ 776, 776, 776, 776, 776, 776, 776, 776,
+ 776, 776, 776, 776, 776, 776, 776, 777,
+ 777, 777, 777, 160, 160, 160, 160, 160,
+
+ 778, 778, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+
+ 322, 322, 779, 322, 322, 322, 780, 322,
+ 322, 322, 322, 781, 322, 322, 322, 322,
+ 322, 322, 322, 322, 322, 322, 322, 322,
+ 322, 322, 322, 322, 322, 322, 322, 322,
+
+ 322, 322, 322, 463, 463, 781, 781, 463,
+ 417, 417, 417, 417, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+
+ 321, 321, 321, 321, 321, 321, 321, 321,
+ 321, 321, 321, 321, 321, 321, 321, 321,
+ 321, 321, 321, 321, 321, 321, 321, 321,
+ 321, 321, 321, 321, 321, 321, 321, 321,
+
+ 321, 321, 321, 321, 321, 321, 321, 321,
+ 321, 321, 321, 321, 321, 321, 321, 321,
+ 321, 321, 321, 321, 782, 782, 303, 303,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+
+ 783, 784, 784, 784, 784, 784, 784, 784,
+ 784, 784, 784, 784, 784, 784, 784, 784,
+ 784, 784, 784, 784, 784, 784, 784, 784,
+ 784, 784, 784, 784, 783, 784, 784, 784,
+
+ 784, 784, 784, 784, 784, 784, 784, 784,
+ 784, 784, 784, 784, 784, 784, 784, 784,
+ 784, 784, 784, 784, 784, 784, 784, 784,
+ 783, 784, 784, 784, 784, 784, 784, 784,
+
+ 784, 784, 784, 784, 784, 784, 784, 784,
+ 784, 784, 784, 784, 784, 784, 784, 784,
+ 784, 784, 784, 784, 783, 784, 784, 784,
+ 784, 784, 784, 784, 784, 784, 784, 784,
+
+ 784, 784, 784, 784, 784, 784, 784, 784,
+ 784, 784, 784, 784, 784, 784, 784, 784,
+ 783, 784, 784, 784, 784, 784, 784, 784,
+ 784, 784, 784, 784, 784, 784, 784, 784,
+
+ 784, 784, 784, 784, 784, 784, 784, 784,
+ 784, 784, 784, 784, 783, 784, 784, 784,
+ 784, 784, 784, 784, 784, 784, 784, 784,
+ 784, 784, 784, 784, 784, 784, 784, 784,
+
+ 784, 784, 784, 784, 784, 784, 784, 784,
+ 783, 784, 784, 784, 784, 784, 784, 784,
+ 784, 784, 784, 784, 784, 784, 784, 784,
+ 784, 784, 784, 784, 784, 784, 784, 784,
+
+ 784, 784, 784, 784, 783, 784, 784, 784,
+ 784, 784, 784, 784, 784, 784, 784, 784,
+ 784, 784, 784, 784, 784, 784, 784, 784,
+ 784, 784, 784, 784, 784, 784, 784, 784,
+
+ 784, 784, 784, 784, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+
+ 785, 785, 785, 785, 785, 785, 785, 785,
+ 785, 785, 785, 785, 785, 785, 785, 785,
+ 785, 785, 785, 785, 785, 785, 785, 785,
+ 785, 785, 785, 785, 785, 785, 785, 785,
+
+ 786, 786, 786, 786, 786, 786, 786, 786,
+ 786, 786, 786, 786, 786, 786, 786, 786,
+ 786, 786, 786, 786, 786, 786, 786, 786,
+ 786, 786, 786, 786, 786, 786, 786, 786,
+
+ 738, 738, 738, 738, 738, 738, 738, 738,
+ 738, 738, 738, 738, 738, 738, 160, 160,
+ 787, 787, 787, 787, 787, 787, 787, 787,
+ 787, 787, 787, 787, 787, 787, 787, 787,
+
+ 787, 787, 787, 787, 787, 787, 787, 787,
+ 787, 787, 787, 787, 787, 787, 787, 787,
+ 787, 787, 787, 787, 787, 787, 787, 787,
+ 787, 787, 787, 787, 787, 787, 787, 787,
+
+ 787, 787, 787, 787, 787, 787, 787, 787,
+ 787, 787, 787, 160, 160, 160, 160, 160,
+ 773, 773, 773, 773, 773, 773, 773, 773,
+ 773, 773, 773, 773, 773, 773, 773, 773,
+
+ 773, 773, 773, 773, 773, 773, 773, 773,
+ 773, 773, 773, 773, 773, 773, 773, 773,
+ 773, 773, 773, 773, 773, 773, 773, 773,
+ 773, 773, 773, 773, 773, 773, 773, 773,
+
+ 773, 773, 773, 773, 773, 773, 773, 773,
+ 773, 773, 773, 773, 773, 773, 773, 773,
+ 773, 773, 773, 773, 773, 773, 773, 773,
+ 773, 773, 160, 160, 160, 160, 160, 160,
+
+ 788, 789, 790, 791, 792, 793, 794, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 795, 796, 797, 798, 799,
+ 160, 160, 160, 160, 160, 800, 801, 230,
+
+ 230, 230, 230, 230, 230, 230, 230, 230,
+ 230, 634, 230, 230, 230, 230, 230, 230,
+ 230, 230, 230, 230, 230, 230, 230, 204,
+ 230, 230, 230, 230, 230, 204, 230, 204,
+
+ 230, 230, 204, 230, 230, 204, 230, 230,
+ 230, 230, 230, 230, 230, 230, 230, 230,
+ 242, 242, 242, 242, 242, 242, 242, 242,
+ 242, 242, 242, 242, 242, 242, 242, 242,
+
+ 242, 242, 242, 242, 242, 242, 242, 242,
+ 242, 242, 242, 242, 242, 242, 242, 242,
+ 242, 242, 242, 242, 242, 242, 242, 242,
+ 242, 242, 242, 242, 242, 242, 242, 242,
+
+ 242, 242, 242, 242, 242, 242, 242, 242,
+ 242, 242, 242, 242, 242, 242, 242, 242,
+ 242, 242, 234, 234, 234, 234, 234, 234,
+ 234, 234, 234, 234, 234, 234, 234, 234,
+
+ 234, 234, 234, 234, 234, 234, 234, 234,
+ 234, 234, 234, 234, 234, 234, 234, 234,
+ 234, 234, 234, 242, 242, 242, 242, 242,
+ 242, 242, 242, 242, 242, 242, 242, 242,
+
+ 242, 242, 242, 242, 242, 242, 242, 242,
+ 242, 242, 242, 242, 242, 242, 242, 242,
+ 242, 242, 242, 242, 242, 242, 242, 242,
+ 242, 242, 242, 242, 242, 242, 599, 741,
+
+ 234, 234, 234, 234, 234, 234, 234, 234,
+ 234, 234, 234, 234, 234, 234, 234, 234,
+ 242, 242, 242, 242, 242, 242, 242, 242,
+ 242, 242, 242, 242, 242, 242, 242, 242,
+
+ 242, 242, 242, 242, 242, 242, 242, 242,
+ 242, 242, 242, 242, 242, 242, 242, 242,
+ 234, 234, 242, 242, 242, 242, 242, 242,
+ 242, 242, 242, 242, 242, 242, 242, 242,
+
+ 242, 242, 242, 242, 242, 242, 242, 242,
+ 234, 234, 234, 234, 234, 234, 234, 234,
+ 802, 802, 802, 802, 802, 802, 802, 802,
+ 802, 802, 802, 802, 802, 802, 802, 802,
+
+ 802, 802, 802, 802, 802, 802, 802, 802,
+ 802, 802, 802, 802, 802, 802, 802, 802,
+ 242, 242, 242, 242, 242, 242, 242, 242,
+ 242, 242, 242, 242, 803, 238, 234, 234,
+
+ 422, 422, 422, 422, 422, 422, 422, 422,
+ 422, 422, 422, 422, 422, 422, 422, 422,
+ 804, 805, 805, 804, 804, 806, 806, 807,
+ 808, 809, 160, 160, 160, 160, 160, 160,
+
+ 139, 139, 139, 139, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 735, 746, 746, 810, 810, 599, 741, 599,
+ 741, 599, 741, 599, 741, 599, 741, 599,
+
+ 741, 599, 741, 599, 741, 751, 751, 811,
+ 812, 735, 735, 735, 735, 810, 810, 810,
+ 813, 735, 814, 160, 761, 815, 9, 9,
+ 746, 16, 17, 16, 17, 16, 17, 816,
+
+ 735, 735, 817, 818, 819, 820, 821, 160,
+ 735, 12, 13, 735, 160, 160, 160, 160,
+ 242, 242, 242, 285, 242, 234, 242, 242,
+ 242, 242, 242, 242, 242, 242, 242, 242,
+
+ 242, 242, 242, 242, 242, 242, 242, 242,
+ 242, 242, 242, 242, 242, 242, 242, 242,
+ 242, 242, 242, 242, 242, 242, 242, 242,
+ 242, 242, 242, 242, 242, 234, 234, 822,
+
+ 160, 9, 735, 816, 12, 13, 735, 735,
+ 16, 17, 735, 817, 813, 818, 814, 823,
+ 824, 825, 826, 827, 828, 829, 830, 831,
+ 832, 833, 815, 761, 834, 821, 835, 9,
+
+ 735, 836, 836, 836, 836, 836, 836, 836,
+ 836, 836, 836, 836, 836, 836, 836, 836,
+ 836, 836, 836, 836, 836, 836, 836, 836,
+ 836, 836, 836, 39, 735, 41, 837, 810,
+
+ 837, 838, 838, 838, 838, 838, 838, 838,
+ 838, 838, 838, 838, 838, 838, 838, 838,
+ 838, 838, 838, 838, 838, 838, 838, 838,
+ 838, 838, 838, 39, 821, 41, 821, 699,
+
+ 700, 734, 16, 17, 733, 761, 839, 759,
+ 759, 759, 759, 759, 759, 759, 759, 759,
+ 762, 839, 839, 839, 839, 839, 839, 839,
+ 839, 839, 839, 839, 839, 839, 839, 839,
+
+ 839, 839, 839, 839, 839, 839, 839, 839,
+ 839, 839, 839, 839, 839, 839, 839, 839,
+ 839, 839, 839, 839, 839, 839, 839, 839,
+ 839, 839, 839, 839, 839, 839, 762, 762,
+
+ 90, 90, 90, 90, 90, 90, 90, 90,
+ 90, 90, 90, 90, 90, 90, 90, 90,
+ 90, 90, 90, 90, 90, 90, 90, 90,
+ 90, 90, 90, 90, 90, 90, 90, 160,
+
+ 160, 160, 90, 90, 90, 90, 90, 90,
+ 160, 160, 90, 90, 90, 90, 90, 90,
+ 160, 160, 90, 90, 90, 90, 90, 90,
+ 160, 160, 90, 90, 90, 160, 160, 160,
+
+ 48, 12, 821, 837, 736, 12, 12, 160,
+ 49, 36, 36, 36, 36, 49, 49, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 840, 840, 840, 841, 49, 842, 842,
+
+ 307, 307, 307, 307, 307, 307, 307, 307,
+ 307, 307, 307, 307, 160, 307, 307, 307,
+ 307, 307, 307, 307, 307, 307, 307, 307,
+ 307, 307, 307, 307, 307, 307, 307, 307,
+
+ 307, 307, 307, 307, 307, 307, 307, 160,
+ 307, 307, 307, 307, 307, 307, 307, 307,
+ 307, 307, 307, 307, 307, 307, 307, 307,
+ 307, 307, 307, 160, 307, 307, 160, 307,
+
+ 307, 307, 307, 307, 307, 307, 307, 307,
+ 307, 307, 307, 307, 307, 307, 160, 160,
+ 307, 307, 307, 307, 307, 307, 307, 307,
+ 307, 307, 307, 307, 307, 307, 160, 160,
+
+ 307, 307, 307, 307, 307, 307, 307, 307,
+ 307, 307, 307, 307, 307, 307, 307, 307,
+ 307, 307, 307, 307, 307, 307, 307, 307,
+ 307, 307, 307, 307, 307, 307, 307, 307,
+
+ 307, 307, 307, 307, 307, 307, 307, 307,
+ 307, 307, 307, 307, 307, 307, 307, 307,
+ 307, 307, 307, 307, 307, 307, 307, 307,
+ 307, 307, 307, 160, 160, 160, 160, 160,
+
+ 843, 844, 845, 160, 160, 160, 160, 846,
+ 846, 846, 846, 846, 846, 846, 846, 846,
+ 846, 846, 846, 846, 846, 846, 846, 846,
+ 846, 846, 846, 846, 846, 846, 846, 846,
+
+ 846, 846, 846, 846, 846, 846, 846, 846,
+ 846, 846, 846, 846, 846, 846, 846, 846,
+ 846, 846, 846, 846, 160, 160, 160, 847,
+ 847, 847, 847, 847, 847, 847, 847, 847,
+
+ 848, 848, 848, 848, 848, 848, 848, 848,
+ 848, 848, 848, 848, 848, 848, 848, 848,
+ 848, 848, 848, 848, 848, 848, 848, 848,
+ 848, 848, 848, 848, 848, 848, 848, 848,
+
+ 848, 848, 848, 848, 848, 848, 848, 848,
+ 848, 848, 848, 848, 848, 848, 848, 848,
+ 848, 848, 848, 848, 848, 725, 725, 725,
+ 725, 417, 417, 417, 417, 417, 417, 417,
+
+ 417, 417, 417, 417, 417, 417, 417, 417,
+ 417, 417, 725, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+
+ 849, 849, 849, 849, 849, 849, 849, 849,
+ 849, 849, 849, 849, 849, 849, 849, 849,
+ 849, 849, 849, 849, 849, 849, 849, 849,
+ 849, 849, 849, 849, 849, 849, 849, 160,
+
+ 850, 850, 850, 850, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 849, 849, 849, 849, 849, 849, 849, 849,
+ 849, 849, 849, 849, 849, 849, 849, 849,
+
+ 849, 851, 849, 849, 849, 849, 849, 849,
+ 849, 849, 851, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+
+ 307, 307, 307, 307, 307, 307, 307, 307,
+ 307, 307, 307, 307, 307, 307, 307, 307,
+ 307, 307, 307, 307, 307, 307, 307, 307,
+ 307, 307, 307, 307, 307, 307, 160, 843,
+
+ 322, 322, 322, 322, 160, 160, 160, 160,
+ 322, 322, 322, 322, 322, 322, 322, 322,
+ 464, 852, 852, 852, 852, 852, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+
+ 853, 853, 853, 853, 853, 853, 853, 853,
+ 853, 853, 853, 853, 853, 853, 853, 853,
+ 853, 853, 853, 853, 853, 853, 853, 853,
+ 853, 853, 853, 853, 853, 853, 853, 853,
+
+ 853, 853, 853, 853, 853, 853, 854, 854,
+ 855, 855, 855, 855, 855, 855, 855, 855,
+ 855, 855, 855, 855, 855, 855, 855, 855,
+ 855, 855, 855, 855, 855, 855, 855, 855,
+
+ 855, 855, 855, 855, 855, 855, 855, 855,
+ 855, 855, 855, 855, 855, 855, 856, 856,
+ 307, 307, 307, 307, 307, 307, 307, 307,
+ 307, 307, 307, 307, 307, 307, 307, 307,
+
+ 307, 307, 307, 307, 307, 307, 307, 307,
+ 307, 307, 307, 307, 307, 307, 307, 307,
+ 307, 307, 307, 307, 307, 307, 307, 307,
+ 307, 307, 307, 307, 307, 307, 160, 160,
+
+ 440, 441, 442, 443, 444, 445, 446, 447,
+ 448, 449, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+
+ 857, 857, 857, 857, 857, 857, 204, 204,
+ 857, 204, 857, 857, 857, 857, 857, 857,
+ 857, 857, 857, 857, 857, 857, 857, 857,
+ 857, 857, 857, 857, 857, 857, 857, 857,
+
+ 857, 857, 857, 857, 857, 857, 857, 857,
+ 857, 857, 857, 857, 857, 857, 857, 857,
+ 857, 857, 857, 857, 857, 857, 204, 857,
+ 857, 204, 204, 204, 857, 204, 204, 857,
+
+ 858, 858, 858, 858, 858, 858, 858, 858,
+ 858, 858, 858, 858, 858, 858, 858, 858,
+ 858, 858, 858, 858, 858, 858, 859, 859,
+ 859, 859, 204, 204, 204, 204, 204, 860,
+
+ 861, 781, 781, 781, 204, 781, 781, 204,
+ 204, 204, 204, 204, 781, 152, 781, 153,
+ 861, 861, 861, 861, 204, 861, 861, 861,
+ 204, 861, 861, 861, 861, 861, 861, 861,
+
+ 861, 861, 861, 861, 861, 861, 861, 861,
+ 861, 861, 861, 861, 861, 861, 861, 861,
+ 861, 861, 861, 861, 204, 204, 204, 204,
+ 153, 642, 152, 204, 204, 204, 204, 780,
+
+ 862, 863, 864, 865, 866, 866, 866, 866,
+ 204, 204, 204, 204, 204, 204, 204, 204,
+ 867, 867, 867, 867, 867, 867, 867, 867,
+ 868, 204, 204, 204, 204, 204, 204, 204,
+
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+
+ 321, 321, 321, 321, 321, 321, 321, 321,
+ 321, 321, 321, 321, 321, 321, 321, 321,
+ 321, 321, 321, 321, 321, 321, 321, 321,
+ 321, 321, 321, 321, 321, 321, 321, 321,
+ 321, 321, 321, 321, 321, 321, 321, 321,
+ 321, 321, 321, 321, 321, 321, 321, 321,
+ 321, 321, 321, 321, 321, 321, 321, 321,
+ 321, 321, 321, 321, 321, 321, 321, 321,
+ 321, 321, 321, 321, 321, 321, 321, 321,
+ 321, 321, 321, 321, 321, 321, 321, 321,
+ 321, 321, 321, 321, 321, 321, 321, 321,
+ 321, 321, 321, 321, 321, 321, 321, 321,
+ 321, 321, 321, 321, 321, 321, 321, 321,
+ 321, 321, 321, 321, 321, 321, 321, 321,
+ 321, 321, 321, 321, 321, 321, 321, 321,
+ 321, 321, 321, 321, 321, 321, 321, 321,
+ 321, 321, 321, 321, 321, 321, 321, 321,
+ 321, 321, 321, 321, 321, 321, 321, 321,
+ 321, 321, 321, 321, 321, 321, 321, 321,
+ 321, 321, 321, 321, 321, 321, 321, 321,
+ 321, 321, 321, 321, 321, 321, 321, 321,
+ 321, 321, 321, 321, 321, 321, 321, 321,
+ 321, 321, 321, 321, 321, 321, 321, 321,
+ 321, 321, 321, 321, 321, 321, 321, 321,
+ 321, 321, 321, 321, 321, 321, 321, 321,
+ 321, 321, 321, 321, 321, 321, 321, 321,
+ 321, 321, 321, 321, 321, 321, 321, 321,
+ 321, 321, 321, 321, 321, 321, 321, 321,
+ 321, 321, 321, 321, 321, 321, 321, 321,
+ 321, 321, 321, 321, 321, 321, 321, 321,
+ 321, 321, 321, 321, 321, 321, 321, 321,
+ 321, 321, 321, 321, 321, 321, 321, 321,
+
+ 321, 321, 321, 321, 321, 321, 321, 321,
+ 321, 321, 321, 321, 321, 321, 321, 321,
+ 321, 321, 321, 321, 321, 321, 321, 321,
+ 321, 321, 321, 321, 321, 321, 321, 321,
+ 321, 321, 321, 321, 321, 321, 321, 321,
+ 321, 321, 321, 321, 321, 321, 321, 321,
+ 321, 321, 321, 321, 321, 321, 321, 321,
+ 321, 321, 321, 321, 321, 321, 321, 321,
+ 321, 321, 321, 321, 321, 321, 321, 321,
+ 321, 321, 321, 321, 321, 321, 321, 321,
+ 321, 321, 321, 321, 321, 321, 321, 321,
+ 321, 321, 321, 321, 321, 321, 321, 321,
+ 321, 321, 321, 321, 321, 321, 321, 321,
+ 321, 321, 321, 321, 321, 321, 321, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+
+ 869, 869, 869, 869, 869, 869, 869, 869,
+ 869, 869, 869, 869, 869, 869, 869, 869,
+ 869, 869, 869, 869, 869, 869, 869, 869,
+ 869, 869, 869, 869, 869, 869, 869, 869,
+ 869, 869, 869, 869, 869, 869, 869, 869,
+ 869, 869, 869, 869, 869, 869, 869, 869,
+ 869, 869, 869, 869, 869, 869, 869, 869,
+ 869, 869, 869, 869, 869, 869, 869, 869,
+ 869, 869, 869, 869, 869, 869, 869, 869,
+ 869, 869, 869, 869, 869, 869, 869, 869,
+ 869, 869, 869, 869, 869, 869, 869, 869,
+ 869, 869, 869, 869, 869, 869, 869, 869,
+ 869, 869, 869, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 480, 480, 480, 480, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+
+ 870, 870, 870, 870, 870, 870, 870, 870,
+ 870, 870, 870, 870, 870, 870, 870, 870,
+ 870, 870, 870, 870, 870, 870, 870, 870,
+ 870, 870, 870, 870, 870, 870, 870, 870,
+ 870, 870, 870, 870, 870, 870, 870, 870,
+ 870, 870, 870, 870, 870, 870, 870, 870,
+ 870, 870, 870, 870, 870, 870, 870, 870,
+ 870, 870, 870, 870, 870, 870, 870, 870,
+ 870, 870, 870, 870, 870, 870, 870, 870,
+ 870, 870, 870, 870, 870, 870, 870, 870,
+ 870, 870, 870, 870, 870, 870, 870, 870,
+ 870, 870, 870, 870, 870, 870, 870, 870,
+ 870, 870, 870, 870, 870, 870, 870, 870,
+ 870, 870, 870, 870, 870, 870, 870, 870,
+ 870, 870, 870, 870, 870, 870, 870, 870,
+ 870, 870, 870, 870, 870, 870, 870, 870,
+ 870, 870, 870, 870, 870, 870, 870, 870,
+ 870, 870, 870, 870, 870, 870, 870, 870,
+ 870, 870, 870, 870, 870, 870, 870, 870,
+ 870, 870, 870, 870, 870, 870, 870, 870,
+ 870, 870, 870, 870, 870, 870, 870, 870,
+ 870, 870, 870, 870, 870, 870, 870, 870,
+ 870, 870, 870, 870, 870, 870, 870, 870,
+ 870, 870, 870, 870, 870, 870, 870, 870,
+ 870, 870, 870, 870, 870, 870, 870, 870,
+ 870, 870, 870, 870, 870, 870, 870, 870,
+ 870, 870, 870, 870, 870, 870, 870, 870,
+ 870, 870, 870, 870, 870, 870, 870, 870,
+ 870, 870, 870, 870, 870, 870, 870, 870,
+ 870, 870, 870, 870, 870, 870, 870, 870,
+ 870, 870, 870, 870, 870, 870, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+
+ 870, 870, 870, 870, 870, 870, 870, 870,
+ 870, 870, 870, 870, 870, 870, 870, 870,
+ 870, 870, 870, 870, 870, 870, 870, 870,
+ 870, 870, 870, 870, 870, 870, 870, 870,
+ 870, 870, 870, 870, 870, 870, 870, 160,
+ 160, 160, 870, 870, 870, 870, 870, 870,
+ 870, 870, 870, 870, 870, 870, 870, 870,
+ 870, 870, 870, 870, 870, 870, 870, 870,
+ 870, 870, 870, 870, 870, 870, 870, 870,
+ 870, 870, 870, 870, 870, 870, 870, 870,
+ 870, 870, 870, 870, 870, 870, 870, 870,
+ 870, 870, 870, 870, 870, 870, 870, 870,
+ 870, 870, 870, 870, 870, 871, 872, 873,
+ 873, 873, 870, 870, 870, 874, 871, 871,
+ 871, 871, 871, 875, 875, 875, 875, 875,
+ 875, 875, 875, 876, 876, 876, 876, 876,
+ 876, 876, 876, 870, 870, 877, 877, 877,
+ 877, 877, 876, 876, 870, 870, 870, 870,
+ 870, 870, 870, 870, 870, 870, 870, 870,
+ 870, 870, 870, 870, 870, 870, 870, 870,
+ 870, 870, 870, 870, 870, 870, 870, 870,
+ 870, 870, 877, 877, 877, 877, 870, 870,
+ 870, 870, 870, 870, 870, 870, 870, 870,
+ 870, 870, 870, 870, 870, 870, 870, 870,
+ 870, 870, 870, 870, 870, 870, 870, 870,
+ 870, 870, 870, 870, 870, 870, 870, 870,
+ 870, 870, 870, 870, 870, 870, 870, 870,
+ 870, 870, 870, 870, 870, 870, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+
+ 417, 417, 417, 417, 417, 417, 417, 417,
+ 417, 417, 417, 417, 417, 417, 417, 417,
+ 417, 417, 417, 417, 417, 417, 417, 417,
+ 417, 417, 417, 417, 417, 417, 417, 417,
+ 417, 417, 417, 417, 417, 417, 417, 417,
+ 417, 417, 417, 417, 417, 417, 417, 417,
+ 417, 417, 417, 417, 417, 417, 417, 417,
+ 417, 417, 417, 417, 417, 417, 417, 417,
+ 417, 417, 153, 153, 153, 417, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+
+ 238, 238, 238, 238, 238, 238, 238, 238,
+ 238, 238, 238, 238, 238, 238, 238, 238,
+ 238, 238, 238, 238, 238, 238, 238, 238,
+ 238, 238, 238, 238, 238, 238, 238, 238,
+ 238, 238, 238, 238, 238, 238, 238, 238,
+ 238, 238, 238, 238, 238, 238, 238, 238,
+ 238, 238, 238, 238, 238, 238, 238, 238,
+ 238, 238, 238, 238, 238, 238, 238, 238,
+ 238, 238, 238, 238, 238, 238, 238, 238,
+ 238, 238, 238, 238, 238, 238, 238, 238,
+ 238, 238, 238, 238, 238, 238, 238, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 878, 878, 878, 878, 878, 878, 878, 878,
+ 878, 878, 878, 878, 878, 878, 878, 878,
+ 878, 878, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+
+ 879, 879, 879, 879, 879, 879, 879, 879,
+ 879, 879, 879, 879, 879, 879, 879, 879,
+ 879, 879, 879, 879, 879, 879, 879, 879,
+ 879, 879, 880, 880, 880, 880, 880, 880,
+ 880, 880, 880, 880, 880, 880, 880, 880,
+ 880, 880, 880, 880, 880, 880, 880, 880,
+ 880, 880, 880, 880, 879, 879, 879, 879,
+ 879, 879, 879, 879, 879, 879, 879, 879,
+ 879, 879, 879, 879, 879, 879, 879, 879,
+ 879, 879, 879, 879, 879, 879, 880, 880,
+ 880, 880, 880, 880, 880, 160, 880, 880,
+ 880, 880, 880, 880, 880, 880, 880, 880,
+ 880, 880, 880, 880, 880, 880, 880, 880,
+ 879, 879, 879, 879, 879, 879, 879, 879,
+ 879, 879, 879, 879, 879, 879, 879, 879,
+ 879, 879, 879, 879, 879, 879, 879, 879,
+ 879, 879, 880, 880, 880, 880, 880, 880,
+ 880, 880, 880, 880, 880, 880, 880, 880,
+ 880, 880, 880, 880, 880, 880, 880, 880,
+ 880, 880, 880, 880, 879, 160, 879, 879,
+ 160, 160, 879, 160, 160, 879, 879, 160,
+ 160, 879, 879, 879, 879, 160, 879, 879,
+ 879, 879, 879, 879, 879, 879, 880, 880,
+ 880, 880, 160, 880, 160, 880, 880, 880,
+ 880, 102, 880, 880, 160, 880, 880, 880,
+ 880, 880, 880, 880, 880, 880, 880, 880,
+ 879, 879, 879, 879, 879, 879, 879, 879,
+ 879, 879, 879, 879, 879, 879, 879, 879,
+ 879, 879, 879, 879, 879, 879, 879, 879,
+ 879, 879, 880, 880, 880, 880, 880, 880,
+ 880, 880, 880, 880, 880, 880, 880, 880,
+ 880, 880, 880, 880, 880, 880, 880, 880,
+
+ 880, 880, 880, 880, 879, 879, 160, 879,
+ 879, 879, 879, 160, 160, 879, 879, 879,
+ 879, 879, 879, 879, 879, 160, 879, 879,
+ 879, 879, 879, 879, 879, 160, 880, 880,
+ 880, 880, 880, 880, 880, 880, 880, 880,
+ 880, 880, 880, 880, 880, 880, 880, 880,
+ 880, 880, 880, 880, 880, 880, 880, 880,
+ 879, 879, 160, 879, 879, 879, 879, 160,
+ 879, 879, 879, 879, 879, 160, 879, 160,
+ 160, 160, 879, 879, 879, 879, 879, 879,
+ 879, 160, 880, 880, 880, 880, 880, 880,
+ 880, 880, 880, 880, 880, 880, 880, 880,
+ 880, 880, 880, 880, 880, 880, 880, 880,
+ 880, 880, 880, 880, 879, 879, 879, 879,
+ 879, 879, 879, 879, 879, 879, 879, 879,
+ 879, 879, 879, 879, 879, 879, 879, 879,
+ 879, 879, 879, 879, 879, 879, 880, 880,
+ 880, 880, 880, 880, 880, 880, 880, 880,
+ 880, 880, 880, 880, 880, 880, 880, 880,
+ 880, 880, 880, 880, 880, 880, 880, 880,
+ 879, 879, 879, 879, 879, 879, 879, 879,
+ 879, 879, 879, 879, 879, 879, 879, 879,
+ 879, 879, 879, 879, 879, 879, 879, 879,
+ 879, 879, 880, 880, 880, 880, 880, 880,
+ 880, 880, 880, 880, 880, 880, 880, 880,
+ 880, 880, 880, 880, 880, 880, 880, 880,
+ 880, 880, 880, 880, 879, 879, 879, 879,
+ 879, 879, 879, 879, 879, 879, 879, 879,
+ 879, 879, 879, 879, 879, 879, 879, 879,
+ 879, 879, 879, 879, 879, 879, 880, 880,
+ 880, 880, 880, 880, 880, 880, 880, 880,
+ 880, 880, 880, 880, 880, 880, 880, 880,
+
+ 880, 880, 880, 880, 880, 880, 880, 880,
+ 879, 879, 879, 879, 879, 879, 879, 879,
+ 879, 879, 879, 879, 879, 879, 879, 879,
+ 879, 879, 879, 879, 879, 879, 879, 879,
+ 879, 879, 880, 880, 880, 880, 880, 880,
+ 880, 880, 880, 880, 880, 880, 880, 880,
+ 880, 880, 880, 880, 880, 880, 880, 880,
+ 880, 880, 880, 880, 879, 879, 879, 879,
+ 879, 879, 879, 879, 879, 879, 879, 879,
+ 879, 879, 879, 879, 879, 879, 879, 879,
+ 879, 879, 879, 879, 879, 879, 880, 880,
+ 880, 880, 880, 880, 880, 880, 880, 880,
+ 880, 880, 880, 880, 880, 880, 880, 880,
+ 880, 880, 880, 880, 880, 880, 880, 880,
+ 879, 879, 879, 879, 879, 879, 879, 879,
+ 879, 879, 879, 879, 879, 879, 879, 879,
+ 879, 879, 879, 879, 879, 879, 879, 879,
+ 879, 879, 880, 880, 880, 880, 880, 880,
+ 880, 880, 880, 880, 880, 880, 880, 880,
+ 880, 880, 880, 880, 880, 880, 880, 880,
+ 880, 880, 880, 880, 103, 103, 160, 160,
+ 879, 879, 879, 879, 879, 879, 879, 879,
+ 879, 879, 879, 879, 879, 879, 879, 879,
+ 879, 879, 879, 879, 879, 879, 879, 879,
+ 879, 881, 880, 880, 880, 880, 880, 880,
+ 880, 880, 880, 880, 880, 880, 880, 880,
+ 880, 880, 880, 880, 880, 880, 880, 880,
+ 880, 880, 880, 881, 880, 880, 880, 880,
+ 880, 880, 879, 879, 879, 879, 879, 879,
+ 879, 879, 879, 879, 879, 879, 879, 879,
+ 879, 879, 879, 879, 879, 879, 879, 879,
+ 879, 879, 879, 881, 880, 880, 880, 880,
+
+ 880, 880, 880, 880, 880, 880, 880, 880,
+ 880, 880, 880, 880, 880, 880, 880, 880,
+ 880, 880, 880, 880, 880, 881, 880, 880,
+ 880, 880, 880, 880, 879, 879, 879, 879,
+ 879, 879, 879, 879, 879, 879, 879, 879,
+ 879, 879, 879, 879, 879, 879, 879, 879,
+ 879, 879, 879, 879, 879, 881, 880, 880,
+ 880, 880, 880, 880, 880, 880, 880, 880,
+ 880, 880, 880, 880, 880, 880, 880, 880,
+ 880, 880, 880, 880, 880, 880, 880, 881,
+ 880, 880, 880, 880, 880, 880, 879, 879,
+ 879, 879, 879, 879, 879, 879, 879, 879,
+ 879, 879, 879, 879, 879, 879, 879, 879,
+ 879, 879, 879, 879, 879, 879, 879, 881,
+ 880, 880, 880, 880, 880, 880, 880, 880,
+ 880, 880, 880, 880, 880, 880, 880, 880,
+ 880, 880, 880, 880, 880, 880, 880, 880,
+ 880, 881, 880, 880, 880, 880, 880, 880,
+ 879, 879, 879, 879, 879, 879, 879, 879,
+ 879, 879, 879, 879, 879, 879, 879, 879,
+ 879, 879, 879, 879, 879, 879, 879, 879,
+ 879, 881, 880, 880, 880, 880, 880, 880,
+ 880, 880, 880, 880, 880, 880, 880, 880,
+ 880, 880, 880, 880, 880, 880, 880, 880,
+ 880, 880, 880, 881, 880, 880, 880, 880,
+ 880, 880, 882, 724, 160, 160, 883, 884,
+ 885, 886, 887, 888, 889, 890, 891, 892,
+ 883, 884, 885, 886, 887, 888, 889, 890,
+ 891, 892, 883, 884, 885, 886, 887, 888,
+ 889, 890, 891, 892, 883, 884, 885, 886,
+ 887, 888, 889, 890, 891, 892, 883, 884,
+ 885, 886, 887, 888, 889, 890, 891, 892,
+
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 893, 893,
+
+ 894, 894, 894, 894, 894, 894, 894, 894,
+ 894, 894, 894, 894, 894, 894, 894, 894,
+ 894, 894, 894, 894, 894, 894, 894, 894,
+ 894, 894, 894, 894, 894, 894, 894, 894,
+ 894, 894, 894, 894, 894, 894, 894, 894,
+ 894, 894, 894, 894, 894, 894, 894, 894,
+ 894, 894, 894, 894, 894, 894, 894, 894,
+ 894, 894, 894, 894, 894, 894, 894, 894,
+ 894, 894, 894, 894, 894, 894, 894, 894,
+ 894, 894, 894, 894, 894, 894, 894, 894,
+ 894, 894, 894, 894, 894, 894, 894, 894,
+ 894, 894, 894, 894, 894, 894, 894, 894,
+ 894, 894, 894, 894, 894, 894, 894, 894,
+ 894, 894, 894, 894, 894, 894, 894, 894,
+ 894, 894, 894, 894, 894, 894, 894, 894,
+ 894, 894, 894, 894, 894, 894, 894, 894,
+ 894, 894, 894, 894, 894, 894, 894, 894,
+ 894, 894, 894, 894, 894, 894, 894, 894,
+ 894, 894, 894, 894, 894, 894, 894, 894,
+ 894, 894, 894, 894, 894, 894, 894, 894,
+ 894, 894, 894, 894, 894, 894, 894, 894,
+ 894, 894, 894, 894, 894, 894, 894, 894,
+ 894, 894, 894, 894, 894, 894, 894, 894,
+ 894, 894, 894, 894, 894, 894, 894, 894,
+ 894, 894, 894, 894, 894, 894, 894, 894,
+ 894, 894, 894, 894, 894, 894, 894, 894,
+ 894, 894, 894, 894, 894, 894, 894, 894,
+ 894, 894, 894, 894, 894, 894, 894, 894,
+ 894, 894, 894, 894, 894, 894, 894, 894,
+ 894, 894, 894, 894, 894, 894, 894, 894,
+ 894, 894, 894, 894, 894, 894, 894, 894,
+ 894, 894, 894, 894, 894, 894, 894, 894,
+
+ 894, 894, 894, 894, 894, 894, 894, 894,
+ 894, 894, 894, 894, 894, 894, 894, 894,
+ 894, 894, 894, 894, 894, 894, 894, 894,
+ 894, 894, 894, 894, 894, 894, 894, 894,
+ 894, 894, 894, 894, 894, 894, 894, 894,
+ 894, 894, 894, 894, 894, 894, 894, 894,
+ 894, 894, 894, 894, 894, 894, 894, 894,
+ 894, 894, 894, 894, 894, 894, 894, 894,
+ 894, 894, 894, 894, 894, 894, 894, 894,
+ 894, 894, 894, 894, 894, 894, 894, 894,
+ 894, 894, 894, 894, 894, 894, 894, 894,
+ 894, 894, 894, 894, 894, 894, 894, 894,
+ 894, 894, 894, 894, 894, 894, 894, 894,
+ 894, 894, 894, 894, 894, 894, 894, 894,
+ 894, 894, 894, 894, 894, 894, 894, 894,
+ 894, 894, 894, 894, 894, 894, 894, 894,
+ 894, 894, 894, 894, 894, 894, 894, 894,
+ 894, 894, 894, 894, 894, 894, 894, 894,
+ 894, 894, 894, 894, 894, 894, 894, 894,
+ 894, 894, 894, 894, 894, 894, 894, 894,
+ 894, 894, 894, 894, 894, 894, 894, 894,
+ 894, 894, 894, 894, 894, 894, 894, 894,
+ 894, 894, 894, 894, 894, 894, 894, 894,
+ 894, 894, 894, 894, 894, 894, 894, 894,
+ 894, 894, 894, 894, 894, 894, 894, 894,
+ 894, 894, 894, 894, 894, 894, 894, 894,
+ 894, 894, 894, 894, 894, 894, 894, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+
+ 894, 894, 894, 894, 894, 894, 894, 894,
+ 894, 894, 894, 894, 894, 894, 894, 894,
+ 894, 894, 894, 894, 894, 894, 894, 894,
+ 894, 894, 894, 894, 894, 894, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+
+ 160, 875, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 875, 875, 875, 875, 875, 875, 875, 875,
+ 875, 875, 875, 875, 875, 875, 875, 875,
+ 875, 875, 875, 875, 875, 875, 875, 875,
+ 875, 875, 875, 875, 875, 875, 875, 875,
+ 875, 875, 875, 875, 875, 875, 875, 875,
+ 875, 875, 875, 875, 875, 875, 875, 875,
+ 875, 875, 875, 875, 875, 875, 875, 875,
+ 875, 875, 875, 875, 875, 875, 875, 875,
+ 875, 875, 875, 875, 875, 875, 875, 875,
+ 875, 875, 875, 875, 875, 875, 875, 875,
+ 875, 875, 875, 875, 875, 875, 875, 875,
+ 875, 875, 875, 875, 875, 875, 875, 875,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+
+ 325, 325, 325, 325, 325, 325, 325, 325,
+ 325, 325, 325, 325, 325, 325, 325, 325,
+ 325, 325, 325, 325, 325, 325, 325, 325,
+ 325, 325, 325, 325, 325, 325, 325, 325,
+ 325, 325, 325, 325, 325, 325, 325, 325,
+ 325, 325, 325, 325, 325, 325, 325, 325,
+ 325, 325, 325, 325, 325, 325, 325, 325,
+ 325, 325, 325, 325, 325, 325, 325, 325,
+ 325, 325, 325, 325, 325, 325, 325, 325,
+ 325, 325, 325, 325, 325, 325, 325, 325,
+ 325, 325, 325, 325, 325, 325, 325, 325,
+ 325, 325, 325, 325, 325, 325, 325, 325,
+ 325, 325, 325, 325, 325, 325, 325, 325,
+ 325, 325, 325, 325, 325, 325, 325, 325,
+ 325, 325, 325, 325, 325, 325, 325, 325,
+ 325, 325, 325, 325, 325, 325, 325, 325,
+ 325, 325, 325, 325, 325, 325, 325, 325,
+ 325, 325, 325, 325, 325, 325, 325, 325,
+ 325, 325, 325, 325, 325, 325, 325, 325,
+ 325, 325, 325, 325, 325, 325, 325, 325,
+ 325, 325, 325, 325, 325, 325, 325, 325,
+ 325, 325, 325, 325, 325, 325, 325, 325,
+ 325, 325, 325, 325, 325, 325, 325, 325,
+ 325, 325, 325, 325, 325, 325, 325, 325,
+ 325, 325, 325, 325, 325, 325, 325, 325,
+ 325, 325, 325, 325, 325, 325, 325, 325,
+ 325, 325, 325, 325, 325, 325, 325, 325,
+ 325, 325, 325, 325, 325, 325, 325, 325,
+ 325, 325, 325, 325, 325, 325, 325, 325,
+ 325, 325, 325, 325, 325, 325, 325, 325,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+ 160, 160, 160, 160, 160, 160, 160, 160,
+
+ 895, 895, 895, 895, 895, 895, 895, 895,
+ 895, 895, 895, 895, 895, 895, 895, 895,
+ 895, 895, 895, 895, 895, 895, 895, 895,
+ 895, 895, 895, 895, 895, 895, 895, 895,
+ 895, 895, 895, 895, 895, 895, 895, 895,
+ 895, 895, 895, 895, 895, 895, 895, 895,
+ 895, 895, 895, 895, 895, 895, 895, 895,
+ 895, 895, 895, 895, 895, 895, 895, 895,
+ 895, 895, 895, 895, 895, 895, 895, 895,
+ 895, 895, 895, 895, 895, 895, 895, 895,
+ 895, 895, 895, 895, 895, 895, 895, 895,
+ 895, 895, 895, 895, 895, 895, 895, 895,
+ 895, 895, 895, 895, 895, 895, 895, 895,
+ 895, 895, 895, 895, 895, 895, 895, 895,
+ 895, 895, 895, 895, 895, 895, 895, 895,
+ 895, 895, 895, 895, 895, 895, 895, 895,
+ 895, 895, 895, 895, 895, 895, 895, 895,
+ 895, 895, 895, 895, 895, 895, 895, 895,
+ 895, 895, 895, 895, 895, 895, 895, 895,
+ 895, 895, 895, 895, 895, 895, 895, 895,
+ 895, 895, 895, 895, 895, 895, 895, 895,
+ 895, 895, 895, 895, 895, 895, 895, 895,
+ 895, 895, 895, 895, 895, 895, 895, 895,
+ 895, 895, 895, 895, 895, 895, 895, 895,
+ 895, 895, 895, 895, 895, 895, 895, 895,
+ 895, 895, 895, 895, 895, 895, 895, 895,
+ 895, 895, 895, 895, 895, 895, 895, 895,
+ 895, 895, 895, 895, 895, 895, 895, 895,
+ 895, 895, 895, 895, 895, 895, 895, 895,
+ 895, 895, 895, 895, 895, 895, 895, 895,
+ 895, 895, 895, 895, 895, 895, 895, 895,
+ 895, 895, 895, 895, 895, 895, 895, 895,
+
+ 895, 895, 895, 895, 895, 895, 895, 895,
+ 895, 895, 895, 895, 895, 895, 895, 895,
+ 895, 895, 895, 895, 895, 895, 895, 895,
+ 895, 895, 895, 895, 895, 895, 895, 895,
+ 895, 895, 895, 895, 895, 895, 895, 895,
+ 895, 895, 895, 895, 895, 895, 895, 895,
+ 895, 895, 895, 895, 895, 895, 895, 895,
+ 895, 895, 895, 895, 895, 895, 895, 895,
+ 895, 895, 895, 895, 895, 895, 895, 895,
+ 895, 895, 895, 895, 895, 895, 895, 895,
+ 895, 895, 895, 895, 895, 895, 895, 895,
+ 895, 895, 895, 895, 895, 895, 895, 895,
+ 895, 895, 895, 895, 895, 895, 895, 895,
+ 895, 895, 895, 895, 895, 895, 895, 895,
+ 895, 895, 895, 895, 895, 895, 895, 895,
+ 895, 895, 895, 895, 895, 895, 895, 895,
+ 895, 895, 895, 895, 895, 895, 895, 895,
+ 895, 895, 895, 895, 895, 895, 895, 895,
+ 895, 895, 895, 895, 895, 895, 895, 895,
+ 895, 895, 895, 895, 895, 895, 895, 895,
+ 895, 895, 895, 895, 895, 895, 895, 895,
+ 895, 895, 895, 895, 895, 895, 895, 895,
+ 895, 895, 895, 895, 895, 895, 895, 895,
+ 895, 895, 895, 895, 895, 895, 895, 895,
+ 895, 895, 895, 895, 895, 895, 895, 895,
+ 895, 895, 895, 895, 895, 895, 895, 895,
+ 895, 895, 895, 895, 895, 895, 895, 895,
+ 895, 895, 895, 895, 895, 895, 895, 895,
+ 895, 895, 895, 895, 895, 895, 895, 895,
+ 895, 895, 895, 895, 895, 895, 895, 895,
+ 895, 895, 895, 895, 895, 895, 895, 895,
+ 895, 895, 895, 895, 895, 895, 893, 893,
+};
+
+#define GET_PROP_INDEX(ucs4) \
+ (ucs4 < 0x11000 \
+ ? (uc_property_trie[uc_property_trie[ucs4>>5] + (ucs4 & 0x1f)]) \
+ : (uc_property_trie[uc_property_trie[((ucs4 - 0x11000)>>8) + 0x880] + (ucs4 & 0xff)]))
+
+#define GET_PROP_INDEX_UCS2(ucs2) \
+(uc_property_trie[uc_property_trie[ucs2>>5] + (ucs2 & 0x1f)])
+
+static const QUnicodeTables::Properties uc_properties [] = {
+ { 10, 19, 18, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0},
+ { 10, 15, 8, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 3},
+ { 10, 30, 7, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 1},
+ { 10, 31, 8, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 3},
+ { 10, 31, 9, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 3},
+ { 10, 29, 7, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1},
+ { 10, 19, 7, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0},
+ { 10, 19, 8, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0},
+ { 7, 28, 9, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3},
+ { 26, 5, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9},
+ { 26, 2, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10},
+ { 26, 11, 4, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 28, 8, 4, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 26, 9, 4, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 26, 11, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 26, 2, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 10},
+ { 22, 0, 10, 0, 0, -1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 10},
+ { 23, 1, 10, 0, 0, -1, 1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 10},
+ { 27, 8, 3, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 26, 7, 6, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0},
+ { 21, 14, 3, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 26, 7, 6, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 8},
+ { 26, 6, 6, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 4, 10, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 4, 10, 2, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 4, 10, 2, 0, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 4, 10, 2, 0, 0, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 4, 10, 2, 0, 0, 4, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 4, 10, 2, 0, 0, 5, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 4, 10, 2, 0, 0, 6, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 4, 10, 2, 0, 0, 7, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 4, 10, 2, 0, 0, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 4, 10, 2, 0, 0, 9, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 26, 7, 6, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0},
+ { 26, 7, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0},
+ { 27, 11, 10, 0, 0, -1, 1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0},
+ { 27, 11, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 27, 11, 10, 0, 0, -1, 1, 0, 0, 0, 0, -2, 0, 0, 0, 0, 0, 0, 0},
+ { 15, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 32, 0, 0, 32, 0, 3, 5},
+ { 22, 0, 10, 0, 0, -1, 1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 10},
+ { 26, 8, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 23, 1, 10, 0, 0, -1, 1, 0, 0, 0, 0, -2, 0, 0, 0, 0, 0, 0, 10},
+ { 29, 11, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 20, 11, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, -32, -32, 0, 0, 3, 4},
+ { 27, 15, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 10, 11, 7, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 1},
+ { 7, 3, 6, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6},
+ { 28, 9, 4, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 30, 11, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4},
+ { 24, 2, 10, 0, 0, -1, 1, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 10},
+ { 11, 15, 18, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 2},
+ { 30, 9, 4, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 27, 8, 4, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 6, 11, 2, 0, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 6, 11, 2, 0, 0, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 29, 16, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 743, 743, 775, 0, 3, 4},
+ { 26, 11, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0},
+ { 6, 11, 2, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 25, 2, 10, 0, 0, -1, 1, 0, 0, 0, 0, -16, 0, 0, 0, 0, 0, 0, 10},
+ { 6, 11, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 1, 1, 0, 0, 0, 3, 0, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 121, 121, 0, 0, 3, 4},
+ { 15, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 3, 5},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, -1, -1, 0, 0, 3, 4},
+ { 15, 11, 0, 0, 0, -1, 1, 1, 0, 0, 0, 0, 6, 0, 0, 0, 0, 3, 5},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, -232, -232, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 1, 1, 0, 0, 0, 91, 88, 0, 0, 3, 4},
+ { 15, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, -121, 0, 0, -121, 0, 3, 5},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, -300, -300, -268, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 195, 195, 0, 0, 3, 4},
+ { 15, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 210, 0, 0, 210, 0, 3, 5},
+ { 15, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 206, 0, 0, 206, 0, 3, 5},
+ { 15, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 205, 0, 0, 205, 0, 3, 5},
+ { 15, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 79, 0, 0, 79, 0, 3, 5},
+ { 15, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 202, 0, 0, 202, 0, 3, 5},
+ { 15, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 203, 0, 0, 203, 0, 3, 5},
+ { 15, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 207, 0, 0, 207, 0, 3, 5},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 97, 97, 0, 0, 3, 4},
+ { 15, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 211, 0, 0, 211, 0, 3, 5},
+ { 15, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 209, 0, 0, 209, 0, 3, 5},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 163, 163, 0, 0, 3, 4},
+ { 15, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 213, 0, 0, 213, 0, 3, 5},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 130, 130, 0, 0, 3, 4},
+ { 15, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 214, 0, 0, 214, 0, 3, 5},
+ { 15, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 218, 0, 0, 218, 0, 3, 5},
+ { 15, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 217, 0, 0, 217, 0, 3, 5},
+ { 15, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 219, 0, 0, 219, 0, 3, 5},
+ { 19, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 6},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 56, 56, 0, 0, 3, 4},
+ { 15, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 2, 0, 1, 2, 0, 3, 5},
+ { 17, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 1, -1, 0, 1, 0, 3, 5},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, -2, -1, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, -79, -79, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 1, 1, 0, 0, 0, 113, 110, 0, 0, 3, 4},
+ { 15, 11, 0, 0, 0, -1, 4, 0, 0, 0, 0, 0, -97, 0, 0, -97, 0, 3, 5},
+ { 15, 11, 0, 0, 0, -1, 4, 0, 0, 0, 0, 0, -56, 0, 0, -56, 0, 3, 5},
+ { 15, 11, 0, 0, 0, -1, 4, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 3, 5},
+ { 16, 11, 0, 0, 0, -1, 4, 0, 0, 0, 0, 0, 0, -1, -1, 0, 0, 3, 4},
+ { 15, 11, 0, 0, 0, -1, 6, 0, 0, 0, 0, 0, -130, 0, 0, -130, 0, 3, 5},
+ { 16, 11, 0, 0, 0, -1, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4},
+ { 15, 11, 0, 0, 0, -1, 8, 0, 0, 0, 0, 0, 10795, 0, 0, 10795, 0, 3, 5},
+ { 15, 11, 0, 0, 0, -1, 8, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 3, 5},
+ { 16, 11, 0, 0, 0, -1, 8, 0, 0, 0, 0, 0, 0, -1, -1, 0, 0, 3, 4},
+ { 15, 11, 0, 0, 0, -1, 8, 0, 0, 0, 0, 0, -163, 0, 0, -163, 0, 3, 5},
+ { 15, 11, 0, 0, 0, -1, 8, 0, 0, 0, 0, 0, 10792, 0, 0, 10792, 0, 3, 5},
+ { 16, 11, 0, 0, 0, -1, 9, 0, 0, 0, 0, 0, 0, -1, -1, 0, 0, 3, 4},
+ { 15, 11, 0, 0, 0, -1, 9, 0, 0, 0, 0, 0, -195, 0, 0, -195, 0, 3, 5},
+ { 15, 11, 0, 0, 0, -1, 9, 0, 0, 0, 0, 0, 69, 0, 0, 69, 0, 3, 5},
+ { 15, 11, 0, 0, 0, -1, 9, 0, 0, 0, 0, 0, 71, 0, 0, 71, 0, 3, 5},
+ { 15, 11, 0, 0, 0, -1, 9, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 3, 5},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, -210, -210, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, -206, -206, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, -205, -205, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, -202, -202, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, -203, -203, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, -207, -207, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, -209, -209, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, -211, -211, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 10743, 10743, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, -213, -213, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, -214, -214, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 10727, 10727, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, -218, -218, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, -69, -69, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, -217, -217, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, -71, -71, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, -219, -219, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4},
+ { 18, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4},
+ { 18, 11, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 6},
+ { 18, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 6},
+ { 18, 16, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 6},
+ { 29, 11, 10, 0, 0, -1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 18, 11, 0, 0, 0, -1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 6},
+ { 29, 11, 10, 0, 0, -1, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 1, 19, 17, 230, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 1, 19, 17, 232, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 1, 19, 17, 220, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 1, 19, 17, 216, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 1, 19, 17, 202, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 1, 19, 17, 1, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 1, 19, 17, 240, 0, -1, 1, 0, 0, 0, 0, 0, 0, 84, 84, 116, 4, 1, 0},
+ { 1, 19, 17, 230, 0, -1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 1, 19, 17, 220, 0, -1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 1, 3, 17, 0, 0, -1, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 1, 19, 17, 230, 0, -1, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 1, 19, 17, 220, 0, -1, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 1, 19, 17, 232, 0, -1, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 1, 19, 17, 220, 0, -1, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 1, 19, 17, 230, 0, -1, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 1, 3, 17, 233, 0, -1, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 1, 3, 17, 234, 0, -1, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 1, 3, 17, 233, 0, -1, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 1, 3, 17, 234, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 1, 3, 17, 233, 0, -1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 1, 19, 17, 230, 0, -1, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 0, 11, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 16, 11, 0, 0, 0, -1, 9, 0, 0, 0, 0, 0, 0, 130, 130, 0, 0, 3, 4},
+ { 15, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 38, 0, 0, 38, 0, 3, 5},
+ { 15, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 37, 0, 0, 37, 0, 3, 5},
+ { 15, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 64, 0, 0, 64, 0, 3, 5},
+ { 15, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 63, 0, 0, 63, 0, 3, 5},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 1, 1, 0, 0, 0, 98, 94, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, -38, -38, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, -37, -37, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 1, 1, 0, 0, 0, 106, 102, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, -31, -31, 1, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, -64, -64, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, -63, -63, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, -62, -62, -30, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, -57, -57, -25, 0, 3, 4},
+ { 15, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 5},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, -47, -47, -15, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, -54, -54, -22, 0, 3, 4},
+ { 15, 11, 0, 0, 0, -1, 6, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 3, 5},
+ { 16, 11, 0, 0, 0, -1, 6, 0, 0, 0, 0, 0, 0, -1, -1, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, -86, -86, -54, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, -80, -80, -48, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 7, 7, 0, 0, 3, 4},
+ { 15, 11, 0, 0, 0, -1, 5, 0, 0, 0, 0, 0, -60, 0, 0, -60, 0, 3, 5},
+ { 16, 11, 0, 0, 0, -1, 5, 0, 0, 0, 0, 0, 0, -96, -96, -64, 0, 3, 4},
+ { 27, 11, 10, 0, 0, -1, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 15, 11, 0, 0, 0, -1, 7, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 3, 5},
+ { 16, 11, 0, 0, 0, -1, 7, 0, 0, 0, 0, 0, 0, -1, -1, 0, 0, 3, 4},
+ { 15, 11, 0, 0, 0, -1, 7, 0, 0, 0, 0, 0, -7, 0, 0, -7, 0, 3, 5},
+ { 15, 11, 0, 0, 0, -1, 8, 0, 0, 0, 0, 0, -130, 0, 0, -130, 0, 3, 5},
+ { 15, 11, 0, 0, 0, -1, 4, 0, 0, 0, 0, 0, 80, 0, 0, 80, 0, 3, 5},
+ { 15, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 80, 0, 0, 80, 0, 3, 5},
+ { 16, 11, 0, 0, 0, -1, 4, 0, 0, 0, 0, 0, 0, -80, -80, 0, 0, 3, 4},
+ { 30, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 3, 19, 17, 0, 0, -1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 15, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 15, 0, 0, 15, 0, 3, 5},
+ { 16, 11, 0, 0, 0, -1, 9, 0, 0, 0, 0, 0, 0, -15, -15, 0, 0, 3, 4},
+ { 15, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 48, 0, 0, 48, 0, 3, 5},
+ { 26, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 26, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, -48, -48, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 1, 1, 0, 0, 0, 55, 52, 0, 0, 3, 4},
+ { 26, 7, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 9},
+ { 21, 15, 10, 0, 0, -1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 0, 11, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 1, 19, 17, 220, 0, -1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 1, 19, 17, 230, 0, -1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 1, 19, 17, 222, 0, -1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 1, 19, 17, 228, 0, -1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 1, 19, 17, 10, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 1, 19, 17, 11, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 1, 19, 17, 12, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 1, 19, 17, 13, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 1, 19, 17, 14, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 1, 19, 17, 15, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 1, 19, 17, 16, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 1, 19, 17, 17, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 1, 19, 17, 18, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 1, 19, 17, 19, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 1, 19, 17, 19, 0, -1, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 1, 19, 17, 20, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 1, 19, 17, 21, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 1, 19, 17, 22, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 26, 15, 1, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 1, 19, 17, 23, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 26, 11, 1, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 1, 19, 17, 24, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 1, 19, 17, 25, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 26, 5, 1, 0, 0, -1, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 1, 19, 17, 18, 0, -1, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 19, 11, 1, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 6},
+ { 26, 11, 1, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 6},
+ { 26, 11, 1, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0},
+ { 11, 11, 13, 0, 0, -1, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 2},
+ { 0, 11, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 28, 9, 13, 0, 0, -1, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 26, 5, 6, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 26, 7, 13, 0, 0, -1, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0},
+ { 30, 11, 10, 0, 0, -1, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 26, 5, 13, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 26, 5, 13, 0, 0, -1, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 26, 5, 13, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9},
+ { 19, 11, 13, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 6},
+ { 19, 11, 13, 0, 2, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 6},
+ { 19, 11, 13, 0, 1, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 6},
+ { 18, 11, 13, 0, 3, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 6},
+ { 1, 19, 17, 27, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 1, 19, 17, 28, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 1, 19, 17, 29, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 1, 19, 17, 30, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 1, 19, 17, 31, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 1, 19, 17, 32, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 1, 19, 17, 33, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 1, 19, 17, 34, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 4, 10, 5, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 4, 10, 5, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 4, 10, 5, 0, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 4, 10, 5, 0, 0, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 4, 10, 5, 0, 0, 4, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 4, 10, 5, 0, 0, 5, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 4, 10, 5, 0, 0, 6, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 4, 10, 5, 0, 0, 7, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 4, 10, 5, 0, 0, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 4, 10, 5, 0, 0, 9, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 26, 5, 4, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 26, 10, 5, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 26, 11, 13, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 19, 11, 13, 0, 1, -1, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 6},
+ { 1, 19, 17, 35, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 19, 11, 13, 0, 1, -1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 6},
+ { 19, 11, 13, 0, 2, -1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 6},
+ { 11, 11, 13, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 2},
+ { 3, 19, 17, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 18, 11, 13, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 6},
+ { 19, 11, 13, 0, 2, -1, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 6},
+ { 30, 11, 13, 0, 0, -1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 19, 11, 13, 0, 1, -1, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 6},
+ { 26, 11, 13, 0, 0, -1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9},
+ { 26, 11, 13, 0, 0, -1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 11, 11, 18, 0, 0, -1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 2},
+ { 1, 19, 17, 36, 0, -1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 19, 11, 13, 0, 1, -1, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 6},
+ { 19, 11, 13, 0, 2, -1, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 6},
+ { 19, 11, 13, 0, 0, -1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 6},
+ { 1, 19, 17, 0, 0, -1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 19, 11, 13, 0, 0, -1, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 6},
+ { 4, 10, 1, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 4, 10, 1, 0, 0, 1, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 4, 10, 1, 0, 0, 2, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 4, 10, 1, 0, 0, 3, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 4, 10, 1, 0, 0, 4, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 4, 10, 1, 0, 0, 5, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 4, 10, 1, 0, 0, 6, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 4, 10, 1, 0, 0, 7, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 4, 10, 1, 0, 0, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 4, 10, 1, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 19, 11, 1, 0, 1, -1, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 6},
+ { 1, 19, 17, 230, 0, -1, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 1, 19, 17, 220, 0, -1, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 18, 11, 1, 0, 0, -1, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 6},
+ { 30, 11, 10, 0, 0, -1, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 26, 11, 10, 0, 0, -1, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 26, 7, 10, 0, 0, -1, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0},
+ { 26, 5, 10, 0, 0, -1, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9},
+ { 18, 11, 1, 0, 3, -1, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 6},
+ { 1, 19, 17, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 2, 19, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 6},
+ { 19, 11, 0, 0, 0, -1, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 6},
+ { 1, 19, 17, 7, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 1, 19, 17, 9, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 26, 15, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9},
+ { 4, 10, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 4, 10, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 4, 10, 0, 0, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 4, 10, 0, 0, 0, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 4, 10, 0, 0, 0, 4, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 4, 10, 0, 0, 0, 5, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 4, 10, 0, 0, 0, 6, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 4, 10, 0, 0, 0, 7, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 4, 10, 0, 0, 0, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 4, 10, 0, 0, 0, 9, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 19, 11, 0, 0, 0, -1, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 6},
+ { 19, 11, 0, 0, 0, -1, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 6},
+ { 2, 19, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 6, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 1, 19, 17, 0, 0, -1, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 2, 19, 0, 0, 0, -1, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 6},
+ { 28, 8, 4, 0, 0, -1, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 4, 10, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 1, 19, 17, 84, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 1, 19, 17, 91, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 1, 19, 17, 7, 0, -1, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 1, 19, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 1, 19, 17, 0, 0, -1, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 2, 19, 0, 0, 0, -1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 6},
+ { 19, 11, 0, 0, 0, -1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 6},
+ { 1, 19, 17, 9, 0, -1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 2, 19, 0, 0, 0, -1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 26, 11, 0, 0, 0, -1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 19, 26, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6},
+ { 1, 26, 17, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 1, 26, 17, 103, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 1, 26, 17, 9, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 18, 26, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6},
+ { 1, 26, 17, 107, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 26, 15, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 1, 26, 17, 118, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 1, 26, 17, 122, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 19, 11, 0, 0, 0, -1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 6},
+ { 30, 16, 0, 0, 0, -1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 26, 16, 0, 0, 0, -1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 26, 11, 0, 0, 0, -1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 26, 3, 0, 0, 0, -1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 26, 15, 0, 0, 0, -1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 26, 5, 0, 0, 0, -1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 30, 11, 0, 0, 0, -1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 30, 5, 0, 0, 0, -1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 4, 10, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 4, 10, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 4, 10, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 4, 10, 0, 0, 0, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 4, 10, 0, 0, 0, 4, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 4, 10, 0, 0, 0, 5, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 4, 10, 0, 0, 0, 6, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 4, 10, 0, 0, 0, 7, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 4, 10, 0, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 4, 10, 0, 0, 0, 9, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 6, 11, 0, 0, 0, -1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 30, 15, 0, 0, 0, -1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 1, 19, 17, 216, 0, -1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 22, 0, 10, 0, 0, -1, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 10},
+ { 23, 1, 10, 0, 0, -1, 2, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 10},
+ { 2, 19, 0, 0, 0, -1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 1, 19, 17, 129, 0, -1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 1, 19, 17, 130, 0, -1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 1, 19, 17, 0, 0, -1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 1, 19, 17, 132, 0, -1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 2, 15, 0, 0, 0, -1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 6},
+ { 1, 19, 17, 9, 0, -1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 30, 15, 0, 0, 0, -1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 30, 11, 0, 0, 0, -1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 26, 16, 0, 0, 0, -1, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 19, 26, 0, 0, 0, -1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6},
+ { 2, 26, 0, 0, 0, -1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6},
+ { 1, 26, 17, 0, 0, -1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 1, 26, 17, 7, 0, -1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 1, 26, 17, 9, 0, -1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 4, 10, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 4, 10, 0, 0, 0, 1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 4, 10, 0, 0, 0, 2, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 4, 10, 0, 0, 0, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 4, 10, 0, 0, 0, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 4, 10, 0, 0, 0, 5, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 4, 10, 0, 0, 0, 6, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 4, 10, 0, 0, 0, 7, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 4, 10, 0, 0, 0, 8, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 4, 10, 0, 0, 0, 9, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 26, 15, 0, 0, 0, -1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9},
+ { 15, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 7264, 0, 0, 7264, 0, 3, 5},
+ { 19, 11, 0, 0, 0, -1, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 6},
+ { 18, 11, 0, 0, 0, -1, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 6},
+ { 19, 23, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 3, 6},
+ { 19, 24, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 3, 6},
+ { 19, 25, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 3, 6},
+ { 30, 11, 0, 0, 0, -1, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 26, 15, 0, 0, 0, -1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 26, 11, 0, 0, 0, -1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9},
+ { 6, 11, 0, 0, 0, 1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 6, 11, 0, 0, 0, 2, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 6, 11, 0, 0, 0, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 6, 11, 0, 0, 0, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 6, 11, 0, 0, 0, 5, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 6, 11, 0, 0, 0, 6, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 6, 11, 0, 0, 0, 7, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 6, 11, 0, 0, 0, 8, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 6, 11, 0, 0, 0, 9, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 6, 11, 0, 0, 0, -1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 30, 11, 10, 0, 0, -1, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 7, 15, 9, 0, 0, -1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3},
+ { 22, 0, 10, 0, 0, -1, 4, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 10},
+ { 23, 1, 10, 0, 0, -1, 4, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 10},
+ { 5, 11, 0, 0, 0, -1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 6},
+ { 1, 19, 17, 0, 0, -1, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 1, 19, 17, 9, 0, -1, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 26, 15, 0, 0, 0, -1, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 11, 26, 0, 0, 0, -1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 2},
+ { 26, 4, 0, 0, 0, -1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 18, 26, 0, 0, 0, -1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6},
+ { 28, 8, 4, 0, 0, -1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 1, 26, 17, 230, 0, -1, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 6, 11, 10, 0, 0, -1, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 26, 11, 10, 0, 0, -1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 26, 15, 10, 0, 0, -1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 26, 15, 10, 0, 0, -1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9},
+ { 21, 16, 10, 0, 0, -1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 7, 3, 9, 0, 0, -1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3},
+ { 1, 19, 17, 228, 0, -1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 2, 19, 17, 0, 0, -1, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 6},
+ { 1, 19, 17, 222, 0, -1, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 26, 5, 10, 0, 0, -1, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9},
+ { 4, 10, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 4, 10, 0, 0, 0, 1, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 4, 10, 0, 0, 0, 2, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 4, 10, 0, 0, 0, 3, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 4, 10, 0, 0, 0, 4, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 4, 10, 0, 0, 0, 5, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 4, 10, 0, 0, 0, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 4, 10, 0, 0, 0, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 4, 10, 0, 0, 0, 8, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 4, 10, 0, 0, 0, 9, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 19, 26, 0, 0, 0, -1, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6},
+ { 19, 26, 0, 0, 0, -1, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6},
+ { 2, 26, 0, 0, 0, -1, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6},
+ { 4, 10, 0, 0, 0, 1, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 4, 10, 0, 0, 0, 2, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 4, 10, 0, 0, 0, 3, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 4, 10, 0, 0, 0, 4, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 4, 10, 0, 0, 0, 5, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 4, 10, 0, 0, 0, 6, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 4, 10, 0, 0, 0, 7, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 4, 10, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 4, 10, 0, 0, 0, 9, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 26, 26, 10, 0, 0, -1, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 2, 19, 0, 0, 0, -1, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 6},
+ { 26, 15, 0, 0, 0, -1, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 26, 11, 0, 0, 0, -1, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 2, 19, 0, 0, 0, -1, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 6},
+ { 1, 19, 17, 7, 0, -1, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 2, 19, 0, 9, 0, -1, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 4, 10, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 4, 10, 0, 0, 0, 1, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 4, 10, 0, 0, 0, 2, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 4, 10, 0, 0, 0, 3, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 4, 10, 0, 0, 0, 4, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 4, 10, 0, 0, 0, 5, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 4, 10, 0, 0, 0, 6, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 4, 10, 0, 0, 0, 7, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 4, 10, 0, 0, 0, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 4, 10, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 26, 15, 0, 0, 0, -1, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9},
+ { 26, 15, 0, 0, 0, -1, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 30, 11, 0, 0, 0, -1, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 18, 11, 0, 0, 0, -1, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4},
+ { 18, 11, 0, 0, 0, -1, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 8, 0, 0, 0, 0, 0, 0, 3814, 3814, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 1, 1, 0, 0, 0, 119, 116, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 1, 1, 0, 0, 0, 125, 122, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 1, 1, 0, 0, 0, 131, 128, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 1, 1, 0, 0, 0, 137, 134, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 1, 1, 0, 0, 0, 143, 140, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 2, 0, 0, 0, 0, 0, 0, -59, -59, -58, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 3, 4},
+ { 15, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, -8, 0, 0, -8, 0, 3, 5},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 1, 1, 0, 0, 0, 149, 146, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 1, 1, 0, 0, 0, 156, 152, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 1, 1, 0, 0, 0, 164, 160, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 1, 1, 0, 0, 0, 172, 168, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 74, 74, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 86, 86, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 100, 100, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 128, 128, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 112, 112, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 126, 126, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 1, 0, 0, 0, 0, 244, 8, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 1, 0, 0, 0, 0, 247, 8, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 1, 0, 0, 0, 0, 250, 8, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 1, 0, 0, 0, 0, 253, 8, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 1, 0, 0, 0, 0, 256, 8, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 1, 0, 0, 0, 0, 259, 8, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 1, 0, 0, 0, 0, 262, 8, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 1, 0, 0, 0, 0, 265, 8, 0, 0, 3, 4},
+ { 17, 11, 0, 0, 0, -1, 1, 0, 1, 0, 0, 0, -8, 244, 0, -8, 0, 3, 5},
+ { 17, 11, 0, 0, 0, -1, 1, 0, 1, 0, 0, 0, -8, 247, 0, -8, 0, 3, 5},
+ { 17, 11, 0, 0, 0, -1, 1, 0, 1, 0, 0, 0, -8, 250, 0, -8, 0, 3, 5},
+ { 17, 11, 0, 0, 0, -1, 1, 0, 1, 0, 0, 0, -8, 253, 0, -8, 0, 3, 5},
+ { 17, 11, 0, 0, 0, -1, 1, 0, 1, 0, 0, 0, -8, 256, 0, -8, 0, 3, 5},
+ { 17, 11, 0, 0, 0, -1, 1, 0, 1, 0, 0, 0, -8, 259, 0, -8, 0, 3, 5},
+ { 17, 11, 0, 0, 0, -1, 1, 0, 1, 0, 0, 0, -8, 262, 0, -8, 0, 3, 5},
+ { 17, 11, 0, 0, 0, -1, 1, 0, 1, 0, 0, 0, -8, 268, 0, -8, 0, 3, 5},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 1, 0, 0, 0, 0, 271, 8, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 1, 0, 0, 0, 0, 274, 8, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 1, 0, 0, 0, 0, 277, 8, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 1, 0, 0, 0, 0, 280, 8, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 1, 0, 0, 0, 0, 283, 8, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 1, 0, 0, 0, 0, 286, 8, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 1, 0, 0, 0, 0, 289, 8, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 1, 0, 0, 0, 0, 292, 8, 0, 0, 3, 4},
+ { 17, 11, 0, 0, 0, -1, 1, 0, 1, 0, 0, 0, -8, 271, 0, -8, 0, 3, 5},
+ { 17, 11, 0, 0, 0, -1, 1, 0, 1, 0, 0, 0, -8, 274, 0, -8, 0, 3, 5},
+ { 17, 11, 0, 0, 0, -1, 1, 0, 1, 0, 0, 0, -8, 277, 0, -8, 0, 3, 5},
+ { 17, 11, 0, 0, 0, -1, 1, 0, 1, 0, 0, 0, -8, 280, 0, -8, 0, 3, 5},
+ { 17, 11, 0, 0, 0, -1, 1, 0, 1, 0, 0, 0, -8, 283, 0, -8, 0, 3, 5},
+ { 17, 11, 0, 0, 0, -1, 1, 0, 1, 0, 0, 0, -8, 286, 0, -8, 0, 3, 5},
+ { 17, 11, 0, 0, 0, -1, 1, 0, 1, 0, 0, 0, -8, 289, 0, -8, 0, 3, 5},
+ { 17, 11, 0, 0, 0, -1, 1, 0, 1, 0, 0, 0, -8, 295, 0, -8, 0, 3, 5},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 1, 0, 0, 0, 0, 298, 8, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 1, 0, 0, 0, 0, 301, 8, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 1, 0, 0, 0, 0, 304, 8, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 1, 0, 0, 0, 0, 307, 8, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 1, 0, 0, 0, 0, 310, 8, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 1, 0, 0, 0, 0, 313, 8, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 1, 0, 0, 0, 0, 316, 8, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 1, 0, 0, 0, 0, 319, 8, 0, 0, 3, 4},
+ { 17, 11, 0, 0, 0, -1, 1, 0, 1, 0, 0, 0, -8, 298, 0, -8, 0, 3, 5},
+ { 17, 11, 0, 0, 0, -1, 1, 0, 1, 0, 0, 0, -8, 301, 0, -8, 0, 3, 5},
+ { 17, 11, 0, 0, 0, -1, 1, 0, 1, 0, 0, 0, -8, 304, 0, -8, 0, 3, 5},
+ { 17, 11, 0, 0, 0, -1, 1, 0, 1, 0, 0, 0, -8, 307, 0, -8, 0, 3, 5},
+ { 17, 11, 0, 0, 0, -1, 1, 0, 1, 0, 0, 0, -8, 310, 0, -8, 0, 3, 5},
+ { 17, 11, 0, 0, 0, -1, 1, 0, 1, 0, 0, 0, -8, 313, 0, -8, 0, 3, 5},
+ { 17, 11, 0, 0, 0, -1, 1, 0, 1, 0, 0, 0, -8, 316, 0, -8, 0, 3, 5},
+ { 17, 11, 0, 0, 0, -1, 1, 0, 1, 0, 0, 0, -8, 322, 0, -8, 0, 3, 5},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 1, 1, 0, 0, 0, 346, 343, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 1, 0, 0, 0, 0, 325, 9, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 1, 1, 0, 0, 0, 352, 349, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 1, 1, 0, 0, 0, 179, 176, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 1, 1, 0, 0, 0, 383, 379, 0, 0, 3, 4},
+ { 15, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, -74, 0, 0, -74, 0, 3, 5},
+ { 17, 11, 0, 0, 0, -1, 1, 0, 1, 0, 0, 0, -9, 328, 0, -9, 0, 3, 5},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, -7205, -7205, -7173, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 1, 1, 0, 0, 0, 358, 355, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 1, 0, 0, 0, 0, 331, 9, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 1, 1, 0, 0, 0, 364, 361, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 1, 1, 0, 0, 0, 185, 182, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 1, 1, 0, 0, 0, 391, 387, 0, 0, 3, 4},
+ { 15, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, -86, 0, 0, -86, 0, 3, 5},
+ { 17, 11, 0, 0, 0, -1, 1, 0, 1, 0, 0, 0, -9, 334, 0, -9, 0, 3, 5},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 1, 1, 0, 0, 0, 192, 188, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 1, 1, 0, 0, 0, 94, 94, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 1, 1, 0, 0, 0, 199, 196, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 1, 1, 0, 0, 0, 206, 202, 0, 0, 3, 4},
+ { 15, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, -100, 0, 0, -100, 0, 3, 5},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 1, 1, 0, 0, 0, 214, 210, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 1, 1, 0, 0, 0, 102, 102, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 1, 1, 0, 0, 0, 221, 218, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 1, 1, 0, 0, 0, 227, 224, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 1, 1, 0, 0, 0, 234, 230, 0, 0, 3, 4},
+ { 15, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, -112, 0, 0, -112, 0, 3, 5},
+ { 15, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, -7, 0, 0, -7, 0, 3, 5},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 1, 1, 0, 0, 0, 370, 367, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 1, 0, 0, 0, 0, 337, 9, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 1, 1, 0, 0, 0, 376, 373, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 1, 1, 0, 0, 0, 241, 238, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 1, 1, 0, 0, 0, 399, 395, 0, 0, 3, 4},
+ { 15, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, -128, 0, 0, -128, 0, 3, 5},
+ { 15, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, -126, 0, 0, -126, 0, 3, 5},
+ { 17, 11, 0, 0, 0, -1, 1, 0, 1, 0, 0, 0, -9, 340, 0, -9, 0, 3, 5},
+ { 7, 15, 9, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3},
+ { 7, 3, 9, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3},
+ { 11, 18, 18, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 2},
+ { 11, 19, 18, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 11, 19, 18, 0, 3, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 11, 19, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 2},
+ { 11, 19, 1, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 2},
+ { 21, 15, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 21, 3, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 21, 17, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 21, 11, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 24, 2, 10, 0, 0, -1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 10},
+ { 25, 2, 10, 0, 0, -1, 1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 4, 10},
+ { 22, 0, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10},
+ { 24, 2, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10},
+ { 25, 2, 10, 0, 0, -1, 1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 10},
+ { 26, 13, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 26, 15, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0},
+ { 8, 31, 9, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 1},
+ { 9, 31, 7, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 1},
+ { 11, 19, 11, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 2},
+ { 11, 19, 14, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 2},
+ { 11, 19, 16, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 2},
+ { 11, 19, 12, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 2},
+ { 11, 19, 15, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 2},
+ { 7, 3, 6, 0, 0, -1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3},
+ { 26, 9, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 26, 4, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9},
+ { 27, 7, 6, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0},
+ { 26, 4, 10, 0, 0, -1, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9},
+ { 26, 4, 10, 0, 0, -1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9},
+ { 26, 11, 10, 0, 0, -1, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 26, 11, 10, 0, 0, -1, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 20, 11, 10, 0, 0, -1, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0},
+ { 26, 11, 10, 0, 0, -1, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 26, 15, 10, 0, 0, -1, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 7, 15, 9, 0, 0, -1, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3},
+ { 11, 20, 18, 0, 0, -1, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 2},
+ { 11, 11, 18, 0, 0, -1, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 2},
+ { 11, 19, 18, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 2},
+ { 6, 11, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 16, 11, 0, 0, 0, -1, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4},
+ { 6, 11, 2, 0, 0, 4, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 6, 11, 2, 0, 0, 5, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 6, 11, 2, 0, 0, 6, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 6, 11, 2, 0, 0, 7, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 6, 11, 2, 0, 0, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 6, 11, 2, 0, 0, 9, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 27, 11, 3, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 28, 8, 4, 0, 0, -1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 28, 8, 4, 0, 0, -1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 28, 8, 4, 0, 0, -1, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 28, 8, 4, 0, 0, -1, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 3, 19, 17, 0, 0, -1, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 1, 19, 17, 1, 0, -1, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 1, 19, 17, 220, 0, -1, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 1, 19, 17, 1, 0, -1, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 30, 9, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 30, 8, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 15, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, -7517, 0, 0, -7517, 0, 3, 5},
+ { 15, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, -8383, 0, 0, -8383, 0, 3, 5},
+ { 15, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, -8262, 0, 0, -8262, 0, 3, 5},
+ { 30, 11, 4, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 15, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 28, 0, 0, 28, 0, 3, 5},
+ { 30, 11, 10, 0, 0, -1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 15, 11, 0, 0, 0, -1, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 5},
+ { 30, 11, 10, 0, 0, -1, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 16, 11, 0, 0, 0, -1, 9, 0, 0, 0, 0, 0, 0, -28, -28, 0, 0, 3, 4},
+ { 5, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 16, 0, 0, 16, 0, 3, 5},
+ { 5, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, -16, -16, 0, 0, 3, 4},
+ { 5, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 6},
+ { 27, 11, 10, 0, 0, -1, 1, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0},
+ { 27, 11, 10, 0, 0, -1, 1, 0, 0, 0, 0, -3, 0, 0, 0, 0, 0, 0, 0},
+ { 27, 11, 10, 0, 0, -1, 1, 0, 0, 0, 0, 2016, 0, 0, 0, 0, 0, 0, 0},
+ { 27, 11, 10, 0, 0, -1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0},
+ { 27, 11, 10, 0, 0, -1, 1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0},
+ { 27, 11, 10, 0, 0, -1, 1, 0, 0, 0, 0, 138, 0, 0, 0, 0, 0, 0, 0},
+ { 27, 11, 10, 0, 0, -1, 1, 0, 0, 0, 0, 1824, 0, 0, 0, 0, 0, 0, 0},
+ { 27, 11, 10, 0, 0, -1, 1, 0, 0, 0, 0, 2104, 0, 0, 0, 0, 0, 0, 0},
+ { 27, 11, 10, 0, 0, -1, 1, 0, 0, 0, 0, 2108, 0, 0, 0, 0, 0, 0, 0},
+ { 27, 11, 10, 0, 0, -1, 1, 0, 0, 0, 0, 2106, 0, 0, 0, 0, 0, 0, 0},
+ { 27, 11, 10, 0, 0, -1, 1, 0, 0, 0, 0, -138, 0, 0, 0, 0, 0, 0, 0},
+ { 27, 11, 10, 0, 0, -1, 6, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0},
+ { 27, 11, 10, 0, 0, -1, 6, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0},
+ { 27, 11, 10, 0, 0, -1, 6, 0, 0, 0, 0, -8, 0, 0, 0, 0, 0, 0, 0},
+ { 27, 11, 10, 0, 0, -1, 6, 0, 0, 0, 0, -7, 0, 0, 0, 0, 0, 0, 0},
+ { 27, 11, 10, 0, 0, -1, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 6, 11, 10, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 6, 11, 10, 0, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 6, 11, 10, 0, 0, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 6, 11, 10, 0, 0, 4, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 6, 11, 10, 0, 0, 5, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 6, 11, 10, 0, 0, 6, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 6, 11, 10, 0, 0, 7, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 6, 11, 10, 0, 0, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 6, 11, 10, 0, 0, 9, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 6, 11, 2, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 30, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 26, 0, 0, 26, 0, 3, 5},
+ { 30, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, -26, -26, 0, 0, 3, 4},
+ { 6, 11, 10, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 6, 11, 10, 0, 0, -1, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 6, 11, 10, 0, 0, 1, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 6, 11, 10, 0, 0, 2, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 6, 11, 10, 0, 0, 3, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 6, 11, 10, 0, 0, 4, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 6, 11, 10, 0, 0, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 6, 11, 10, 0, 0, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 6, 11, 10, 0, 0, 7, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 6, 11, 10, 0, 0, 8, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 6, 11, 10, 0, 0, 9, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 6, 11, 10, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 30, 2, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10},
+ { 30, 5, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 22, 0, 10, 0, 0, -1, 6, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 10},
+ { 23, 1, 10, 0, 0, -1, 6, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 10},
+ { 27, 11, 10, 0, 0, -1, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 27, 11, 10, 0, 0, -1, 8, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0},
+ { 27, 11, 10, 0, 0, -1, 8, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0},
+ { 22, 0, 10, 0, 0, -1, 8, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 10},
+ { 23, 1, 10, 0, 0, -1, 8, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 10},
+ { 27, 11, 10, 0, 0, -1, 6, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0},
+ { 27, 11, 10, 0, 0, -1, 6, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0},
+ { 22, 0, 10, 0, 0, -1, 6, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 10},
+ { 23, 1, 10, 0, 0, -1, 6, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 10},
+ { 22, 0, 10, 0, 0, -1, 6, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 10},
+ { 23, 1, 10, 0, 0, -1, 6, 0, 0, 0, 0, -3, 0, 0, 0, 0, 0, 0, 10},
+ { 27, 11, 10, 0, 0, -1, 6, 0, 0, 0, 0, -1824, 0, 0, 0, 0, 0, 0, 0},
+ { 27, 11, 10, 0, 0, -1, 6, 0, 0, 0, 0, -2016, 0, 0, 0, 0, 0, 0, 0},
+ { 27, 11, 10, 0, 0, -1, 6, 0, 0, 0, 0, -2104, 0, 0, 0, 0, 0, 0, 0},
+ { 27, 11, 10, 0, 0, -1, 6, 0, 0, 0, 0, -2106, 0, 0, 0, 0, 0, 0, 0},
+ { 27, 11, 10, 0, 0, -1, 6, 0, 0, 0, 0, -2108, 0, 0, 0, 0, 0, 0, 0},
+ { 15, 11, 0, 0, 0, -1, 8, 0, 0, 0, 0, 0, 48, 0, 0, 48, 0, 3, 5},
+ { 16, 11, 0, 0, 0, -1, 8, 0, 0, 0, 0, 0, 0, -48, -48, 0, 0, 3, 4},
+ { 15, 11, 0, 0, 0, -1, 9, 0, 0, 0, 0, 0, -10743, 0, 0, -10743, 0, 3, 5},
+ { 15, 11, 0, 0, 0, -1, 9, 0, 0, 0, 0, 0, -3814, 0, 0, -3814, 0, 3, 5},
+ { 15, 11, 0, 0, 0, -1, 9, 0, 0, 0, 0, 0, -10727, 0, 0, -10727, 0, 3, 5},
+ { 16, 11, 0, 0, 0, -1, 9, 0, 0, 0, 0, 0, 0, -10795, -10795, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 9, 0, 0, 0, 0, 0, 0, -10792, -10792, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4},
+ { 6, 11, 10, 0, 0, -1, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 16, 11, 0, 0, 0, -1, 8, 0, 0, 0, 0, 0, 0, -7264, -7264, 0, 0, 3, 4},
+ { 26, 2, 10, 0, 0, -1, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10},
+ { 24, 2, 10, 0, 0, -1, 8, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 10},
+ { 25, 2, 10, 0, 0, -1, 8, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 10},
+ { 21, 15, 10, 0, 0, -1, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 30, 12, 10, 0, 0, -1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 7, 12, 9, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3},
+ { 26, 1, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 26, 1, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9},
+ { 26, 12, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 30, 12, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 18, 4, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 6},
+ { 19, 12, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6},
+ { 5, 12, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6},
+ { 21, 4, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 23, 1, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10},
+ { 1, 19, 17, 218, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 1, 19, 17, 228, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 1, 19, 17, 222, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 1, 19, 17, 224, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 21, 12, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 18, 12, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 6},
+ { 5, 12, 0, 0, 0, -1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6},
+ { 18, 4, 0, 0, 0, -1, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 6},
+ { 19, 4, 0, 0, 0, -1, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 6},
+ { 26, 12, 10, 0, 0, -1, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 19, 4, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6},
+ { 19, 4, 0, 0, 0, -1, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6},
+ { 1, 19, 17, 8, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 29, 4, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0},
+ { 18, 4, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6},
+ { 19, 12, 0, 0, 0, -1, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6},
+ { 21, 4, 10, 0, 0, -1, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0},
+ { 19, 4, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 6},
+ { 19, 12, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 6},
+ { 26, 4, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 18, 4, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 6},
+ { 19, 12, 0, 0, 0, -1, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 6},
+ { 19, 12, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 6},
+ { 30, 12, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 6, 12, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 19, 12, 0, 0, 0, -1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 6},
+ { 30, 12, 10, 0, 0, -1, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 19, 4, 0, 0, 0, -1, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 6},
+ { 30, 12, 10, 0, 0, -1, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 6, 12, 10, 0, 0, -1, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 19, 12, 0, 0, 0, -1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6},
+ { 19, 12, 0, 0, 0, -1, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6},
+ { 18, 4, 0, 0, 0, -1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 6},
+ { 30, 12, 10, 0, 0, -1, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 29, 11, 10, 0, 0, -1, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 18, 11, 10, 0, 0, -1, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 6},
+ { 29, 11, 10, 0, 0, -1, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 2, 19, 17, 0, 0, -1, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 1, 19, 17, 9, 0, -1, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 1, 19, 17, 0, 0, -1, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 26, 16, 10, 0, 0, -1, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 19, 21, 0, 0, 0, -1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 3, 6},
+ { 19, 22, 0, 0, 0, -1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 3, 6},
+ { 12, 27, 0, 0, 0, -1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 13, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 19, 12, 0, 0, 0, -1, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 6},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 1, 1, 0, 0, 0, 12, 9, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 1, 1, 0, 0, 0, 18, 15, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 1, 1, 0, 0, 0, 24, 21, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 1, 1, 0, 0, 0, 31, 27, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 1, 1, 0, 0, 0, 39, 35, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 1, 1, 0, 0, 0, 46, 43, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 1, 1, 0, 0, 0, 49, 43, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 1, 1, 0, 0, 0, 61, 58, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 1, 1, 0, 0, 0, 67, 64, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 1, 1, 0, 0, 0, 73, 70, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 1, 1, 0, 0, 0, 79, 76, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 1, 0, 1, 1, 0, 0, 0, 85, 82, 0, 0, 3, 4},
+ { 19, 11, 1, 0, 0, -1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 6},
+ { 1, 19, 17, 26, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 0, 11, 0, 0, 0, -1, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 28, 9, 13, 0, 0, -1, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 26, 7, 10, 0, 0, -1, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0},
+ { 26, 1, 10, 0, 0, -1, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 26, 5, 10, 0, 0, -1, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 22, 0, 10, 0, 0, -1, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10},
+ { 23, 1, 10, 0, 0, -1, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10},
+ { 26, 13, 10, 0, 0, -1, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 20, 12, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0},
+ { 22, 0, 10, 0, 0, -1, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10},
+ { 23, 1, 10, 0, 0, -1, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10},
+ { 26, 1, 6, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 26, 1, 6, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9},
+ { 26, 4, 6, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 26, 12, 4, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 27, 12, 3, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 21, 12, 3, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 27, 12, 10, 0, 0, -1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0},
+ { 27, 12, 10, 0, 0, -1, 1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0},
+ { 27, 12, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 11, 20, 18, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 2},
+ { 26, 12, 6, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 4, 12, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 4, 12, 2, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 4, 12, 2, 0, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 4, 12, 2, 0, 0, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 4, 12, 2, 0, 0, 4, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 4, 12, 2, 0, 0, 5, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 4, 12, 2, 0, 0, 6, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 4, 12, 2, 0, 0, 7, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 4, 12, 2, 0, 0, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 4, 12, 2, 0, 0, 9, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 27, 12, 10, 0, 0, -1, 1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0},
+ { 27, 12, 10, 0, 0, -1, 1, 0, 0, 0, 0, -2, 0, 0, 0, 0, 0, 0, 0},
+ { 15, 12, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 32, 0, 0, 32, 0, 3, 5},
+ { 29, 12, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 16, 12, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, -32, -32, 0, 0, 3, 4},
+ { 19, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 6},
+ { 11, 19, 10, 0, 0, -1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 2},
+ { 30, 11, 10, 0, 0, -1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 0, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 26, 15, 0, 0, 0, -1, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 26, 15, 10, 0, 0, -1, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 30, 15, 0, 0, 0, -1, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 6, 11, 0, 0, 0, -1, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 30, 11, 0, 0, 0, -1, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 5, 11, 10, 0, 0, -1, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 6},
+ { 19, 11, 0, 0, 0, -1, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 6},
+ { 6, 11, 0, 0, 0, -1, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 5, 11, 0, 0, 0, -1, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 6},
+ { 5, 11, 0, 0, 0, -1, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 6},
+ { 15, 11, 0, 0, 0, -1, 5, 0, 0, 0, 0, 0, 40, 0, 0, 40, 0, 3, 5},
+ { 15, 11, 0, 0, 0, -1, 7, 0, 0, 0, 0, 0, 40, 0, 0, 40, 0, 3, 5},
+ { 16, 11, 0, 0, 0, -1, 5, 0, 0, 0, 0, 0, 0, -40, -40, 0, 0, 3, 4},
+ { 16, 11, 0, 0, 0, -1, 7, 0, 0, 0, 0, 0, 0, -40, -40, 0, 0, 3, 4},
+ { 19, 11, 1, 0, 0, -1, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 6},
+ { 19, 11, 1, 0, 0, -1, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 6},
+ { 6, 11, 1, 0, 0, -1, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 26, 15, 10, 0, 0, -1, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 19, 11, 1, 0, 0, -1, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 6},
+ { 6, 11, 1, 0, 0, 1, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 6, 11, 1, 0, 0, 2, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 6, 11, 1, 0, 0, 3, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 6, 11, 1, 0, 0, 4, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 6, 11, 1, 0, 0, -1, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 26, 15, 1, 0, 0, -1, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 26, 11, 1, 0, 0, -1, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 5, 11, 0, 0, 0, -1, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 6},
+ { 30, 11, 0, 0, 0, -1, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 2, 19, 0, 216, 0, -1, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 2, 19, 0, 216, 0, -1, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 1, 19, 17, 1, 0, -1, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 2, 19, 0, 226, 0, -1, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 11, 19, 18, 0, 0, -1, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 2},
+ { 1, 19, 17, 220, 0, -1, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 1, 19, 17, 230, 0, -1, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0},
+ { 6, 11, 0, 0, 0, -1, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 15, 11, 0, 0, 0, -1, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 5},
+ { 16, 11, 0, 0, 0, -1, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4},
+ { 27, 11, 0, 0, 0, -1, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 15, 11, 0, 0, 0, -1, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 5},
+ { 4, 10, 2, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 4, 10, 2, 0, 0, 1, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 4, 10, 2, 0, 0, 2, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 4, 10, 2, 0, 0, 3, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 4, 10, 2, 0, 0, 4, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 4, 10, 2, 0, 0, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 4, 10, 2, 0, 0, 6, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 4, 10, 2, 0, 0, 7, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 4, 10, 2, 0, 0, 8, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 4, 10, 2, 0, 0, 9, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7},
+ { 0, 11, 0, 0, 0, -1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 19, 12, 0, 0, 0, -1, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6},
+ { 13, 11, 0, 0, 0, -1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+};
+
+static inline const QUnicodeTables::Properties *qGetProp(uint ucs4)
+{
+ int index = GET_PROP_INDEX(ucs4);
+ return uc_properties + index;
+}
+
+static inline const QUnicodeTables::Properties *qGetProp(ushort ucs2)
+{
+ int index = GET_PROP_INDEX_UCS2(ucs2);
+ return uc_properties + index;
+}
+
+Q_CORE_EXPORT const QUnicodeTables::Properties* QT_FASTCALL QUnicodeTables::properties(uint ucs4)
+{
+ int index = GET_PROP_INDEX(ucs4);
+ return uc_properties + index;
+}
+
+Q_CORE_EXPORT const QUnicodeTables::Properties* QT_FASTCALL QUnicodeTables::properties(ushort ucs2)
+{
+ int index = GET_PROP_INDEX_UCS2(ucs2);
+ return uc_properties + index;
+}
+
+#define CURRENT_VERSION QChar::Unicode_5_0
+
+static const ushort specialCaseMap [] = {
+ 0x53, 0x73, 0x0, 0x53, 0x53, 0x0, 0x69, 0x307, 0x0, 0x46, 0x66, 0x0, 0x46, 0x46, 0x0, 0x46,
+ 0x69, 0x0, 0x46, 0x49, 0x0, 0x46, 0x6c, 0x0, 0x46, 0x4c, 0x0, 0x46, 0x66, 0x69, 0x0, 0x46,
+ 0x46, 0x49, 0x0, 0x46, 0x66, 0x6c, 0x0, 0x46, 0x46, 0x4c, 0x0, 0x53, 0x74, 0x0, 0x53, 0x54,
+ 0x0, 0x53, 0x54, 0x0, 0x535, 0x582, 0x0, 0x535, 0x552, 0x0, 0x544, 0x576, 0x0, 0x544, 0x546, 0x0,
+ 0x544, 0x565, 0x0, 0x544, 0x535, 0x0, 0x544, 0x56b, 0x0, 0x544, 0x53b, 0x0, 0x54e, 0x576, 0x0, 0x54e,
+ 0x546, 0x0, 0x544, 0x56d, 0x0, 0x544, 0x53d, 0x0, 0x2bc, 0x4e, 0x0, 0x2bc, 0x4e, 0x0, 0x399, 0x308,
+ 0x301, 0x0, 0x399, 0x308, 0x301, 0x0, 0x3a5, 0x308, 0x301, 0x0, 0x3a5, 0x308, 0x301, 0x0, 0x4a, 0x30c,
+ 0x0, 0x4a, 0x30c, 0x0, 0x48, 0x331, 0x0, 0x48, 0x331, 0x0, 0x54, 0x308, 0x0, 0x54, 0x308, 0x0,
+ 0x57, 0x30a, 0x0, 0x57, 0x30a, 0x0, 0x59, 0x30a, 0x0, 0x59, 0x30a, 0x0, 0x41, 0x2be, 0x0, 0x41,
+ 0x2be, 0x0, 0x3a5, 0x313, 0x0, 0x3a5, 0x313, 0x0, 0x3a5, 0x313, 0x300, 0x0, 0x3a5, 0x313, 0x300, 0x0,
+ 0x3a5, 0x313, 0x301, 0x0, 0x3a5, 0x313, 0x301, 0x0, 0x3a5, 0x313, 0x342, 0x0, 0x3a5, 0x313, 0x342, 0x0,
+ 0x391, 0x342, 0x0, 0x391, 0x342, 0x0, 0x397, 0x342, 0x0, 0x397, 0x342, 0x0, 0x399, 0x308, 0x300, 0x0,
+ 0x399, 0x308, 0x300, 0x0, 0x399, 0x342, 0x0, 0x399, 0x342, 0x0, 0x399, 0x308, 0x342, 0x0, 0x399, 0x308,
+ 0x342, 0x0, 0x3a5, 0x308, 0x300, 0x0, 0x3a5, 0x308, 0x300, 0x0, 0x3a1, 0x313, 0x0, 0x3a1, 0x313, 0x0,
+ 0x3a5, 0x342, 0x0, 0x3a5, 0x342, 0x0, 0x3a5, 0x308, 0x342, 0x0, 0x3a5, 0x308, 0x342, 0x0, 0x3a9, 0x342,
+ 0x0, 0x3a9, 0x342, 0x0, 0x1f08, 0x399, 0x0, 0x1f09, 0x399, 0x0, 0x1f0a, 0x399, 0x0, 0x1f0b, 0x399, 0x0,
+ 0x1f0c, 0x399, 0x0, 0x1f0d, 0x399, 0x0, 0x1f0e, 0x399, 0x0, 0x1f0f, 0x399, 0x0, 0x1f0f, 0x399, 0x0, 0x1f28,
+ 0x399, 0x0, 0x1f29, 0x399, 0x0, 0x1f2a, 0x399, 0x0, 0x1f2b, 0x399, 0x0, 0x1f2c, 0x399, 0x0, 0x1f2d, 0x399,
+ 0x0, 0x1f2e, 0x399, 0x0, 0x1f2f, 0x399, 0x0, 0x1f2f, 0x399, 0x0, 0x1f68, 0x399, 0x0, 0x1f69, 0x399, 0x0,
+ 0x1f6a, 0x399, 0x0, 0x1f6b, 0x399, 0x0, 0x1f6c, 0x399, 0x0, 0x1f6d, 0x399, 0x0, 0x1f6e, 0x399, 0x0, 0x1f6f,
+ 0x399, 0x0, 0x1f6f, 0x399, 0x0, 0x391, 0x399, 0x0, 0x391, 0x399, 0x0, 0x397, 0x399, 0x0, 0x397, 0x399,
+ 0x0, 0x3a9, 0x399, 0x0, 0x3a9, 0x399, 0x0, 0x1fba, 0x345, 0x0, 0x1fba, 0x399, 0x0, 0x386, 0x345, 0x0,
+ 0x386, 0x399, 0x0, 0x1fca, 0x345, 0x0, 0x1fca, 0x399, 0x0, 0x389, 0x345, 0x0, 0x389, 0x399, 0x0, 0x1ffa,
+ 0x345, 0x0, 0x1ffa, 0x399, 0x0, 0x38f, 0x345, 0x0, 0x38f, 0x399, 0x0, 0x391, 0x342, 0x345, 0x0, 0x391,
+ 0x342, 0x399, 0x0, 0x397, 0x342, 0x345, 0x0, 0x397, 0x342, 0x399, 0x0, 0x3a9, 0x342, 0x345, 0x0, 0x3a9,
+ 0x342, 0x399, 0x0
+};
+#define SPECIAL_CASE_MAX_LEN 3
+
+static const unsigned short uc_decomposition_trie[] = {
+ // 0 - 0x3400
+
+ 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548,
+ 1548, 1548, 1564, 1580, 1596, 1612, 1628, 1644,
+ 1660, 1676, 1692, 1708, 1724, 1740, 1756, 1772,
+ 1548, 1548, 1788, 1804, 1820, 1836, 1852, 1868,
+ 1884, 1900, 1916, 1932, 1548, 1548, 1548, 1548,
+ 1548, 1548, 1548, 1948, 1548, 1964, 1980, 1548,
+ 1548, 1548, 1548, 1548, 1996, 1548, 1548, 2012,
+ 2028, 2044, 2060, 2076, 2092, 2108, 1548, 2124,
+ 2140, 2156, 1548, 2172, 1548, 2188, 1548, 2204,
+ 1548, 1548, 1548, 1548, 2220, 2236, 2252, 2268,
+ 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548,
+ 2284, 1548, 1548, 1548, 1548, 1548, 1548, 1548,
+ 1548, 1548, 2300, 1548, 1548, 1548, 1548, 2316,
+ 1548, 1548, 1548, 1548, 2332, 2348, 1548, 1548,
+ 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548,
+ 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548,
+ 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548,
+ 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548,
+ 1548, 1548, 2364, 2380, 1548, 2396, 1548, 1548,
+ 1548, 1548, 1548, 1548, 2412, 2428, 1548, 1548,
+ 1548, 1548, 1548, 2444, 1548, 2460, 1548, 1548,
+ 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548,
+ 1548, 1548, 1548, 1548, 2476, 2492, 1548, 1548,
+ 1548, 2508, 1548, 1548, 2524, 1548, 1548, 1548,
+ 1548, 1548, 1548, 1548, 2540, 1548, 1548, 1548,
+ 1548, 1548, 1548, 1548, 2556, 1548, 1548, 1548,
+ 1548, 1548, 1548, 1548, 2572, 1548, 1548, 1548,
+ 1548, 1548, 1548, 1548, 1548, 2588, 1548, 1548,
+ 1548, 1548, 1548, 2604, 1548, 1548, 1548, 1548,
+ 1548, 1548, 1548, 2620, 1548, 2636, 1548, 1548,
+ 2652, 1548, 1548, 1548, 2668, 2684, 2700, 2716,
+ 2732, 2748, 2764, 2780, 1548, 1548, 1548, 1548,
+
+ 1548, 1548, 2796, 1548, 1548, 1548, 1548, 1548,
+ 1548, 1548, 1548, 1548, 1548, 1548, 1548, 2812,
+ 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548,
+ 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548,
+ 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548,
+ 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548,
+ 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548,
+ 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548,
+ 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548,
+ 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548,
+ 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548,
+ 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548,
+ 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548,
+ 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548,
+ 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548,
+ 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548,
+ 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548,
+ 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548,
+ 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548,
+ 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548,
+ 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548,
+ 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548,
+ 2828, 2844, 1548, 2860, 2876, 1548, 1548, 1548,
+ 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548,
+ 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548,
+ 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548,
+ 1548, 1548, 2892, 2908, 2924, 2940, 2956, 2972,
+ 1548, 2988, 3004, 3020, 1548, 1548, 1548, 1548,
+ 3036, 3052, 3068, 3084, 3100, 3116, 3132, 3148,
+ 3164, 3180, 3196, 3212, 3228, 3244, 3260, 3276,
+ 3292, 3308, 3324, 3340, 3356, 3372, 3388, 3404,
+ 3420, 3436, 3452, 3468, 3484, 3500, 3516, 3532,
+
+ 3548, 3564, 3580, 3596, 3612, 3628, 1548, 3644,
+ 3660, 3676, 3692, 1548, 1548, 1548, 1548, 1548,
+ 3708, 3724, 3740, 3756, 3772, 3788, 3804, 3820,
+ 1548, 3836, 3852, 1548, 3868, 1548, 1548, 1548,
+ 3884, 1548, 3900, 3916, 3932, 1548, 3948, 3964,
+ 3980, 1548, 3996, 1548, 1548, 1548, 4012, 1548,
+ 1548, 1548, 4028, 1548, 1548, 1548, 1548, 1548,
+ 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548,
+ 1548, 1548, 1548, 1548, 1548, 1548, 4044, 4060,
+ 4076, 4092, 4108, 4124, 4140, 4156, 4172, 1548,
+ 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548,
+ 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548,
+ 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548,
+ 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548,
+ 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548,
+ 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548,
+ 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548,
+ 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548,
+ 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548,
+ 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548,
+ 4188, 1548, 1548, 1548, 1548, 1548, 1548, 4204,
+ 1548, 1548, 1548, 1548, 1548, 4220, 1548, 1548,
+ 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548,
+ 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548,
+ 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548,
+ 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548,
+ 1548, 1548, 1548, 1548, 1548, 1548, 4236, 1548,
+ 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548,
+ 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548,
+ 1548, 4252, 1548, 1548, 1548, 1548, 1548, 4268,
+ 4284, 4300, 4316, 4332, 4348, 4364, 4380, 4396,
+ 4412, 4428, 4444, 4460, 4476, 4492, 1548, 1548,
+
+ 4508, 1548, 1548, 4524, 4540, 4556, 4572, 4588,
+ 1548, 4604, 4620, 4636, 4652, 4668, 1548, 4684,
+ 1548, 1548, 1548, 4700, 4716, 4732, 4748, 4764,
+ 4780, 4796, 1548, 1548, 1548, 1548, 1548, 1548,
+ 4812, 4828, 4844, 4860, 4876, 4892, 4908, 4924,
+ 4940, 4956, 4972, 4988, 5004, 5020, 5036, 5052,
+ 5068, 5084, 5100, 5116, 5132, 5148, 5164, 5180,
+ 5196, 5212, 5228, 5244, 5260, 5276, 5292, 5308,
+
+ // 0x3400 - 0x30000
+
+ 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324,
+ 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324,
+ 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324,
+ 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324,
+ 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324,
+ 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324,
+ 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324,
+ 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324,
+ 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324,
+ 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324,
+ 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324,
+ 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324,
+ 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324,
+ 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324,
+ 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324,
+ 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324,
+ 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324,
+ 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324,
+ 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324,
+ 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324,
+ 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324,
+ 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324,
+ 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324,
+ 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324,
+
+ 5324, 5324, 5324, 5324, 5324, 5580, 5836, 6092,
+ 6348, 6604, 6860, 7116, 5324, 5324, 5324, 5324,
+ 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324,
+ 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324,
+ 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324,
+ 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324,
+ 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324,
+ 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324,
+ 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324,
+ 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324,
+ 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324,
+ 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324,
+ 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324,
+ 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324,
+ 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324,
+ 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324,
+ 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324,
+ 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324,
+ 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324,
+ 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324,
+ 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324,
+ 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324,
+ 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324,
+ 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324,
+ 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324,
+ 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324,
+ 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324,
+ 5324, 5324, 5324, 5324, 5324, 7372, 5324, 5324,
+ 7628, 7884, 8140, 8396, 5324, 5324, 5324, 5324,
+ 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324,
+ 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324,
+ 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324,
+
+ 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324,
+ 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324,
+ 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324,
+ 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324,
+ 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324,
+ 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324,
+ 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324,
+ 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324,
+ 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324,
+ 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324,
+ 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324,
+ 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324,
+ 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324,
+ 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324,
+ 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324,
+ 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324,
+ 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324,
+ 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324,
+ 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324,
+ 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324,
+ 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324,
+ 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324,
+ 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324,
+ 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324,
+ 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324,
+ 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324,
+ 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324,
+ 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324,
+ 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324,
+ 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324,
+ 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324,
+ 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324,
+
+ 5324, 5324, 5324, 5324, 8652, 8908, 9164, 5324,
+ 5324, 5324, 5324, 5324,
+
+
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+
+ 0x0, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0x2, 0xffff, 0x5, 0xffff, 0xffff, 0xffff, 0xffff, 0x7,
+
+ 0xffff, 0xffff, 0xa, 0xc, 0xe, 0x11, 0xffff, 0xffff,
+ 0x13, 0x16, 0x18, 0xffff, 0x1a, 0x1e, 0x22, 0xffff,
+
+ 0x26, 0x29, 0x2c, 0x2f, 0x32, 0x35, 0xffff, 0x38,
+ 0x3b, 0x3e, 0x41, 0x44, 0x47, 0x4a, 0x4d, 0x50,
+
+ 0xffff, 0x53, 0x56, 0x59, 0x5c, 0x5f, 0x62, 0xffff,
+ 0xffff, 0x65, 0x68, 0x6b, 0x6e, 0x71, 0xffff, 0xffff,
+
+ 0x74, 0x77, 0x7a, 0x7d, 0x80, 0x83, 0xffff, 0x86,
+ 0x89, 0x8c, 0x8f, 0x92, 0x95, 0x98, 0x9b, 0x9e,
+
+ 0xffff, 0xa1, 0xa4, 0xa7, 0xaa, 0xad, 0xb0, 0xffff,
+ 0xffff, 0xb3, 0xb6, 0xb9, 0xbc, 0xbf, 0xffff, 0xc2,
+
+ 0xc5, 0xc8, 0xcb, 0xce, 0xd1, 0xd4, 0xd7, 0xda,
+ 0xdd, 0xe0, 0xe3, 0xe6, 0xe9, 0xec, 0xef, 0xf2,
+
+ 0xffff, 0xffff, 0xf5, 0xf8, 0xfb, 0xfe, 0x101, 0x104,
+ 0x107, 0x10a, 0x10d, 0x110, 0x113, 0x116, 0x119, 0x11c,
+
+ 0x11f, 0x122, 0x125, 0x128, 0x12b, 0x12e, 0xffff, 0xffff,
+ 0x131, 0x134, 0x137, 0x13a, 0x13d, 0x140, 0x143, 0x146,
+
+ 0x149, 0xffff, 0x14c, 0x14f, 0x152, 0x155, 0x158, 0x15b,
+ 0xffff, 0x15e, 0x161, 0x164, 0x167, 0x16a, 0x16d, 0x170,
+
+ 0x173, 0xffff, 0xffff, 0x176, 0x179, 0x17c, 0x17f, 0x182,
+ 0x185, 0x188, 0xffff, 0xffff, 0x18b, 0x18e, 0x191, 0x194,
+
+ 0x197, 0x19a, 0xffff, 0xffff, 0x19d, 0x1a0, 0x1a3, 0x1a6,
+ 0x1a9, 0x1ac, 0x1af, 0x1b2, 0x1b5, 0x1b8, 0x1bb, 0x1be,
+
+ 0x1c1, 0x1c4, 0x1c7, 0x1ca, 0x1cd, 0x1d0, 0xffff, 0xffff,
+ 0x1d3, 0x1d6, 0x1d9, 0x1dc, 0x1df, 0x1e2, 0x1e5, 0x1e8,
+
+ 0x1eb, 0x1ee, 0x1f1, 0x1f4, 0x1f7, 0x1fa, 0x1fd, 0x200,
+ 0x203, 0x206, 0x209, 0x20c, 0x20f, 0x212, 0x215, 0x218,
+
+ 0x21a, 0x21d, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x220,
+
+ 0x223, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+
+ 0xffff, 0xffff, 0xffff, 0xffff, 0x226, 0x229, 0x22c, 0x22f,
+ 0x232, 0x235, 0x238, 0x23b, 0x23e, 0x241, 0x244, 0x247,
+
+ 0x24a, 0x24d, 0x250, 0x253, 0x256, 0x259, 0x25c, 0x25f,
+ 0x262, 0x265, 0x268, 0x26b, 0x26e, 0xffff, 0x271, 0x274,
+
+ 0x277, 0x27a, 0x27d, 0x280, 0xffff, 0xffff, 0x283, 0x286,
+ 0x289, 0x28c, 0x28f, 0x292, 0x295, 0x298, 0x29b, 0x29e,
+
+ 0x2a1, 0x2a4, 0x2a7, 0x2aa, 0x2ad, 0x2b0, 0xffff, 0xffff,
+ 0x2b3, 0x2b6, 0x2b9, 0x2bc, 0x2bf, 0x2c2, 0x2c5, 0x2c8,
+
+ 0x2cb, 0x2ce, 0x2d1, 0x2d4, 0x2d7, 0x2da, 0x2dd, 0x2e0,
+ 0x2e3, 0x2e6, 0x2e9, 0x2ec, 0x2ef, 0x2f2, 0x2f5, 0x2f8,
+
+ 0x2fb, 0x2fe, 0x301, 0x304, 0x307, 0x30a, 0x30d, 0x310,
+ 0x313, 0x316, 0x319, 0x31c, 0xffff, 0xffff, 0x31f, 0x322,
+
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x325, 0x328,
+ 0x32b, 0x32e, 0x331, 0x334, 0x337, 0x33a, 0x33d, 0x340,
+
+ 0x343, 0x346, 0x349, 0x34c, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+
+ 0x34f, 0x351, 0x353, 0x355, 0x357, 0x359, 0x35b, 0x35d,
+ 0x35f, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0x361, 0x364, 0x367, 0x36a, 0x36d, 0x370, 0xffff, 0xffff,
+
+ 0x373, 0x375, 0x377, 0x379, 0x37b, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+
+ 0x37d, 0x37f, 0xffff, 0x381, 0x383, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+
+ 0xffff, 0xffff, 0xffff, 0xffff, 0x386, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0x388, 0xffff, 0xffff, 0xffff, 0x38b, 0xffff,
+
+ 0xffff, 0xffff, 0xffff, 0xffff, 0x38d, 0x390, 0x393, 0x396,
+ 0x398, 0x39b, 0x39e, 0xffff, 0x3a1, 0xffff, 0x3a4, 0x3a7,
+
+ 0x3aa, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0x3ad, 0x3b0, 0x3b3, 0x3b6, 0x3b9, 0x3bc,
+
+ 0x3bf, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0x3c2, 0x3c5, 0x3c8, 0x3cb, 0x3ce, 0xffff,
+
+ 0x3d1, 0x3d3, 0x3d5, 0x3d7, 0x3da, 0x3dd, 0x3df, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+
+ 0x3e1, 0x3e3, 0x3e5, 0xffff, 0x3e7, 0x3e9, 0xffff, 0xffff,
+ 0xffff, 0x3eb, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+
+ 0x3ed, 0x3f0, 0xffff, 0x3f3, 0xffff, 0xffff, 0xffff, 0x3f6,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0x3f9, 0x3fc, 0x3ff, 0xffff,
+
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0x402, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0x405, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+
+ 0x408, 0x40b, 0xffff, 0x40e, 0xffff, 0xffff, 0xffff, 0x411,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0x414, 0x417, 0x41a, 0xffff,
+
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x41d, 0x420,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+
+ 0xffff, 0x423, 0x426, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+
+ 0x429, 0x42c, 0x42f, 0x432, 0xffff, 0xffff, 0x435, 0x438,
+ 0xffff, 0xffff, 0x43b, 0x43e, 0x441, 0x444, 0x447, 0x44a,
+
+ 0xffff, 0xffff, 0x44d, 0x450, 0x453, 0x456, 0x459, 0x45c,
+ 0xffff, 0xffff, 0x45f, 0x462, 0x465, 0x468, 0x46b, 0x46e,
+
+ 0x471, 0x474, 0x477, 0x47a, 0x47d, 0x480, 0xffff, 0xffff,
+ 0x483, 0x486, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x489,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+
+ 0xffff, 0xffff, 0x48c, 0x48f, 0x492, 0x495, 0x498, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x49b, 0x49e, 0x4a1,
+ 0x4a4, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+
+ 0x4a7, 0xffff, 0x4aa, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+
+ 0xffff, 0xffff, 0xffff, 0x4ad, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0x4b0, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+
+ 0xffff, 0x4b3, 0xffff, 0xffff, 0x4b6, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0x4b9, 0x4bc, 0x4bf, 0x4c2, 0x4c5, 0x4c8, 0x4cb, 0x4ce,
+
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0x4d1, 0x4d4, 0xffff, 0xffff, 0xffff,
+
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0x4d7, 0x4da, 0xffff, 0x4dd,
+
+ 0xffff, 0xffff, 0xffff, 0x4e0, 0xffff, 0xffff, 0x4e3, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0x4e6, 0x4e9, 0x4ec, 0xffff, 0xffff, 0x4ef, 0xffff,
+
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0x4f2, 0xffff, 0xffff, 0x4f5, 0x4f8, 0xffff, 0xffff, 0xffff,
+
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0x4fb, 0x4fe, 0xffff, 0xffff,
+
+ 0xffff, 0xffff, 0xffff, 0xffff, 0x501, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0x504, 0x507, 0x50a, 0xffff, 0xffff, 0xffff,
+
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0x50d, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+
+ 0x510, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x513,
+ 0x516, 0xffff, 0x519, 0x51c, 0xffff, 0xffff, 0xffff, 0xffff,
+
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0x51f, 0x522, 0x525, 0xffff, 0xffff, 0xffff,
+
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0x528, 0xffff, 0x52b, 0x52e, 0x531, 0xffff,
+
+ 0xffff, 0xffff, 0xffff, 0x534, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+
+ 0xffff, 0xffff, 0xffff, 0x537, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0x53a, 0x53d, 0xffff, 0xffff,
+
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0x540, 0xffff, 0xffff, 0xffff,
+
+ 0xffff, 0xffff, 0xffff, 0x542, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x545, 0xffff, 0xffff,
+
+ 0xffff, 0xffff, 0x548, 0xffff, 0xffff, 0xffff, 0xffff, 0x54b,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0x54e, 0xffff, 0xffff, 0xffff,
+
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0x551, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+
+ 0xffff, 0xffff, 0xffff, 0x554, 0xffff, 0x557, 0x55a, 0x55d,
+ 0x560, 0x563, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+
+ 0xffff, 0x566, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+
+ 0xffff, 0xffff, 0xffff, 0x569, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x56c, 0xffff, 0xffff,
+
+ 0xffff, 0xffff, 0x56f, 0xffff, 0xffff, 0xffff, 0xffff, 0x572,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0x575, 0xffff, 0xffff, 0xffff,
+
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0x578, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x57b, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0x57e, 0xffff, 0xffff, 0xffff,
+
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x580, 0xffff,
+ 0x583, 0xffff, 0x586, 0xffff, 0x589, 0xffff, 0x58c, 0xffff,
+
+ 0xffff, 0xffff, 0x58f, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0x592, 0xffff, 0x595, 0xffff, 0xffff,
+
+ 0x598, 0x59b, 0xffff, 0x59e, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0x5a1, 0x5a3, 0x5a5, 0xffff,
+
+ 0x5a7, 0x5a9, 0x5ab, 0x5ad, 0x5af, 0x5b1, 0x5b3, 0x5b5,
+ 0x5b7, 0x5b9, 0x5bb, 0xffff, 0x5bd, 0x5bf, 0x5c1, 0x5c3,
+
+ 0x5c5, 0x5c7, 0x5c9, 0x5cb, 0x5cd, 0x5cf, 0x5d1, 0x5d3,
+ 0x5d5, 0x5d7, 0x5d9, 0x5db, 0x5dd, 0x5df, 0xffff, 0x5e1,
+
+ 0x5e3, 0x5e5, 0x5e7, 0x5e9, 0x5eb, 0x5ed, 0x5ef, 0x5f1,
+ 0x5f3, 0x5f5, 0x5f7, 0x5f9, 0x5fb, 0x5fd, 0x5ff, 0x601,
+
+ 0x603, 0x605, 0x607, 0x609, 0x60b, 0x60d, 0x60f, 0x611,
+ 0x613, 0x615, 0x617, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0x619, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0x61b, 0x61d, 0x61f, 0x621, 0x623,
+
+ 0x625, 0x627, 0x629, 0x62b, 0x62d, 0x62f, 0x631, 0x633,
+ 0x635, 0x637, 0x639, 0x63b, 0x63d, 0x63f, 0x641, 0x643,
+
+ 0x645, 0x647, 0x649, 0x64b, 0x64d, 0x64f, 0x651, 0x653,
+ 0x655, 0x657, 0x659, 0x65b, 0x65d, 0x65f, 0x661, 0x663,
+
+ 0x665, 0x668, 0x66b, 0x66e, 0x671, 0x674, 0x677, 0x67a,
+ 0x67d, 0x680, 0x683, 0x686, 0x689, 0x68c, 0x68f, 0x692,
+
+ 0x695, 0x698, 0x69b, 0x69e, 0x6a1, 0x6a4, 0x6a7, 0x6aa,
+ 0x6ad, 0x6b0, 0x6b3, 0x6b6, 0x6b9, 0x6bc, 0x6bf, 0x6c2,
+
+ 0x6c5, 0x6c8, 0x6cb, 0x6ce, 0x6d1, 0x6d4, 0x6d7, 0x6da,
+ 0x6dd, 0x6e0, 0x6e3, 0x6e6, 0x6e9, 0x6ec, 0x6ef, 0x6f2,
+
+ 0x6f5, 0x6f8, 0x6fb, 0x6fe, 0x701, 0x704, 0x707, 0x70a,
+ 0x70d, 0x710, 0x713, 0x716, 0x719, 0x71c, 0x71f, 0x722,
+
+ 0x725, 0x728, 0x72b, 0x72e, 0x731, 0x734, 0x737, 0x73a,
+ 0x73d, 0x740, 0x743, 0x746, 0x749, 0x74c, 0x74f, 0x752,
+
+ 0x755, 0x758, 0x75b, 0x75e, 0x761, 0x764, 0x767, 0x76a,
+ 0x76d, 0x770, 0x773, 0x776, 0x779, 0x77c, 0x77f, 0x782,
+
+ 0x785, 0x788, 0x78b, 0x78e, 0x791, 0x794, 0x797, 0x79a,
+ 0x79d, 0x7a0, 0x7a3, 0x7a6, 0x7a9, 0x7ac, 0x7af, 0x7b2,
+
+ 0x7b5, 0x7b8, 0x7bb, 0x7be, 0x7c1, 0x7c4, 0x7c7, 0x7ca,
+ 0x7cd, 0x7d0, 0x7d3, 0x7d6, 0x7d9, 0x7dc, 0x7df, 0x7e2,
+
+ 0x7e5, 0x7e8, 0x7eb, 0x7ee, 0x7f1, 0x7f4, 0x7f7, 0x7fa,
+ 0x7fd, 0x800, 0x803, 0x806, 0x809, 0x80c, 0x80f, 0x812,
+
+ 0x815, 0x818, 0x81b, 0x81e, 0x821, 0x824, 0x827, 0x82a,
+ 0x82d, 0x830, 0x833, 0x836, 0xffff, 0xffff, 0xffff, 0xffff,
+
+ 0x839, 0x83c, 0x83f, 0x842, 0x845, 0x848, 0x84b, 0x84e,
+ 0x851, 0x854, 0x857, 0x85a, 0x85d, 0x860, 0x863, 0x866,
+
+ 0x869, 0x86c, 0x86f, 0x872, 0x875, 0x878, 0x87b, 0x87e,
+ 0x881, 0x884, 0x887, 0x88a, 0x88d, 0x890, 0x893, 0x896,
+
+ 0x899, 0x89c, 0x89f, 0x8a2, 0x8a5, 0x8a8, 0x8ab, 0x8ae,
+ 0x8b1, 0x8b4, 0x8b7, 0x8ba, 0x8bd, 0x8c0, 0x8c3, 0x8c6,
+
+ 0x8c9, 0x8cc, 0x8cf, 0x8d2, 0x8d5, 0x8d8, 0x8db, 0x8de,
+ 0x8e1, 0x8e4, 0x8e7, 0x8ea, 0x8ed, 0x8f0, 0x8f3, 0x8f6,
+
+ 0x8f9, 0x8fc, 0x8ff, 0x902, 0x905, 0x908, 0x90b, 0x90e,
+ 0x911, 0x914, 0x917, 0x91a, 0x91d, 0x920, 0x923, 0x926,
+
+ 0x929, 0x92c, 0x92f, 0x932, 0x935, 0x938, 0x93b, 0x93e,
+ 0x941, 0x944, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+
+ 0x947, 0x94a, 0x94d, 0x950, 0x953, 0x956, 0x959, 0x95c,
+ 0x95f, 0x962, 0x965, 0x968, 0x96b, 0x96e, 0x971, 0x974,
+
+ 0x977, 0x97a, 0x97d, 0x980, 0x983, 0x986, 0xffff, 0xffff,
+ 0x989, 0x98c, 0x98f, 0x992, 0x995, 0x998, 0xffff, 0xffff,
+
+ 0x99b, 0x99e, 0x9a1, 0x9a4, 0x9a7, 0x9aa, 0x9ad, 0x9b0,
+ 0x9b3, 0x9b6, 0x9b9, 0x9bc, 0x9bf, 0x9c2, 0x9c5, 0x9c8,
+
+ 0x9cb, 0x9ce, 0x9d1, 0x9d4, 0x9d7, 0x9da, 0x9dd, 0x9e0,
+ 0x9e3, 0x9e6, 0x9e9, 0x9ec, 0x9ef, 0x9f2, 0x9f5, 0x9f8,
+
+ 0x9fb, 0x9fe, 0xa01, 0xa04, 0xa07, 0xa0a, 0xffff, 0xffff,
+ 0xa0d, 0xa10, 0xa13, 0xa16, 0xa19, 0xa1c, 0xffff, 0xffff,
+
+ 0xa1f, 0xa22, 0xa25, 0xa28, 0xa2b, 0xa2e, 0xa31, 0xa34,
+ 0xffff, 0xa37, 0xffff, 0xa3a, 0xffff, 0xa3d, 0xffff, 0xa40,
+
+ 0xa43, 0xa46, 0xa49, 0xa4c, 0xa4f, 0xa52, 0xa55, 0xa58,
+ 0xa5b, 0xa5e, 0xa61, 0xa64, 0xa67, 0xa6a, 0xa6d, 0xa70,
+
+ 0xa73, 0xa76, 0xa78, 0xa7b, 0xa7d, 0xa80, 0xa82, 0xa85,
+ 0xa87, 0xa8a, 0xa8c, 0xa8f, 0xa91, 0xa94, 0xffff, 0xffff,
+
+ 0xa96, 0xa99, 0xa9c, 0xa9f, 0xaa2, 0xaa5, 0xaa8, 0xaab,
+ 0xaae, 0xab1, 0xab4, 0xab7, 0xaba, 0xabd, 0xac0, 0xac3,
+
+ 0xac6, 0xac9, 0xacc, 0xacf, 0xad2, 0xad5, 0xad8, 0xadb,
+ 0xade, 0xae1, 0xae4, 0xae7, 0xaea, 0xaed, 0xaf0, 0xaf3,
+
+ 0xaf6, 0xaf9, 0xafc, 0xaff, 0xb02, 0xb05, 0xb08, 0xb0b,
+ 0xb0e, 0xb11, 0xb14, 0xb17, 0xb1a, 0xb1d, 0xb20, 0xb23,
+
+ 0xb26, 0xb29, 0xb2c, 0xb2f, 0xb32, 0xffff, 0xb35, 0xb38,
+ 0xb3b, 0xb3e, 0xb41, 0xb44, 0xb46, 0xb49, 0xb4c, 0xb4e,
+
+ 0xb51, 0xb54, 0xb57, 0xb5a, 0xb5d, 0xffff, 0xb60, 0xb63,
+ 0xb66, 0xb69, 0xb6b, 0xb6e, 0xb70, 0xb73, 0xb76, 0xb79,
+
+ 0xb7c, 0xb7f, 0xb82, 0xb85, 0xffff, 0xffff, 0xb87, 0xb8a,
+ 0xb8d, 0xb90, 0xb93, 0xb96, 0xffff, 0xb98, 0xb9b, 0xb9e,
+
+ 0xba1, 0xba4, 0xba7, 0xbaa, 0xbac, 0xbaf, 0xbb2, 0xbb5,
+ 0xbb8, 0xbbb, 0xbbe, 0xbc1, 0xbc3, 0xbc6, 0xbc9, 0xbcb,
+
+ 0xffff, 0xffff, 0xbcd, 0xbd0, 0xbd3, 0xffff, 0xbd6, 0xbd9,
+ 0xbdc, 0xbdf, 0xbe1, 0xbe4, 0xbe6, 0xbe9, 0xbeb, 0xffff,
+
+ 0xbee, 0xbf0, 0xbf2, 0xbf4, 0xbf6, 0xbf8, 0xbfa, 0xbfc,
+ 0xbfe, 0xc00, 0xc02, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+
+ 0xffff, 0xc04, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xc06,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xc09, 0xc0b, 0xc0e, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xc12,
+
+ 0xffff, 0xffff, 0xffff, 0xc14, 0xc17, 0xffff, 0xc1b, 0xc1e,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xc22, 0xffff, 0xc25, 0xffff,
+
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xc28,
+ 0xc2b, 0xc2e, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xc31,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xc36,
+
+ 0xc38, 0xc3a, 0xffff, 0xffff, 0xc3c, 0xc3e, 0xc40, 0xc42,
+ 0xc44, 0xc46, 0xc48, 0xc4a, 0xc4c, 0xc4e, 0xc50, 0xc52,
+
+ 0xc54, 0xc56, 0xc58, 0xc5a, 0xc5c, 0xc5e, 0xc60, 0xc62,
+ 0xc64, 0xc66, 0xc68, 0xc6a, 0xc6c, 0xc6e, 0xc70, 0xffff,
+
+ 0xc72, 0xc74, 0xc76, 0xc78, 0xc7a, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xc7c, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+
+ 0xc7f, 0xc83, 0xc87, 0xc89, 0xffff, 0xc8c, 0xc90, 0xc94,
+ 0xffff, 0xc96, 0xc99, 0xc9b, 0xc9d, 0xc9f, 0xca1, 0xca3,
+
+ 0xca5, 0xca7, 0xca9, 0xcab, 0xffff, 0xcad, 0xcaf, 0xffff,
+ 0xffff, 0xcb2, 0xcb4, 0xcb6, 0xcb8, 0xcba, 0xffff, 0xffff,
+
+ 0xcbc, 0xcbf, 0xcc3, 0xffff, 0xcc6, 0xffff, 0xcc8, 0xffff,
+ 0xcca, 0xffff, 0xccc, 0xcce, 0xcd0, 0xcd2, 0xffff, 0xcd4,
+
+ 0xcd6, 0xcd8, 0xffff, 0xcda, 0xcdc, 0xcde, 0xce0, 0xce2,
+ 0xce4, 0xce6, 0xffff, 0xce8, 0xcec, 0xcee, 0xcf0, 0xcf2,
+
+ 0xcf4, 0xffff, 0xffff, 0xffff, 0xffff, 0xcf6, 0xcf8, 0xcfa,
+ 0xcfc, 0xcfe, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+
+ 0xffff, 0xffff, 0xffff, 0xd00, 0xd04, 0xd08, 0xd0c, 0xd10,
+ 0xd14, 0xd18, 0xd1c, 0xd20, 0xd24, 0xd28, 0xd2c, 0xd30,
+
+ 0xd33, 0xd35, 0xd38, 0xd3c, 0xd3f, 0xd41, 0xd44, 0xd48,
+ 0xd4d, 0xd50, 0xd52, 0xd55, 0xd59, 0xd5b, 0xd5d, 0xd5f,
+
+ 0xd61, 0xd63, 0xd66, 0xd6a, 0xd6d, 0xd6f, 0xd72, 0xd76,
+ 0xd7b, 0xd7e, 0xd80, 0xd83, 0xd87, 0xd89, 0xd8b, 0xd8d,
+
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xd8f, 0xd92, 0xffff, 0xffff, 0xffff, 0xffff,
+
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xd95, 0xffff,
+
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xd98, 0xd9b, 0xd9e,
+
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xda1, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xda4, 0xffff, 0xffff, 0xda7, 0xffff, 0xffff, 0xffff,
+
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xdaa, 0xffff, 0xdad, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xdb0, 0xdb3, 0xffff, 0xdb7,
+
+ 0xdba, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+
+ 0xffff, 0xdbe, 0xffff, 0xffff, 0xdc1, 0xffff, 0xffff, 0xdc4,
+ 0xffff, 0xdc7, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+
+ 0xdca, 0xffff, 0xdcd, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xdd0, 0xdd3, 0xdd6,
+
+ 0xdd9, 0xddc, 0xffff, 0xffff, 0xddf, 0xde2, 0xffff, 0xffff,
+ 0xde5, 0xde8, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+
+ 0xdeb, 0xdee, 0xffff, 0xffff, 0xdf1, 0xdf4, 0xffff, 0xffff,
+ 0xdf7, 0xdfa, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xdfd, 0xe00, 0xe03, 0xe06,
+
+ 0xe09, 0xe0c, 0xe0f, 0xe12, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xe15, 0xe18, 0xe1b, 0xe1e, 0xffff, 0xffff,
+
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xe21, 0xe23, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+
+ 0xe25, 0xe27, 0xe29, 0xe2b, 0xe2d, 0xe2f, 0xe31, 0xe33,
+ 0xe35, 0xe37, 0xe3a, 0xe3d, 0xe40, 0xe43, 0xe46, 0xe49,
+
+ 0xe4c, 0xe4f, 0xe52, 0xe55, 0xe58, 0xe5c, 0xe60, 0xe64,
+ 0xe68, 0xe6c, 0xe70, 0xe74, 0xe78, 0xe7c, 0xe81, 0xe86,
+
+ 0xe8b, 0xe90, 0xe95, 0xe9a, 0xe9f, 0xea4, 0xea9, 0xeae,
+ 0xeb3, 0xeb6, 0xeb9, 0xebc, 0xebf, 0xec2, 0xec5, 0xec8,
+
+ 0xecb, 0xece, 0xed2, 0xed6, 0xeda, 0xede, 0xee2, 0xee6,
+ 0xeea, 0xeee, 0xef2, 0xef6, 0xefa, 0xefe, 0xf02, 0xf06,
+
+ 0xf0a, 0xf0e, 0xf12, 0xf16, 0xf1a, 0xf1e, 0xf22, 0xf26,
+ 0xf2a, 0xf2e, 0xf32, 0xf36, 0xf3a, 0xf3e, 0xf42, 0xf46,
+
+ 0xf4a, 0xf4e, 0xf52, 0xf56, 0xf5a, 0xf5e, 0xf62, 0xf64,
+ 0xf66, 0xf68, 0xf6a, 0xf6c, 0xf6e, 0xf70, 0xf72, 0xf74,
+
+ 0xf76, 0xf78, 0xf7a, 0xf7c, 0xf7e, 0xf80, 0xf82, 0xf84,
+ 0xf86, 0xf88, 0xf8a, 0xf8c, 0xf8e, 0xf90, 0xf92, 0xf94,
+
+ 0xf96, 0xf98, 0xf9a, 0xf9c, 0xf9e, 0xfa0, 0xfa2, 0xfa4,
+ 0xfa6, 0xfa8, 0xfaa, 0xfac, 0xfae, 0xfb0, 0xfb2, 0xfb4,
+
+ 0xfb6, 0xfb8, 0xfba, 0xfbc, 0xfbe, 0xfc0, 0xfc2, 0xfc4,
+ 0xfc6, 0xfc8, 0xfca, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xfcc, 0xffff, 0xffff, 0xffff,
+
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xfd1, 0xfd5, 0xfd8, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xfdc, 0xffff, 0xffff, 0xffff,
+
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xfdf,
+
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xfe1,
+
+ 0xffff, 0xffff, 0xffff, 0xfe3, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+
+ 0xfe5, 0xfe7, 0xfe9, 0xfeb, 0xfed, 0xfef, 0xff1, 0xff3,
+ 0xff5, 0xff7, 0xff9, 0xffb, 0xffd, 0xfff, 0x1001, 0x1003,
+
+ 0x1005, 0x1007, 0x1009, 0x100b, 0x100d, 0x100f, 0x1011, 0x1013,
+ 0x1015, 0x1017, 0x1019, 0x101b, 0x101d, 0x101f, 0x1021, 0x1023,
+
+ 0x1025, 0x1027, 0x1029, 0x102b, 0x102d, 0x102f, 0x1031, 0x1033,
+ 0x1035, 0x1037, 0x1039, 0x103b, 0x103d, 0x103f, 0x1041, 0x1043,
+
+ 0x1045, 0x1047, 0x1049, 0x104b, 0x104d, 0x104f, 0x1051, 0x1053,
+ 0x1055, 0x1057, 0x1059, 0x105b, 0x105d, 0x105f, 0x1061, 0x1063,
+
+ 0x1065, 0x1067, 0x1069, 0x106b, 0x106d, 0x106f, 0x1071, 0x1073,
+ 0x1075, 0x1077, 0x1079, 0x107b, 0x107d, 0x107f, 0x1081, 0x1083,
+
+ 0x1085, 0x1087, 0x1089, 0x108b, 0x108d, 0x108f, 0x1091, 0x1093,
+ 0x1095, 0x1097, 0x1099, 0x109b, 0x109d, 0x109f, 0x10a1, 0x10a3,
+
+ 0x10a5, 0x10a7, 0x10a9, 0x10ab, 0x10ad, 0x10af, 0x10b1, 0x10b3,
+ 0x10b5, 0x10b7, 0x10b9, 0x10bb, 0x10bd, 0x10bf, 0x10c1, 0x10c3,
+
+ 0x10c5, 0x10c7, 0x10c9, 0x10cb, 0x10cd, 0x10cf, 0x10d1, 0x10d3,
+ 0x10d5, 0x10d7, 0x10d9, 0x10db, 0x10dd, 0x10df, 0x10e1, 0x10e3,
+
+ 0x10e5, 0x10e7, 0x10e9, 0x10eb, 0x10ed, 0x10ef, 0x10f1, 0x10f3,
+ 0x10f5, 0x10f7, 0x10f9, 0x10fb, 0x10fd, 0x10ff, 0x1101, 0x1103,
+
+ 0x1105, 0x1107, 0x1109, 0x110b, 0x110d, 0x110f, 0x1111, 0x1113,
+ 0x1115, 0x1117, 0x1119, 0x111b, 0x111d, 0x111f, 0x1121, 0x1123,
+
+ 0x1125, 0x1127, 0x1129, 0x112b, 0x112d, 0x112f, 0x1131, 0x1133,
+ 0x1135, 0x1137, 0x1139, 0x113b, 0x113d, 0x113f, 0x1141, 0x1143,
+
+ 0x1145, 0x1147, 0x1149, 0x114b, 0x114d, 0x114f, 0x1151, 0x1153,
+ 0x1155, 0x1157, 0x1159, 0x115b, 0x115d, 0x115f, 0x1161, 0x1163,
+
+ 0x1165, 0x1167, 0x1169, 0x116b, 0x116d, 0x116f, 0x1171, 0x1173,
+ 0x1175, 0x1177, 0x1179, 0x117b, 0x117d, 0x117f, 0x1181, 0x1183,
+
+ 0x1185, 0x1187, 0x1189, 0x118b, 0x118d, 0x118f, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+
+ 0x1191, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x1193, 0xffff,
+ 0x1195, 0x1197, 0x1199, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0x119b, 0xffff, 0x119e, 0xffff,
+
+ 0x11a1, 0xffff, 0x11a4, 0xffff, 0x11a7, 0xffff, 0x11aa, 0xffff,
+ 0x11ad, 0xffff, 0x11b0, 0xffff, 0x11b3, 0xffff, 0x11b6, 0xffff,
+
+ 0x11b9, 0xffff, 0x11bc, 0xffff, 0xffff, 0x11bf, 0xffff, 0x11c2,
+ 0xffff, 0x11c5, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+
+ 0x11c8, 0x11cb, 0xffff, 0x11ce, 0x11d1, 0xffff, 0x11d4, 0x11d7,
+ 0xffff, 0x11da, 0x11dd, 0xffff, 0x11e0, 0x11e3, 0xffff, 0xffff,
+
+ 0xffff, 0xffff, 0xffff, 0xffff, 0x11e6, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0x11e9, 0x11ec, 0xffff, 0x11ef, 0x11f2,
+
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0x11f5, 0xffff, 0x11f8, 0xffff,
+
+ 0x11fb, 0xffff, 0x11fe, 0xffff, 0x1201, 0xffff, 0x1204, 0xffff,
+ 0x1207, 0xffff, 0x120a, 0xffff, 0x120d, 0xffff, 0x1210, 0xffff,
+
+ 0x1213, 0xffff, 0x1216, 0xffff, 0xffff, 0x1219, 0xffff, 0x121c,
+ 0xffff, 0x121f, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+
+ 0x1222, 0x1225, 0xffff, 0x1228, 0x122b, 0xffff, 0x122e, 0x1231,
+ 0xffff, 0x1234, 0x1237, 0xffff, 0x123a, 0x123d, 0xffff, 0xffff,
+
+ 0xffff, 0xffff, 0xffff, 0xffff, 0x1240, 0xffff, 0xffff, 0x1243,
+ 0x1246, 0x1249, 0x124c, 0xffff, 0xffff, 0xffff, 0x124f, 0x1252,
+
+ 0xffff, 0x1255, 0x1257, 0x1259, 0x125b, 0x125d, 0x125f, 0x1261,
+ 0x1263, 0x1265, 0x1267, 0x1269, 0x126b, 0x126d, 0x126f, 0x1271,
+
+ 0x1273, 0x1275, 0x1277, 0x1279, 0x127b, 0x127d, 0x127f, 0x1281,
+ 0x1283, 0x1285, 0x1287, 0x1289, 0x128b, 0x128d, 0x128f, 0x1291,
+
+ 0x1293, 0x1295, 0x1297, 0x1299, 0x129b, 0x129d, 0x129f, 0x12a1,
+ 0x12a3, 0x12a5, 0x12a7, 0x12a9, 0x12ab, 0x12ad, 0x12af, 0x12b1,
+
+ 0x12b3, 0x12b5, 0x12b7, 0x12b9, 0x12bb, 0x12bd, 0x12bf, 0x12c1,
+ 0x12c3, 0x12c5, 0x12c7, 0x12c9, 0x12cb, 0x12cd, 0x12cf, 0x12d1,
+
+ 0x12d3, 0x12d5, 0x12d7, 0x12d9, 0x12db, 0x12dd, 0x12df, 0x12e1,
+ 0x12e3, 0x12e5, 0x12e7, 0x12e9, 0x12eb, 0x12ed, 0x12ef, 0x12f1,
+
+ 0x12f3, 0x12f5, 0x12f7, 0x12f9, 0x12fb, 0x12fd, 0x12ff, 0x1301,
+ 0x1303, 0x1305, 0x1307, 0x1309, 0x130b, 0x130d, 0x130f, 0xffff,
+
+ 0xffff, 0xffff, 0x1311, 0x1313, 0x1315, 0x1317, 0x1319, 0x131b,
+ 0x131d, 0x131f, 0x1321, 0x1323, 0x1325, 0x1327, 0x1329, 0x132b,
+
+ 0x132d, 0x1331, 0x1335, 0x1339, 0x133d, 0x1341, 0x1345, 0x1349,
+ 0x134d, 0x1351, 0x1355, 0x1359, 0x135d, 0x1361, 0x1365, 0x136a,
+
+ 0x136f, 0x1374, 0x1379, 0x137e, 0x1383, 0x1388, 0x138d, 0x1392,
+ 0x1397, 0x139c, 0x13a1, 0x13a6, 0x13ab, 0x13b0, 0x13b8, 0xffff,
+
+ 0x13bf, 0x13c3, 0x13c7, 0x13cb, 0x13cf, 0x13d3, 0x13d7, 0x13db,
+ 0x13df, 0x13e3, 0x13e7, 0x13eb, 0x13ef, 0x13f3, 0x13f7, 0x13fb,
+
+ 0x13ff, 0x1403, 0x1407, 0x140b, 0x140f, 0x1413, 0x1417, 0x141b,
+ 0x141f, 0x1423, 0x1427, 0x142b, 0x142f, 0x1433, 0x1437, 0x143b,
+
+ 0x143f, 0x1443, 0x1447, 0x144b, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+
+ 0x144f, 0x1453, 0x1456, 0x1459, 0x145c, 0x145f, 0x1462, 0x1465,
+ 0x1468, 0x146b, 0x146e, 0x1471, 0x1474, 0x1477, 0x147a, 0x147d,
+
+ 0x1480, 0x1482, 0x1484, 0x1486, 0x1488, 0x148a, 0x148c, 0x148e,
+ 0x1490, 0x1492, 0x1494, 0x1496, 0x1498, 0x149a, 0x149c, 0x149f,
+
+ 0x14a2, 0x14a5, 0x14a8, 0x14ab, 0x14ae, 0x14b1, 0x14b4, 0x14b7,
+ 0x14ba, 0x14bd, 0x14c0, 0x14c3, 0x14c6, 0x14cc, 0x14d1, 0xffff,
+
+ 0x14d4, 0x14d6, 0x14d8, 0x14da, 0x14dc, 0x14de, 0x14e0, 0x14e2,
+ 0x14e4, 0x14e6, 0x14e8, 0x14ea, 0x14ec, 0x14ee, 0x14f0, 0x14f2,
+
+ 0x14f4, 0x14f6, 0x14f8, 0x14fa, 0x14fc, 0x14fe, 0x1500, 0x1502,
+ 0x1504, 0x1506, 0x1508, 0x150a, 0x150c, 0x150e, 0x1510, 0x1512,
+
+ 0x1514, 0x1516, 0x1518, 0x151a, 0x151c, 0x151e, 0x1520, 0x1522,
+ 0x1524, 0x1526, 0x1528, 0x152a, 0x152c, 0x152e, 0x1530, 0x1532,
+
+ 0x1534, 0x1536, 0x1539, 0x153c, 0x153f, 0x1542, 0x1545, 0x1548,
+ 0x154b, 0x154e, 0x1551, 0x1554, 0x1557, 0x155a, 0x155d, 0x1560,
+
+ 0x1563, 0x1566, 0x1569, 0x156c, 0x156f, 0x1572, 0x1575, 0x1578,
+ 0x157b, 0x157e, 0x1582, 0x1586, 0x158a, 0x158d, 0x1591, 0x1594,
+
+ 0x1598, 0x159a, 0x159c, 0x159e, 0x15a0, 0x15a2, 0x15a4, 0x15a6,
+ 0x15a8, 0x15aa, 0x15ac, 0x15ae, 0x15b0, 0x15b2, 0x15b4, 0x15b6,
+
+ 0x15b8, 0x15ba, 0x15bc, 0x15be, 0x15c0, 0x15c2, 0x15c4, 0x15c6,
+ 0x15c8, 0x15ca, 0x15cc, 0x15ce, 0x15d0, 0x15d2, 0x15d4, 0x15d6,
+
+ 0x15d8, 0x15da, 0x15dc, 0x15de, 0x15e0, 0x15e2, 0x15e4, 0x15e6,
+ 0x15e8, 0x15ea, 0x15ec, 0x15ee, 0x15f0, 0x15f2, 0x15f4, 0xffff,
+
+ 0x15f6, 0x15fb, 0x1600, 0x1605, 0x1609, 0x160e, 0x1612, 0x1616,
+ 0x161c, 0x1621, 0x1625, 0x1629, 0x162d, 0x1632, 0x1637, 0x163b,
+
+ 0x163f, 0x1642, 0x1646, 0x164b, 0x1650, 0x1653, 0x1659, 0x1660,
+ 0x1666, 0x166a, 0x1670, 0x1676, 0x167b, 0x167f, 0x1683, 0x1687,
+
+ 0x168c, 0x1692, 0x1697, 0x169b, 0x169f, 0x16a3, 0x16a6, 0x16a9,
+ 0x16ac, 0x16af, 0x16b3, 0x16b7, 0x16bd, 0x16c1, 0x16c6, 0x16cc,
+
+ 0x16d0, 0x16d3, 0x16d6, 0x16dc, 0x16e1, 0x16e7, 0x16eb, 0x16f1,
+ 0x16f4, 0x16f8, 0x16fc, 0x1700, 0x1704, 0x1708, 0x170d, 0x1711,
+
+ 0x1714, 0x1718, 0x171c, 0x1720, 0x1725, 0x1729, 0x172d, 0x1731,
+ 0x1737, 0x173c, 0x173f, 0x1745, 0x1748, 0x174d, 0x1752, 0x1756,
+
+ 0x175a, 0x175e, 0x1763, 0x1766, 0x176a, 0x176f, 0x1772, 0x1778,
+ 0x177c, 0x177f, 0x1782, 0x1785, 0x1788, 0x178b, 0x178e, 0x1791,
+
+ 0x1794, 0x1797, 0x179a, 0x179e, 0x17a2, 0x17a6, 0x17aa, 0x17ae,
+ 0x17b2, 0x17b6, 0x17ba, 0x17be, 0x17c2, 0x17c6, 0x17ca, 0x17ce,
+
+ 0x17d2, 0x17d6, 0x17da, 0x17dd, 0x17e0, 0x17e4, 0x17e7, 0x17ea,
+ 0x17ed, 0x17f1, 0x17f5, 0x17f8, 0x17fb, 0x17fe, 0x1801, 0x1804,
+
+ 0x1809, 0x180c, 0x180f, 0x1812, 0x1815, 0x1818, 0x181b, 0x181e,
+ 0x1821, 0x1825, 0x182a, 0x182d, 0x1830, 0x1833, 0x1836, 0x1839,
+
+ 0x183c, 0x183f, 0x1843, 0x1847, 0x184b, 0x184f, 0x1852, 0x1855,
+ 0x1858, 0x185b, 0x185e, 0x1861, 0x1864, 0x1867, 0x186a, 0x186d,
+
+ 0x1871, 0x1875, 0x1878, 0x187c, 0x1880, 0x1884, 0x1887, 0x188b,
+ 0x188f, 0x1894, 0x1897, 0x189b, 0x189f, 0x18a3, 0x18a7, 0x18ad,
+
+ 0x18b4, 0x18b7, 0x18ba, 0x18bd, 0x18c0, 0x18c3, 0x18c6, 0x18c9,
+ 0x18cc, 0x18cf, 0x18d2, 0x18d5, 0x18d8, 0x18db, 0x18de, 0x18e1,
+
+ 0x18e4, 0x18e7, 0x18ea, 0x18ef, 0x18f2, 0x18f5, 0x18f8, 0x18fd,
+ 0x1901, 0x1904, 0x1907, 0x190a, 0x190d, 0x1910, 0x1913, 0x1916,
+
+ 0x1919, 0x191c, 0x191f, 0x1923, 0x1926, 0x1929, 0x192d, 0x1931,
+ 0x1934, 0x1939, 0x193d, 0x1940, 0x1943, 0x1946, 0x1949, 0x194d,
+
+ 0x1951, 0x1954, 0x1957, 0x195a, 0x195d, 0x1960, 0x1963, 0x1966,
+ 0x1969, 0x196c, 0x1970, 0x1974, 0x1978, 0x197c, 0x1980, 0x1984,
+
+ 0x1988, 0x198c, 0x1990, 0x1994, 0x1998, 0x199c, 0x19a0, 0x19a4,
+ 0x19a8, 0x19ac, 0x19b0, 0x19b4, 0x19b8, 0x19bc, 0x19c0, 0x19c4,
+
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+
+ 0x19c8, 0x19ca, 0x19cc, 0x19ce, 0x19d0, 0x19d2, 0x19d4, 0x19d6,
+ 0x19d8, 0x19da, 0x19dc, 0x19de, 0x19e0, 0x19e2, 0x19e4, 0x19e6,
+ 0x19e8, 0x19ea, 0x19ec, 0x19ee, 0x19f0, 0x19f2, 0x19f4, 0x19f6,
+ 0x19f8, 0x19fa, 0x19fc, 0x19fe, 0x1a00, 0x1a02, 0x1a04, 0x1a06,
+ 0x1a08, 0x1a0a, 0x1a0c, 0x1a0e, 0x1a10, 0x1a12, 0x1a14, 0x1a16,
+ 0x1a18, 0x1a1a, 0x1a1c, 0x1a1e, 0x1a20, 0x1a22, 0x1a24, 0x1a26,
+ 0x1a28, 0x1a2a, 0x1a2c, 0x1a2e, 0x1a30, 0x1a32, 0x1a34, 0x1a36,
+ 0x1a38, 0x1a3a, 0x1a3c, 0x1a3e, 0x1a40, 0x1a42, 0x1a44, 0x1a46,
+ 0x1a48, 0x1a4a, 0x1a4c, 0x1a4e, 0x1a50, 0x1a52, 0x1a54, 0x1a56,
+ 0x1a58, 0x1a5a, 0x1a5c, 0x1a5e, 0x1a60, 0x1a62, 0x1a64, 0x1a66,
+ 0x1a68, 0x1a6a, 0x1a6c, 0x1a6e, 0x1a70, 0x1a72, 0x1a74, 0x1a76,
+ 0x1a78, 0x1a7a, 0x1a7c, 0x1a7e, 0x1a80, 0x1a82, 0x1a84, 0x1a86,
+ 0x1a88, 0x1a8a, 0x1a8c, 0x1a8e, 0x1a90, 0x1a92, 0x1a94, 0x1a96,
+ 0x1a98, 0x1a9a, 0x1a9c, 0x1a9e, 0x1aa0, 0x1aa2, 0x1aa4, 0x1aa6,
+ 0x1aa8, 0x1aaa, 0x1aac, 0x1aae, 0x1ab0, 0x1ab2, 0x1ab4, 0x1ab6,
+ 0x1ab8, 0x1aba, 0x1abc, 0x1abe, 0x1ac0, 0x1ac2, 0x1ac4, 0x1ac6,
+ 0x1ac8, 0x1aca, 0x1acc, 0x1ace, 0x1ad0, 0x1ad2, 0x1ad4, 0x1ad6,
+ 0x1ad8, 0x1ada, 0x1adc, 0x1ade, 0x1ae0, 0x1ae2, 0x1ae4, 0x1ae6,
+ 0x1ae8, 0x1aea, 0x1aec, 0x1aee, 0x1af0, 0x1af2, 0x1af4, 0x1af6,
+ 0x1af8, 0x1afa, 0x1afc, 0x1afe, 0x1b00, 0x1b02, 0x1b04, 0x1b06,
+ 0x1b08, 0x1b0a, 0x1b0c, 0x1b0e, 0x1b10, 0x1b12, 0x1b14, 0x1b16,
+ 0x1b18, 0x1b1a, 0x1b1c, 0x1b1e, 0x1b20, 0x1b22, 0x1b24, 0x1b26,
+ 0x1b28, 0x1b2a, 0x1b2c, 0x1b2e, 0x1b30, 0x1b32, 0x1b34, 0x1b36,
+ 0x1b38, 0x1b3a, 0x1b3c, 0x1b3e, 0x1b40, 0x1b42, 0x1b44, 0x1b46,
+ 0x1b48, 0x1b4a, 0x1b4c, 0x1b4e, 0x1b50, 0x1b52, 0x1b54, 0x1b56,
+ 0x1b58, 0x1b5a, 0x1b5c, 0x1b5e, 0x1b60, 0x1b62, 0x1b64, 0x1b66,
+ 0x1b68, 0x1b6a, 0x1b6c, 0x1b6e, 0x1b70, 0x1b72, 0x1b74, 0x1b76,
+ 0x1b78, 0x1b7a, 0x1b7c, 0x1b7e, 0x1b80, 0x1b82, 0x1b84, 0x1b86,
+ 0x1b88, 0x1b8a, 0x1b8c, 0x1b8e, 0x1b90, 0x1b92, 0x1b94, 0x1b96,
+ 0x1b98, 0x1b9a, 0x1b9c, 0x1b9e, 0x1ba0, 0x1ba2, 0x1ba4, 0x1ba6,
+ 0x1ba8, 0x1baa, 0x1bac, 0x1bae, 0x1bb0, 0x1bb2, 0x1bb4, 0x1bb6,
+ 0x1bb8, 0x1bba, 0x1bbc, 0x1bbe, 0x1bc0, 0x1bc2, 0x1bc4, 0x1bc6,
+
+ 0x1bc8, 0x1bca, 0x1bcc, 0x1bce, 0x1bd0, 0x1bd2, 0x1bd4, 0x1bd6,
+ 0x1bd8, 0x1bda, 0x1bdc, 0x1bde, 0x1be0, 0x1be2, 0xffff, 0xffff,
+ 0x1be4, 0xffff, 0x1be6, 0xffff, 0xffff, 0x1be8, 0x1bea, 0x1bec,
+ 0x1bee, 0x1bf0, 0x1bf2, 0x1bf4, 0x1bf6, 0x1bf8, 0x1bfa, 0xffff,
+ 0x1bfc, 0xffff, 0x1bfe, 0xffff, 0xffff, 0x1c00, 0x1c02, 0xffff,
+ 0xffff, 0xffff, 0x1c04, 0x1c06, 0x1c08, 0x1c0a, 0xffff, 0xffff,
+ 0x1c0c, 0x1c0e, 0x1c10, 0x1c12, 0x1c14, 0x1c16, 0x1c18, 0x1c1a,
+ 0x1c1c, 0x1c1e, 0x1c20, 0x1c22, 0x1c24, 0x1c26, 0x1c28, 0x1c2a,
+ 0x1c2c, 0x1c2e, 0x1c30, 0x1c32, 0x1c34, 0x1c36, 0x1c38, 0x1c3a,
+ 0x1c3c, 0x1c3e, 0x1c40, 0x1c42, 0x1c44, 0x1c46, 0x1c48, 0x1c4a,
+ 0x1c4c, 0x1c4e, 0x1c50, 0x1c52, 0x1c54, 0x1c56, 0x1c58, 0x1c5a,
+ 0x1c5c, 0x1c5e, 0x1c60, 0x1c62, 0x1c64, 0x1c66, 0x1c68, 0x1c6a,
+ 0x1c6c, 0x1c6e, 0x1c70, 0x1c72, 0x1c74, 0x1c76, 0x1c78, 0x1c7a,
+ 0x1c7c, 0x1c7e, 0x1c80, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0x1c82, 0x1c84, 0x1c86, 0x1c88, 0x1c8a, 0x1c8c, 0x1c8e, 0x1c90,
+ 0x1c92, 0x1c94, 0x1c96, 0x1c98, 0x1c9a, 0x1c9c, 0x1c9e, 0x1ca0,
+ 0x1ca2, 0x1ca4, 0x1ca6, 0x1ca8, 0x1caa, 0x1cac, 0x1cae, 0x1cb0,
+ 0x1cb2, 0x1cb4, 0x1cb6, 0x1cb8, 0x1cba, 0x1cbc, 0x1cbe, 0x1cc0,
+ 0x1cc2, 0x1cc4, 0x1cc6, 0x1cc8, 0x1cca, 0x1ccc, 0x1cce, 0x1cd0,
+ 0x1cd2, 0x1cd4, 0x1cd6, 0x1cd8, 0x1cda, 0x1cdc, 0x1cde, 0x1ce0,
+ 0x1ce2, 0x1ce4, 0x1ce6, 0x1ce8, 0x1cea, 0x1cec, 0x1cee, 0x1cf0,
+ 0x1cf2, 0x1cf4, 0x1cf6, 0x1cf8, 0x1cfa, 0x1cfc, 0x1cfe, 0x1d00,
+ 0x1d02, 0x1d04, 0x1d06, 0x1d08, 0x1d0a, 0x1d0c, 0x1d0e, 0x1d10,
+ 0x1d12, 0x1d14, 0x1d16, 0x1d18, 0x1d1a, 0x1d1c, 0x1d1e, 0x1d20,
+ 0x1d22, 0x1d24, 0x1d26, 0x1d28, 0x1d2a, 0x1d2c, 0x1d2e, 0x1d30,
+ 0x1d32, 0x1d34, 0x1d36, 0x1d38, 0x1d3a, 0x1d3c, 0x1d3e, 0x1d40,
+ 0x1d43, 0x1d46, 0x1d49, 0x1d4b, 0x1d4d, 0x1d4f, 0x1d52, 0x1d55,
+ 0x1d58, 0x1d5a, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+
+ 0x1d5c, 0x1d5f, 0x1d62, 0x1d65, 0x1d69, 0x1d6d, 0x1d70, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0x1d73, 0x1d76, 0x1d79, 0x1d7c, 0x1d7f,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x1d82, 0xffff, 0x1d85,
+ 0x1d88, 0x1d8a, 0x1d8c, 0x1d8e, 0x1d90, 0x1d92, 0x1d94, 0x1d96,
+ 0x1d98, 0x1d9a, 0x1d9c, 0x1d9f, 0x1da2, 0x1da5, 0x1da8, 0x1dab,
+ 0x1dae, 0x1db1, 0x1db4, 0x1db7, 0x1dba, 0x1dbd, 0x1dc0, 0xffff,
+ 0x1dc3, 0x1dc6, 0x1dc9, 0x1dcc, 0x1dcf, 0xffff, 0x1dd2, 0xffff,
+ 0x1dd5, 0x1dd8, 0xffff, 0x1ddb, 0x1dde, 0xffff, 0x1de1, 0x1de4,
+ 0x1de7, 0x1dea, 0x1ded, 0x1df0, 0x1df3, 0x1df6, 0x1df9, 0x1dfc,
+ 0x1dff, 0x1e01, 0x1e03, 0x1e05, 0x1e07, 0x1e09, 0x1e0b, 0x1e0d,
+ 0x1e0f, 0x1e11, 0x1e13, 0x1e15, 0x1e17, 0x1e19, 0x1e1b, 0x1e1d,
+ 0x1e1f, 0x1e21, 0x1e23, 0x1e25, 0x1e27, 0x1e29, 0x1e2b, 0x1e2d,
+ 0x1e2f, 0x1e31, 0x1e33, 0x1e35, 0x1e37, 0x1e39, 0x1e3b, 0x1e3d,
+ 0x1e3f, 0x1e41, 0x1e43, 0x1e45, 0x1e47, 0x1e49, 0x1e4b, 0x1e4d,
+ 0x1e4f, 0x1e51, 0x1e53, 0x1e55, 0x1e57, 0x1e59, 0x1e5b, 0x1e5d,
+ 0x1e5f, 0x1e61, 0x1e63, 0x1e65, 0x1e67, 0x1e69, 0x1e6b, 0x1e6d,
+ 0x1e6f, 0x1e71, 0x1e73, 0x1e75, 0x1e77, 0x1e79, 0x1e7b, 0x1e7d,
+ 0x1e7f, 0x1e81, 0x1e83, 0x1e85, 0x1e87, 0x1e89, 0x1e8b, 0x1e8d,
+ 0x1e8f, 0x1e91, 0x1e93, 0x1e95, 0x1e97, 0x1e99, 0x1e9b, 0x1e9d,
+ 0x1e9f, 0x1ea1, 0x1ea3, 0x1ea5, 0x1ea7, 0x1ea9, 0x1eab, 0x1ead,
+ 0x1eaf, 0x1eb1, 0x1eb3, 0x1eb5, 0x1eb7, 0x1eb9, 0x1ebb, 0x1ebd,
+ 0x1ebf, 0x1ec1, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0x1ec3, 0x1ec5, 0x1ec7, 0x1ec9, 0x1ecb,
+ 0x1ecd, 0x1ecf, 0x1ed1, 0x1ed3, 0x1ed5, 0x1ed7, 0x1ed9, 0x1edb,
+ 0x1edd, 0x1edf, 0x1ee1, 0x1ee3, 0x1ee5, 0x1ee7, 0x1ee9, 0x1eeb,
+ 0x1eed, 0x1eef, 0x1ef1, 0x1ef4, 0x1ef7, 0x1efa, 0x1efd, 0x1f00,
+ 0x1f03, 0x1f06, 0x1f09, 0x1f0c, 0x1f0f, 0x1f12, 0x1f15, 0x1f18,
+ 0x1f1b, 0x1f1e, 0x1f21, 0x1f24, 0x1f27, 0x1f29, 0x1f2b, 0x1f2d,
+
+ 0x1f2f, 0x1f32, 0x1f35, 0x1f38, 0x1f3b, 0x1f3e, 0x1f41, 0x1f44,
+ 0x1f47, 0x1f4a, 0x1f4d, 0x1f50, 0x1f53, 0x1f56, 0x1f59, 0x1f5c,
+ 0x1f5f, 0x1f62, 0x1f65, 0x1f68, 0x1f6b, 0x1f6e, 0x1f71, 0x1f74,
+ 0x1f77, 0x1f7a, 0x1f7d, 0x1f80, 0x1f83, 0x1f86, 0x1f89, 0x1f8c,
+ 0x1f8f, 0x1f92, 0x1f95, 0x1f98, 0x1f9b, 0x1f9e, 0x1fa1, 0x1fa4,
+ 0x1fa7, 0x1faa, 0x1fad, 0x1fb0, 0x1fb3, 0x1fb6, 0x1fb9, 0x1fbc,
+ 0x1fbf, 0x1fc2, 0x1fc5, 0x1fc8, 0x1fcb, 0x1fce, 0x1fd1, 0x1fd4,
+ 0x1fd7, 0x1fda, 0x1fdd, 0x1fe0, 0x1fe3, 0x1fe6, 0x1fe9, 0x1fec,
+ 0x1fef, 0x1ff2, 0x1ff5, 0x1ff8, 0x1ffb, 0x1ffe, 0x2001, 0x2004,
+ 0x2007, 0x200a, 0x200d, 0x2010, 0x2013, 0x2016, 0x2019, 0x201c,
+ 0x201f, 0x2022, 0x2025, 0x2028, 0x202b, 0x202e, 0x2031, 0x2034,
+ 0x2037, 0x203a, 0x203d, 0x2040, 0x2043, 0x2046, 0x2049, 0x204d,
+ 0x2051, 0x2055, 0x2059, 0x205d, 0x2061, 0x2064, 0x2067, 0x206a,
+ 0x206d, 0x2070, 0x2073, 0x2076, 0x2079, 0x207c, 0x207f, 0x2082,
+ 0x2085, 0x2088, 0x208b, 0x208e, 0x2091, 0x2094, 0x2097, 0x209a,
+ 0x209d, 0x20a0, 0x20a3, 0x20a6, 0x20a9, 0x20ac, 0x20af, 0x20b2,
+ 0x20b5, 0x20b8, 0x20bb, 0x20be, 0x20c1, 0x20c4, 0x20c7, 0x20ca,
+ 0x20cd, 0x20d0, 0x20d3, 0x20d6, 0x20d9, 0x20dc, 0x20df, 0x20e2,
+ 0x20e5, 0x20e8, 0x20eb, 0x20ee, 0x20f1, 0x20f4, 0x20f7, 0x20fa,
+ 0x20fd, 0x2100, 0x2103, 0x2106, 0x2109, 0x210c, 0x210f, 0x2112,
+ 0x2115, 0x2118, 0x211b, 0x211e, 0x2121, 0x2124, 0x2127, 0x212a,
+ 0x212d, 0x2130, 0x2133, 0x2136, 0x2139, 0x213c, 0x213f, 0x2142,
+ 0x2145, 0x2148, 0x214b, 0x214e, 0x2151, 0x2154, 0x2157, 0x215a,
+ 0x215d, 0x2160, 0x2163, 0x2166, 0x2169, 0x216c, 0x216f, 0x2172,
+ 0x2175, 0x2178, 0x217b, 0x217e, 0x2181, 0x2184, 0x2187, 0x218a,
+ 0x218d, 0x2190, 0x2193, 0x2196, 0x2199, 0x219c, 0x219f, 0x21a2,
+ 0x21a5, 0x21a8, 0x21ab, 0x21ae, 0x21b1, 0x21b4, 0x21b7, 0x21ba,
+ 0x21bd, 0x21c0, 0x21c3, 0x21c6, 0x21c9, 0x21cc, 0x21cf, 0x21d2,
+ 0x21d5, 0x21d8, 0x21db, 0x21de, 0x21e1, 0x21e4, 0x21e7, 0x21ea,
+ 0x21ed, 0x21f0, 0x21f3, 0x21f6, 0x21f9, 0x21fc, 0x21ff, 0x2202,
+ 0x2205, 0x2208, 0x220b, 0x220f, 0x2213, 0x2217, 0x221a, 0x221d,
+ 0x2220, 0x2223, 0x2226, 0x2229, 0x222c, 0x222f, 0x2232, 0x2235,
+
+ 0x2238, 0x223b, 0x223e, 0x2241, 0x2244, 0x2247, 0x224a, 0x224d,
+ 0x2250, 0x2253, 0x2256, 0x2259, 0x225c, 0x225f, 0x2262, 0x2265,
+ 0x2268, 0x226b, 0x226e, 0x2271, 0x2274, 0x2277, 0x227a, 0x227d,
+ 0x2280, 0x2283, 0x2286, 0x2289, 0x228c, 0x228f, 0x2292, 0x2295,
+ 0x2298, 0x229b, 0x229e, 0x22a1, 0x22a4, 0x22a7, 0x22aa, 0x22ad,
+ 0x22b0, 0x22b3, 0x22b6, 0x22b9, 0x22bc, 0x22bf, 0x22c2, 0x22c5,
+ 0x22c8, 0x22cb, 0x22ce, 0x22d1, 0x22d4, 0x22d7, 0x22da, 0x22dd,
+ 0x22e0, 0x22e3, 0x22e6, 0x22e9, 0x22ec, 0x22ef, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0x22f2, 0x22f6, 0x22fa, 0x22fe, 0x2302, 0x2306, 0x230a, 0x230e,
+ 0x2312, 0x2316, 0x231a, 0x231e, 0x2322, 0x2326, 0x232a, 0x232e,
+ 0x2332, 0x2336, 0x233a, 0x233e, 0x2342, 0x2346, 0x234a, 0x234e,
+ 0x2352, 0x2356, 0x235a, 0x235e, 0x2362, 0x2366, 0x236a, 0x236e,
+ 0x2372, 0x2376, 0x237a, 0x237e, 0x2382, 0x2386, 0x238a, 0x238e,
+ 0x2392, 0x2396, 0x239a, 0x239e, 0x23a2, 0x23a6, 0x23aa, 0x23ae,
+ 0x23b2, 0x23b6, 0x23ba, 0x23be, 0x23c2, 0x23c6, 0x23ca, 0x23ce,
+ 0x23d2, 0x23d6, 0x23da, 0x23de, 0x23e2, 0x23e6, 0x23ea, 0x23ee,
+ 0xffff, 0xffff, 0x23f2, 0x23f6, 0x23fa, 0x23fe, 0x2402, 0x2406,
+ 0x240a, 0x240e, 0x2412, 0x2416, 0x241a, 0x241e, 0x2422, 0x2426,
+ 0x242a, 0x242e, 0x2432, 0x2436, 0x243a, 0x243e, 0x2442, 0x2446,
+ 0x244a, 0x244e, 0x2452, 0x2456, 0x245a, 0x245e, 0x2462, 0x2466,
+ 0x246a, 0x246e, 0x2472, 0x2476, 0x247a, 0x247e, 0x2482, 0x2486,
+ 0x248a, 0x248e, 0x2492, 0x2496, 0x249a, 0x249e, 0x24a2, 0x24a6,
+ 0x24aa, 0x24ae, 0x24b2, 0x24b6, 0x24ba, 0x24be, 0x24c2, 0x24c6,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0x24ca, 0x24ce, 0x24d2, 0x24d7, 0x24dc, 0x24e1, 0x24e6, 0x24eb,
+ 0x24f0, 0x24f5, 0x24f9, 0x250c, 0x2515, 0xffff, 0xffff, 0xffff,
+
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0x251a, 0x251c, 0x251e, 0x2520, 0x2522, 0x2524, 0x2526, 0x2528,
+ 0x252a, 0x252c, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0x252e, 0x2530, 0x2532, 0x2534, 0x2536, 0x2538, 0x253a, 0x253c,
+ 0x253e, 0x2540, 0x2542, 0x2544, 0x2546, 0x2548, 0x254a, 0x254c,
+ 0x254e, 0x2550, 0x2552, 0x2554, 0x2556, 0xffff, 0xffff, 0x2558,
+ 0x255a, 0x255c, 0x255e, 0x2560, 0x2562, 0x2564, 0x2566, 0x2568,
+ 0x256a, 0x256c, 0x256e, 0xffff, 0x2570, 0x2572, 0x2574, 0x2576,
+ 0x2578, 0x257a, 0x257c, 0x257e, 0x2580, 0x2582, 0x2584, 0x2586,
+ 0x2588, 0x258a, 0x258c, 0x258e, 0x2590, 0x2592, 0x2594, 0xffff,
+ 0x2596, 0x2598, 0x259a, 0x259c, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0x259e, 0x25a1, 0x25a4, 0xffff, 0x25a7, 0xffff, 0x25aa, 0x25ad,
+ 0x25b0, 0x25b3, 0x25b6, 0x25b9, 0x25bc, 0x25bf, 0x25c2, 0x25c5,
+ 0x25c8, 0x25ca, 0x25cc, 0x25ce, 0x25d0, 0x25d2, 0x25d4, 0x25d6,
+ 0x25d8, 0x25da, 0x25dc, 0x25de, 0x25e0, 0x25e2, 0x25e4, 0x25e6,
+ 0x25e8, 0x25ea, 0x25ec, 0x25ee, 0x25f0, 0x25f2, 0x25f4, 0x25f6,
+ 0x25f8, 0x25fa, 0x25fc, 0x25fe, 0x2600, 0x2602, 0x2604, 0x2606,
+ 0x2608, 0x260a, 0x260c, 0x260e, 0x2610, 0x2612, 0x2614, 0x2616,
+ 0x2618, 0x261a, 0x261c, 0x261e, 0x2620, 0x2622, 0x2624, 0x2626,
+ 0x2628, 0x262a, 0x262c, 0x262e, 0x2630, 0x2632, 0x2634, 0x2636,
+ 0x2638, 0x263a, 0x263c, 0x263e, 0x2640, 0x2642, 0x2644, 0x2646,
+ 0x2648, 0x264a, 0x264c, 0x264e, 0x2650, 0x2652, 0x2654, 0x2656,
+ 0x2658, 0x265a, 0x265c, 0x265e, 0x2660, 0x2662, 0x2664, 0x2666,
+ 0x2668, 0x266a, 0x266c, 0x266e, 0x2670, 0x2672, 0x2674, 0x2676,
+ 0x2678, 0x267a, 0x267c, 0x267e, 0x2680, 0x2682, 0x2684, 0x2686,
+ 0x2688, 0x268a, 0x268c, 0x268e, 0x2690, 0x2692, 0x2694, 0x2696,
+ 0x2698, 0x269a, 0x269c, 0x269e, 0x26a0, 0x26a2, 0x26a4, 0x26a6,
+ 0x26a8, 0x26aa, 0x26ac, 0x26ae, 0x26b0, 0x26b2, 0x26b5, 0x26b8,
+ 0x26bb, 0x26be, 0x26c1, 0x26c4, 0x26c7, 0xffff, 0xffff, 0xffff,
+
+ 0xffff, 0x26ca, 0x26cc, 0x26ce, 0x26d0, 0x26d2, 0x26d4, 0x26d6,
+ 0x26d8, 0x26da, 0x26dc, 0x26de, 0x26e0, 0x26e2, 0x26e4, 0x26e6,
+ 0x26e8, 0x26ea, 0x26ec, 0x26ee, 0x26f0, 0x26f2, 0x26f4, 0x26f6,
+ 0x26f8, 0x26fa, 0x26fc, 0x26fe, 0x2700, 0x2702, 0x2704, 0x2706,
+ 0x2708, 0x270a, 0x270c, 0x270e, 0x2710, 0x2712, 0x2714, 0x2716,
+ 0x2718, 0x271a, 0x271c, 0x271e, 0x2720, 0x2722, 0x2724, 0x2726,
+ 0x2728, 0x272a, 0x272c, 0x272e, 0x2730, 0x2732, 0x2734, 0x2736,
+ 0x2738, 0x273a, 0x273c, 0x273e, 0x2740, 0x2742, 0x2744, 0x2746,
+ 0x2748, 0x274a, 0x274c, 0x274e, 0x2750, 0x2752, 0x2754, 0x2756,
+ 0x2758, 0x275a, 0x275c, 0x275e, 0x2760, 0x2762, 0x2764, 0x2766,
+ 0x2768, 0x276a, 0x276c, 0x276e, 0x2770, 0x2772, 0x2774, 0x2776,
+ 0x2778, 0x277a, 0x277c, 0x277e, 0x2780, 0x2782, 0x2784, 0x2786,
+ 0x2788, 0x278a, 0x278c, 0x278e, 0x2790, 0x2792, 0x2794, 0x2796,
+ 0x2798, 0x279a, 0x279c, 0x279e, 0x27a0, 0x27a2, 0x27a4, 0x27a6,
+ 0x27a8, 0x27aa, 0x27ac, 0x27ae, 0x27b0, 0x27b2, 0x27b4, 0x27b6,
+ 0x27b8, 0x27ba, 0x27bc, 0x27be, 0x27c0, 0x27c2, 0x27c4, 0x27c6,
+ 0x27c8, 0x27ca, 0x27cc, 0x27ce, 0x27d0, 0x27d2, 0x27d4, 0x27d6,
+ 0x27d8, 0x27da, 0x27dc, 0x27de, 0x27e0, 0x27e2, 0x27e4, 0x27e6,
+ 0x27e8, 0x27ea, 0x27ec, 0x27ee, 0x27f0, 0x27f2, 0x27f4, 0x27f6,
+ 0x27f8, 0x27fa, 0x27fc, 0x27fe, 0x2800, 0x2802, 0x2804, 0x2806,
+ 0x2808, 0x280a, 0x280c, 0x280e, 0x2810, 0x2812, 0x2814, 0x2816,
+ 0x2818, 0x281a, 0x281c, 0x281e, 0x2820, 0x2822, 0x2824, 0x2826,
+ 0x2828, 0x282a, 0x282c, 0x282e, 0x2830, 0x2832, 0x2834, 0x2836,
+ 0x2838, 0x283a, 0x283c, 0x283e, 0x2840, 0x2842, 0x2844, 0xffff,
+ 0xffff, 0xffff, 0x2846, 0x2848, 0x284a, 0x284c, 0x284e, 0x2850,
+ 0xffff, 0xffff, 0x2852, 0x2854, 0x2856, 0x2858, 0x285a, 0x285c,
+ 0xffff, 0xffff, 0x285e, 0x2860, 0x2862, 0x2864, 0x2866, 0x2868,
+ 0xffff, 0xffff, 0x286a, 0x286c, 0x286e, 0xffff, 0xffff, 0xffff,
+ 0x2870, 0x2872, 0x2874, 0x2876, 0x2878, 0x287a, 0x287c, 0xffff,
+ 0x287e, 0x2880, 0x2882, 0x2884, 0x2886, 0x2888, 0x288a, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x288c, 0x2891,
+ 0x2896, 0x289b, 0x28a0, 0x28a5, 0x28aa, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0x28af, 0x28b4, 0x28b9, 0x28be, 0x28c3,
+ 0x28c8, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+
+ 0x28cd, 0x28cf, 0x28d1, 0x28d3, 0x28d5, 0x28d7, 0x28d9, 0x28db,
+ 0x28dd, 0x28df, 0x28e1, 0x28e3, 0x28e5, 0x28e7, 0x28e9, 0x28eb,
+ 0x28ed, 0x28ef, 0x28f1, 0x28f3, 0x28f5, 0x28f7, 0x28f9, 0x28fb,
+ 0x28fd, 0x28ff, 0x2901, 0x2903, 0x2905, 0x2907, 0x2909, 0x290b,
+ 0x290d, 0x290f, 0x2911, 0x2913, 0x2915, 0x2917, 0x2919, 0x291b,
+ 0x291d, 0x291f, 0x2921, 0x2923, 0x2925, 0x2927, 0x2929, 0x292b,
+ 0x292d, 0x292f, 0x2931, 0x2933, 0x2935, 0x2937, 0x2939, 0x293b,
+ 0x293d, 0x293f, 0x2941, 0x2943, 0x2945, 0x2947, 0x2949, 0x294b,
+ 0x294d, 0x294f, 0x2951, 0x2953, 0x2955, 0x2957, 0x2959, 0x295b,
+ 0x295d, 0x295f, 0x2961, 0x2963, 0x2965, 0x2967, 0x2969, 0x296b,
+ 0x296d, 0x296f, 0x2971, 0x2973, 0x2975, 0xffff, 0x2977, 0x2979,
+ 0x297b, 0x297d, 0x297f, 0x2981, 0x2983, 0x2985, 0x2987, 0x2989,
+ 0x298b, 0x298d, 0x298f, 0x2991, 0x2993, 0x2995, 0x2997, 0x2999,
+ 0x299b, 0x299d, 0x299f, 0x29a1, 0x29a3, 0x29a5, 0x29a7, 0x29a9,
+ 0x29ab, 0x29ad, 0x29af, 0x29b1, 0x29b3, 0x29b5, 0x29b7, 0x29b9,
+ 0x29bb, 0x29bd, 0x29bf, 0x29c1, 0x29c3, 0x29c5, 0x29c7, 0x29c9,
+ 0x29cb, 0x29cd, 0x29cf, 0x29d1, 0x29d3, 0x29d5, 0x29d7, 0x29d9,
+ 0x29db, 0x29dd, 0x29df, 0x29e1, 0x29e3, 0x29e5, 0x29e7, 0x29e9,
+ 0x29eb, 0x29ed, 0x29ef, 0x29f1, 0x29f3, 0x29f5, 0x29f7, 0x29f9,
+ 0x29fb, 0x29fd, 0x29ff, 0x2a01, 0x2a03, 0xffff, 0x2a05, 0x2a07,
+ 0xffff, 0xffff, 0x2a09, 0xffff, 0xffff, 0x2a0b, 0x2a0d, 0xffff,
+ 0xffff, 0x2a0f, 0x2a11, 0x2a13, 0x2a15, 0xffff, 0x2a17, 0x2a19,
+ 0x2a1b, 0x2a1d, 0x2a1f, 0x2a21, 0x2a23, 0x2a25, 0x2a27, 0x2a29,
+ 0x2a2b, 0x2a2d, 0xffff, 0x2a2f, 0xffff, 0x2a31, 0x2a33, 0x2a35,
+ 0x2a37, 0x2a39, 0x2a3b, 0x2a3d, 0xffff, 0x2a3f, 0x2a41, 0x2a43,
+ 0x2a45, 0x2a47, 0x2a49, 0x2a4b, 0x2a4d, 0x2a4f, 0x2a51, 0x2a53,
+ 0x2a55, 0x2a57, 0x2a59, 0x2a5b, 0x2a5d, 0x2a5f, 0x2a61, 0x2a63,
+ 0x2a65, 0x2a67, 0x2a69, 0x2a6b, 0x2a6d, 0x2a6f, 0x2a71, 0x2a73,
+ 0x2a75, 0x2a77, 0x2a79, 0x2a7b, 0x2a7d, 0x2a7f, 0x2a81, 0x2a83,
+ 0x2a85, 0x2a87, 0x2a89, 0x2a8b, 0x2a8d, 0x2a8f, 0x2a91, 0x2a93,
+ 0x2a95, 0x2a97, 0x2a99, 0x2a9b, 0x2a9d, 0x2a9f, 0x2aa1, 0x2aa3,
+ 0x2aa5, 0x2aa7, 0x2aa9, 0x2aab, 0x2aad, 0x2aaf, 0x2ab1, 0x2ab3,
+
+ 0x2ab5, 0x2ab7, 0x2ab9, 0x2abb, 0x2abd, 0x2abf, 0xffff, 0x2ac1,
+ 0x2ac3, 0x2ac5, 0x2ac7, 0xffff, 0xffff, 0x2ac9, 0x2acb, 0x2acd,
+ 0x2acf, 0x2ad1, 0x2ad3, 0x2ad5, 0x2ad7, 0xffff, 0x2ad9, 0x2adb,
+ 0x2add, 0x2adf, 0x2ae1, 0x2ae3, 0x2ae5, 0xffff, 0x2ae7, 0x2ae9,
+ 0x2aeb, 0x2aed, 0x2aef, 0x2af1, 0x2af3, 0x2af5, 0x2af7, 0x2af9,
+ 0x2afb, 0x2afd, 0x2aff, 0x2b01, 0x2b03, 0x2b05, 0x2b07, 0x2b09,
+ 0x2b0b, 0x2b0d, 0x2b0f, 0x2b11, 0x2b13, 0x2b15, 0x2b17, 0x2b19,
+ 0x2b1b, 0x2b1d, 0xffff, 0x2b1f, 0x2b21, 0x2b23, 0x2b25, 0xffff,
+ 0x2b27, 0x2b29, 0x2b2b, 0x2b2d, 0x2b2f, 0xffff, 0x2b31, 0xffff,
+ 0xffff, 0xffff, 0x2b33, 0x2b35, 0x2b37, 0x2b39, 0x2b3b, 0x2b3d,
+ 0x2b3f, 0xffff, 0x2b41, 0x2b43, 0x2b45, 0x2b47, 0x2b49, 0x2b4b,
+ 0x2b4d, 0x2b4f, 0x2b51, 0x2b53, 0x2b55, 0x2b57, 0x2b59, 0x2b5b,
+ 0x2b5d, 0x2b5f, 0x2b61, 0x2b63, 0x2b65, 0x2b67, 0x2b69, 0x2b6b,
+ 0x2b6d, 0x2b6f, 0x2b71, 0x2b73, 0x2b75, 0x2b77, 0x2b79, 0x2b7b,
+ 0x2b7d, 0x2b7f, 0x2b81, 0x2b83, 0x2b85, 0x2b87, 0x2b89, 0x2b8b,
+ 0x2b8d, 0x2b8f, 0x2b91, 0x2b93, 0x2b95, 0x2b97, 0x2b99, 0x2b9b,
+ 0x2b9d, 0x2b9f, 0x2ba1, 0x2ba3, 0x2ba5, 0x2ba7, 0x2ba9, 0x2bab,
+ 0x2bad, 0x2baf, 0x2bb1, 0x2bb3, 0x2bb5, 0x2bb7, 0x2bb9, 0x2bbb,
+ 0x2bbd, 0x2bbf, 0x2bc1, 0x2bc3, 0x2bc5, 0x2bc7, 0x2bc9, 0x2bcb,
+ 0x2bcd, 0x2bcf, 0x2bd1, 0x2bd3, 0x2bd5, 0x2bd7, 0x2bd9, 0x2bdb,
+ 0x2bdd, 0x2bdf, 0x2be1, 0x2be3, 0x2be5, 0x2be7, 0x2be9, 0x2beb,
+ 0x2bed, 0x2bef, 0x2bf1, 0x2bf3, 0x2bf5, 0x2bf7, 0x2bf9, 0x2bfb,
+ 0x2bfd, 0x2bff, 0x2c01, 0x2c03, 0x2c05, 0x2c07, 0x2c09, 0x2c0b,
+ 0x2c0d, 0x2c0f, 0x2c11, 0x2c13, 0x2c15, 0x2c17, 0x2c19, 0x2c1b,
+ 0x2c1d, 0x2c1f, 0x2c21, 0x2c23, 0x2c25, 0x2c27, 0x2c29, 0x2c2b,
+ 0x2c2d, 0x2c2f, 0x2c31, 0x2c33, 0x2c35, 0x2c37, 0x2c39, 0x2c3b,
+ 0x2c3d, 0x2c3f, 0x2c41, 0x2c43, 0x2c45, 0x2c47, 0x2c49, 0x2c4b,
+ 0x2c4d, 0x2c4f, 0x2c51, 0x2c53, 0x2c55, 0x2c57, 0x2c59, 0x2c5b,
+ 0x2c5d, 0x2c5f, 0x2c61, 0x2c63, 0x2c65, 0x2c67, 0x2c69, 0x2c6b,
+ 0x2c6d, 0x2c6f, 0x2c71, 0x2c73, 0x2c75, 0x2c77, 0x2c79, 0x2c7b,
+ 0x2c7d, 0x2c7f, 0x2c81, 0x2c83, 0x2c85, 0x2c87, 0x2c89, 0x2c8b,
+ 0x2c8d, 0x2c8f, 0x2c91, 0x2c93, 0x2c95, 0x2c97, 0x2c99, 0x2c9b,
+
+ 0x2c9d, 0x2c9f, 0x2ca1, 0x2ca3, 0x2ca5, 0x2ca7, 0x2ca9, 0x2cab,
+ 0x2cad, 0x2caf, 0x2cb1, 0x2cb3, 0x2cb5, 0x2cb7, 0x2cb9, 0x2cbb,
+ 0x2cbd, 0x2cbf, 0x2cc1, 0x2cc3, 0x2cc5, 0x2cc7, 0x2cc9, 0x2ccb,
+ 0x2ccd, 0x2ccf, 0x2cd1, 0x2cd3, 0x2cd5, 0x2cd7, 0x2cd9, 0x2cdb,
+ 0x2cdd, 0x2cdf, 0x2ce1, 0x2ce3, 0x2ce5, 0x2ce7, 0x2ce9, 0x2ceb,
+ 0x2ced, 0x2cef, 0x2cf1, 0x2cf3, 0x2cf5, 0x2cf7, 0x2cf9, 0x2cfb,
+ 0x2cfd, 0x2cff, 0x2d01, 0x2d03, 0x2d05, 0x2d07, 0x2d09, 0x2d0b,
+ 0x2d0d, 0x2d0f, 0x2d11, 0x2d13, 0x2d15, 0x2d17, 0x2d19, 0x2d1b,
+ 0x2d1d, 0x2d1f, 0x2d21, 0x2d23, 0x2d25, 0x2d27, 0x2d29, 0x2d2b,
+ 0x2d2d, 0x2d2f, 0x2d31, 0x2d33, 0x2d35, 0x2d37, 0x2d39, 0x2d3b,
+ 0x2d3d, 0x2d3f, 0x2d41, 0x2d43, 0x2d45, 0x2d47, 0x2d49, 0x2d4b,
+ 0x2d4d, 0x2d4f, 0x2d51, 0x2d53, 0x2d55, 0x2d57, 0x2d59, 0x2d5b,
+ 0x2d5d, 0x2d5f, 0x2d61, 0x2d63, 0x2d65, 0x2d67, 0x2d69, 0x2d6b,
+ 0x2d6d, 0x2d6f, 0x2d71, 0x2d73, 0x2d75, 0x2d77, 0x2d79, 0x2d7b,
+ 0x2d7d, 0x2d7f, 0x2d81, 0x2d83, 0x2d85, 0x2d87, 0x2d89, 0x2d8b,
+ 0x2d8d, 0x2d8f, 0x2d91, 0x2d93, 0x2d95, 0x2d97, 0x2d99, 0x2d9b,
+ 0x2d9d, 0x2d9f, 0x2da1, 0x2da3, 0x2da5, 0x2da7, 0x2da9, 0x2dab,
+ 0x2dad, 0x2daf, 0x2db1, 0x2db3, 0x2db5, 0x2db7, 0x2db9, 0x2dbb,
+ 0x2dbd, 0x2dbf, 0x2dc1, 0x2dc3, 0x2dc5, 0x2dc7, 0x2dc9, 0x2dcb,
+ 0x2dcd, 0x2dcf, 0x2dd1, 0x2dd3, 0x2dd5, 0x2dd7, 0x2dd9, 0x2ddb,
+ 0x2ddd, 0x2ddf, 0x2de1, 0x2de3, 0x2de5, 0x2de7, 0xffff, 0xffff,
+ 0x2de9, 0x2deb, 0x2ded, 0x2def, 0x2df1, 0x2df3, 0x2df5, 0x2df7,
+ 0x2df9, 0x2dfb, 0x2dfd, 0x2dff, 0x2e01, 0x2e03, 0x2e05, 0x2e07,
+ 0x2e09, 0x2e0b, 0x2e0d, 0x2e0f, 0x2e11, 0x2e13, 0x2e15, 0x2e17,
+ 0x2e19, 0x2e1b, 0x2e1d, 0x2e1f, 0x2e21, 0x2e23, 0x2e25, 0x2e27,
+ 0x2e29, 0x2e2b, 0x2e2d, 0x2e2f, 0x2e31, 0x2e33, 0x2e35, 0x2e37,
+ 0x2e39, 0x2e3b, 0x2e3d, 0x2e3f, 0x2e41, 0x2e43, 0x2e45, 0x2e47,
+ 0x2e49, 0x2e4b, 0x2e4d, 0x2e4f, 0x2e51, 0x2e53, 0x2e55, 0x2e57,
+ 0x2e59, 0x2e5b, 0x2e5d, 0x2e5f, 0x2e61, 0x2e63, 0x2e65, 0x2e67,
+ 0x2e69, 0x2e6b, 0x2e6d, 0x2e6f, 0x2e71, 0x2e73, 0x2e75, 0x2e77,
+ 0x2e79, 0x2e7b, 0x2e7d, 0x2e7f, 0x2e81, 0x2e83, 0x2e85, 0x2e87,
+ 0x2e89, 0x2e8b, 0x2e8d, 0x2e8f, 0x2e91, 0x2e93, 0x2e95, 0x2e97,
+
+ 0x2e99, 0x2e9b, 0x2e9d, 0x2e9f, 0x2ea1, 0x2ea3, 0x2ea5, 0x2ea7,
+ 0x2ea9, 0x2eab, 0x2ead, 0x2eaf, 0x2eb1, 0x2eb3, 0x2eb5, 0x2eb7,
+ 0x2eb9, 0x2ebb, 0x2ebd, 0x2ebf, 0x2ec1, 0x2ec3, 0x2ec5, 0x2ec7,
+ 0x2ec9, 0x2ecb, 0x2ecd, 0x2ecf, 0x2ed1, 0x2ed3, 0x2ed5, 0x2ed7,
+ 0x2ed9, 0x2edb, 0x2edd, 0x2edf, 0x2ee1, 0x2ee3, 0x2ee5, 0x2ee7,
+ 0x2ee9, 0x2eeb, 0x2eed, 0x2eef, 0x2ef1, 0x2ef3, 0x2ef5, 0x2ef7,
+ 0x2ef9, 0x2efb, 0x2efd, 0x2eff, 0x2f01, 0x2f03, 0x2f05, 0x2f07,
+ 0x2f09, 0x2f0b, 0x2f0d, 0x2f0f, 0x2f11, 0x2f13, 0x2f15, 0x2f17,
+ 0x2f19, 0x2f1b, 0x2f1d, 0x2f1f, 0x2f21, 0x2f23, 0x2f25, 0x2f27,
+ 0x2f29, 0x2f2b, 0x2f2d, 0x2f2f, 0x2f31, 0x2f33, 0x2f35, 0x2f37,
+ 0x2f39, 0x2f3b, 0x2f3d, 0x2f3f, 0x2f41, 0x2f43, 0x2f45, 0x2f47,
+ 0x2f49, 0x2f4b, 0x2f4d, 0x2f4f, 0x2f51, 0x2f53, 0x2f55, 0x2f57,
+ 0x2f59, 0x2f5b, 0x2f5d, 0x2f5f, 0x2f61, 0x2f63, 0x2f65, 0x2f67,
+ 0x2f69, 0x2f6b, 0x2f6d, 0x2f6f, 0x2f71, 0x2f73, 0x2f75, 0x2f77,
+ 0x2f79, 0x2f7b, 0x2f7d, 0x2f7f, 0x2f81, 0x2f83, 0x2f85, 0x2f87,
+ 0x2f89, 0x2f8b, 0x2f8d, 0x2f8f, 0x2f91, 0x2f93, 0x2f95, 0x2f97,
+ 0x2f99, 0x2f9b, 0x2f9d, 0x2f9f, 0x2fa1, 0x2fa3, 0x2fa5, 0x2fa7,
+ 0x2fa9, 0x2fab, 0x2fad, 0x2faf, 0x2fb1, 0x2fb3, 0x2fb5, 0x2fb7,
+ 0x2fb9, 0x2fbb, 0x2fbd, 0x2fbf, 0x2fc1, 0x2fc3, 0x2fc5, 0x2fc7,
+ 0x2fc9, 0x2fcb, 0x2fcd, 0x2fcf, 0x2fd1, 0x2fd3, 0x2fd5, 0x2fd7,
+ 0x2fd9, 0x2fdb, 0x2fdd, 0x2fdf, 0x2fe1, 0x2fe3, 0x2fe5, 0x2fe7,
+ 0x2fe9, 0x2feb, 0x2fed, 0x2fef, 0x2ff1, 0x2ff3, 0x2ff5, 0x2ff7,
+ 0x2ff9, 0x2ffb, 0x2ffd, 0x2fff, 0x3001, 0x3003, 0x3005, 0x3007,
+ 0x3009, 0x300b, 0x300d, 0x300f, 0x3011, 0x3013, 0x3015, 0x3017,
+ 0x3019, 0x301b, 0x301d, 0x301f, 0x3021, 0x3023, 0x3025, 0x3027,
+ 0x3029, 0x302b, 0x302d, 0x302f, 0xffff, 0xffff, 0x3031, 0x3033,
+ 0x3035, 0x3037, 0x3039, 0x303b, 0x303d, 0x303f, 0x3041, 0x3043,
+ 0x3045, 0x3047, 0x3049, 0x304b, 0x304d, 0x304f, 0x3051, 0x3053,
+ 0x3055, 0x3057, 0x3059, 0x305b, 0x305d, 0x305f, 0x3061, 0x3063,
+ 0x3065, 0x3067, 0x3069, 0x306b, 0x306d, 0x306f, 0x3071, 0x3073,
+ 0x3075, 0x3077, 0x3079, 0x307b, 0x307d, 0x307f, 0x3081, 0x3083,
+ 0x3085, 0x3087, 0x3089, 0x308b, 0x308d, 0x308f, 0x3091, 0x3093,
+
+ 0x3095, 0x3097, 0x3099, 0x309b, 0x309e, 0x30a0, 0x30a2, 0x30a4,
+ 0x30a6, 0x30a8, 0x30aa, 0x30ac, 0x30ae, 0x30b0, 0x30b3, 0x30b5,
+ 0x30b7, 0x30b9, 0x30bb, 0x30be, 0x30c0, 0x30c2, 0x30c4, 0x30c7,
+ 0x30c9, 0x30cb, 0x30cd, 0x30cf, 0x30d1, 0x30d4, 0x30d6, 0x30d8,
+ 0x30da, 0x30dc, 0x30de, 0x30e0, 0x30e2, 0x30e4, 0x30e6, 0x30e8,
+ 0x30ea, 0x30ec, 0x30ee, 0x30f0, 0x30f2, 0x30f4, 0x30f6, 0x30f8,
+ 0x30fa, 0x30fc, 0x30fe, 0x3100, 0x3102, 0x3105, 0x3107, 0x3109,
+ 0x310b, 0x310e, 0x3110, 0x3112, 0x3114, 0x3116, 0x3118, 0x311a,
+ 0x311c, 0x311e, 0x3120, 0x3122, 0x3124, 0x3126, 0x3128, 0x312a,
+ 0x312c, 0x312e, 0x3130, 0x3132, 0x3134, 0x3136, 0x3138, 0x313a,
+ 0x313c, 0x313e, 0x3140, 0x3142, 0x3144, 0x3146, 0x3148, 0x314a,
+ 0x314c, 0x314e, 0x3151, 0x3153, 0x3155, 0x3157, 0x3159, 0x315b,
+ 0x315d, 0x3160, 0x3163, 0x3165, 0x3167, 0x3169, 0x316b, 0x316d,
+ 0x316f, 0x3171, 0x3173, 0x3175, 0x3177, 0x317a, 0x317c, 0x317e,
+ 0x3180, 0x3182, 0x3185, 0x3187, 0x3189, 0x318b, 0x318d, 0x318f,
+ 0x3191, 0x3193, 0x3195, 0x3197, 0x319a, 0x319c, 0x319f, 0x31a1,
+ 0x31a3, 0x31a5, 0x31a7, 0x31a9, 0x31ab, 0x31ad, 0x31af, 0x31b1,
+ 0x31b3, 0x31b5, 0x31b8, 0x31ba, 0x31bc, 0x31be, 0x31c0, 0x31c2,
+ 0x31c5, 0x31c7, 0x31ca, 0x31cd, 0x31cf, 0x31d1, 0x31d3, 0x31d5,
+ 0x31d8, 0x31db, 0x31dd, 0x31df, 0x31e1, 0x31e3, 0x31e5, 0x31e7,
+ 0x31e9, 0x31eb, 0x31ed, 0x31ef, 0x31f1, 0x31f4, 0x31f6, 0x31f8,
+ 0x31fa, 0x31fc, 0x31fe, 0x3200, 0x3202, 0x3204, 0x3206, 0x3208,
+ 0x320a, 0x320c, 0x320e, 0x3210, 0x3212, 0x3214, 0x3216, 0x3218,
+ 0x321a, 0x321d, 0x321f, 0x3221, 0x3223, 0x3225, 0x3227, 0x322a,
+ 0x322c, 0x322e, 0x3230, 0x3232, 0x3234, 0x3236, 0x3238, 0x323a,
+ 0x323c, 0x323e, 0x3240, 0x3243, 0x3245, 0x3247, 0x3249, 0x324b,
+ 0x324d, 0x324f, 0x3251, 0x3253, 0x3255, 0x3257, 0x3259, 0x325b,
+ 0x325d, 0x325f, 0x3261, 0x3263, 0x3265, 0x3267, 0x326a, 0x326c,
+ 0x326e, 0x3270, 0x3272, 0x3274, 0x3277, 0x3279, 0x327b, 0x327d,
+ 0x327f, 0x3281, 0x3283, 0x3285, 0x3287, 0x328a, 0x328c, 0x328e,
+ 0x3290, 0x3293, 0x3295, 0x3297, 0x3299, 0x329b, 0x329d, 0x329f,
+ 0x32a2, 0x32a5, 0x32a8, 0x32aa, 0x32ad, 0x32af, 0x32b1, 0x32b3,
+
+ 0x32b5, 0x32b7, 0x32b9, 0x32bb, 0x32bd, 0x32bf, 0x32c1, 0x32c4,
+ 0x32c6, 0x32c8, 0x32ca, 0x32cc, 0x32ce, 0x32d0, 0x32d3, 0x32d5,
+ 0x32d7, 0x32da, 0x32dd, 0x32df, 0x32e1, 0x32e3, 0x32e5, 0x32e7,
+ 0x32e9, 0x32eb, 0x32ed, 0x32ef, 0x32f2, 0x32f4, 0x32f7, 0x32f9,
+ 0x32fc, 0x32fe, 0x3300, 0x3302, 0x3305, 0x3307, 0x3309, 0x330c,
+ 0x330f, 0x3311, 0x3313, 0x3315, 0x3317, 0x3319, 0x331b, 0x331d,
+ 0x331f, 0x3321, 0x3323, 0x3325, 0x3327, 0x3329, 0x332c, 0x332e,
+ 0x3331, 0x3333, 0x3336, 0x3338, 0x333b, 0x333e, 0x3341, 0x3343,
+ 0x3345, 0x3347, 0x334a, 0x334d, 0x3350, 0x3353, 0x3355, 0x3357,
+ 0x3359, 0x335b, 0x335d, 0x335f, 0x3361, 0x3363, 0x3366, 0x3368,
+ 0x336a, 0x336c, 0x336e, 0x3371, 0x3373, 0x3376, 0x3379, 0x337b,
+ 0x337d, 0x337f, 0x3381, 0x3383, 0x3385, 0x3388, 0x338b, 0x338e,
+ 0x3390, 0x3392, 0x3395, 0x3397, 0x3399, 0x339b, 0x339e, 0x33a0,
+ 0x33a2, 0x33a4, 0x33a6, 0x33a8, 0x33ab, 0x33ad, 0x33af, 0x33b1,
+ 0x33b3, 0x33b5, 0x33b7, 0x33ba, 0x33bd, 0x33bf, 0x33c2, 0x33c4,
+ 0x33c7, 0x33c9, 0x33cb, 0x33cd, 0x33d0, 0x33d3, 0x33d5, 0x33d8,
+ 0x33da, 0x33dd, 0x33df, 0x33e1, 0x33e3, 0x33e5, 0x33e7, 0x33e9,
+ 0x33ec, 0x33ef, 0x33f2, 0x33f5, 0x33f7, 0x33f9, 0x33fb, 0x33fd,
+ 0x33ff, 0x3401, 0x3403, 0x3405, 0x3407, 0x3409, 0x340b, 0x340d,
+ 0x3410, 0x3412, 0x3414, 0x3416, 0x3418, 0x341a, 0x341c, 0x341e,
+ 0x3420, 0x3422, 0x3424, 0x3426, 0x3428, 0x342b, 0x342e, 0x3431,
+ 0x3433, 0x3435, 0x3437, 0x3439, 0x343c, 0x343e, 0x3441, 0x3443,
+ 0x3445, 0x3448, 0x344b, 0x344d, 0x344f, 0x3451, 0x3453, 0x3455,
+ 0x3457, 0x3459, 0x345b, 0x345d, 0x345f, 0x3461, 0x3463, 0x3465,
+ 0x3467, 0x3469, 0x346b, 0x346d, 0x346f, 0x3471, 0x3474, 0x3476,
+ 0x3478, 0x347a, 0x347c, 0x347e, 0x3481, 0x3484, 0x3486, 0x3488,
+ 0x348a, 0x348c, 0x348e, 0x3490, 0x3493, 0x3495, 0x3497, 0x3499,
+ 0x349b, 0x349e, 0x34a1, 0x34a3, 0x34a5, 0x34a7, 0x34aa, 0x34ac,
+ 0x34ae, 0x34b1, 0x34b4, 0x34b6, 0x34b8, 0x34ba, 0x34bd, 0x34bf,
+ 0x34c1, 0x34c3, 0x34c5, 0x34c7, 0x34c9, 0x34cb, 0x34ce, 0x34d0,
+ 0x34d2, 0x34d4, 0x34d7, 0x34d9, 0x34db, 0x34dd, 0x34df, 0x34e2,
+ 0x34e5, 0x34e7, 0x34e9, 0x34eb, 0x34ee, 0x34f0, 0x34f3, 0x34f5,
+
+ 0x34f7, 0x34f9, 0x34fc, 0x34fe, 0x3500, 0x3502, 0x3504, 0x3506,
+ 0x3508, 0x350a, 0x350d, 0x350f, 0x3511, 0x3513, 0x3515, 0x3517,
+ 0x3519, 0x351c, 0x351e, 0x3521, 0x3524, 0x3527, 0x3529, 0x352b,
+ 0x352d, 0x352f, 0x3531, 0x3533, 0x3535, 0x3537, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+};
+
+#define GET_DECOMPOSITION_INDEX(ucs4) \
+ (ucs4 < 0x3400 \
+ ? (uc_decomposition_trie[uc_decomposition_trie[ucs4>>4] + (ucs4 & 0xf)]) \
+ : (ucs4 < 0x30000\
+ ? uc_decomposition_trie[uc_decomposition_trie[((ucs4 - 0x3400)>>8) + 0x340] + (ucs4 & 0xff)]\
+ : 0xffff))
+
+static const unsigned short uc_decomposition_map[] = {
+
+ 0x103, 0x20, 0x210, 0x20, 0x308, 0x109, 0x61, 0x210,
+ 0x20, 0x304, 0x109, 0x32, 0x109, 0x33, 0x210, 0x20,
+ 0x301, 0x110, 0x3bc, 0x210, 0x20, 0x327, 0x109, 0x31,
+ 0x109, 0x6f, 0x311, 0x31, 0x2044, 0x34, 0x311, 0x31,
+ 0x2044, 0x32, 0x311, 0x33, 0x2044, 0x34, 0x201, 0x41,
+ 0x300, 0x201, 0x41, 0x301, 0x201, 0x41, 0x302, 0x201,
+ 0x41, 0x303, 0x201, 0x41, 0x308, 0x201, 0x41, 0x30a,
+ 0x201, 0x43, 0x327, 0x201, 0x45, 0x300, 0x201, 0x45,
+ 0x301, 0x201, 0x45, 0x302, 0x201, 0x45, 0x308, 0x201,
+ 0x49, 0x300, 0x201, 0x49, 0x301, 0x201, 0x49, 0x302,
+ 0x201, 0x49, 0x308, 0x201, 0x4e, 0x303, 0x201, 0x4f,
+ 0x300, 0x201, 0x4f, 0x301, 0x201, 0x4f, 0x302, 0x201,
+ 0x4f, 0x303, 0x201, 0x4f, 0x308, 0x201, 0x55, 0x300,
+ 0x201, 0x55, 0x301, 0x201, 0x55, 0x302, 0x201, 0x55,
+ 0x308, 0x201, 0x59, 0x301, 0x201, 0x61, 0x300, 0x201,
+ 0x61, 0x301, 0x201, 0x61, 0x302, 0x201, 0x61, 0x303,
+ 0x201, 0x61, 0x308, 0x201, 0x61, 0x30a, 0x201, 0x63,
+ 0x327, 0x201, 0x65, 0x300, 0x201, 0x65, 0x301, 0x201,
+ 0x65, 0x302, 0x201, 0x65, 0x308, 0x201, 0x69, 0x300,
+ 0x201, 0x69, 0x301, 0x201, 0x69, 0x302, 0x201, 0x69,
+ 0x308, 0x201, 0x6e, 0x303, 0x201, 0x6f, 0x300, 0x201,
+ 0x6f, 0x301, 0x201, 0x6f, 0x302, 0x201, 0x6f, 0x303,
+ 0x201, 0x6f, 0x308, 0x201, 0x75, 0x300, 0x201, 0x75,
+ 0x301, 0x201, 0x75, 0x302, 0x201, 0x75, 0x308, 0x201,
+ 0x79, 0x301, 0x201, 0x79, 0x308, 0x201, 0x41, 0x304,
+ 0x201, 0x61, 0x304, 0x201, 0x41, 0x306, 0x201, 0x61,
+ 0x306, 0x201, 0x41, 0x328, 0x201, 0x61, 0x328, 0x201,
+ 0x43, 0x301, 0x201, 0x63, 0x301, 0x201, 0x43, 0x302,
+ 0x201, 0x63, 0x302, 0x201, 0x43, 0x307, 0x201, 0x63,
+ 0x307, 0x201, 0x43, 0x30c, 0x201, 0x63, 0x30c, 0x201,
+ 0x44, 0x30c, 0x201, 0x64, 0x30c, 0x201, 0x45, 0x304,
+ 0x201, 0x65, 0x304, 0x201, 0x45, 0x306, 0x201, 0x65,
+ 0x306, 0x201, 0x45, 0x307, 0x201, 0x65, 0x307, 0x201,
+ 0x45, 0x328, 0x201, 0x65, 0x328, 0x201, 0x45, 0x30c,
+ 0x201, 0x65, 0x30c, 0x201, 0x47, 0x302, 0x201, 0x67,
+ 0x302, 0x201, 0x47, 0x306, 0x201, 0x67, 0x306, 0x201,
+ 0x47, 0x307, 0x201, 0x67, 0x307, 0x201, 0x47, 0x327,
+ 0x201, 0x67, 0x327, 0x201, 0x48, 0x302, 0x201, 0x68,
+ 0x302, 0x201, 0x49, 0x303, 0x201, 0x69, 0x303, 0x201,
+ 0x49, 0x304, 0x201, 0x69, 0x304, 0x201, 0x49, 0x306,
+ 0x201, 0x69, 0x306, 0x201, 0x49, 0x328, 0x201, 0x69,
+ 0x328, 0x201, 0x49, 0x307, 0x210, 0x49, 0x4a, 0x210,
+ 0x69, 0x6a, 0x201, 0x4a, 0x302, 0x201, 0x6a, 0x302,
+ 0x201, 0x4b, 0x327, 0x201, 0x6b, 0x327, 0x201, 0x4c,
+ 0x301, 0x201, 0x6c, 0x301, 0x201, 0x4c, 0x327, 0x201,
+ 0x6c, 0x327, 0x201, 0x4c, 0x30c, 0x201, 0x6c, 0x30c,
+ 0x210, 0x4c, 0xb7, 0x210, 0x6c, 0xb7, 0x201, 0x4e,
+ 0x301, 0x201, 0x6e, 0x301, 0x201, 0x4e, 0x327, 0x201,
+ 0x6e, 0x327, 0x201, 0x4e, 0x30c, 0x201, 0x6e, 0x30c,
+ 0x210, 0x2bc, 0x6e, 0x201, 0x4f, 0x304, 0x201, 0x6f,
+ 0x304, 0x201, 0x4f, 0x306, 0x201, 0x6f, 0x306, 0x201,
+ 0x4f, 0x30b, 0x201, 0x6f, 0x30b, 0x201, 0x52, 0x301,
+ 0x201, 0x72, 0x301, 0x201, 0x52, 0x327, 0x201, 0x72,
+ 0x327, 0x201, 0x52, 0x30c, 0x201, 0x72, 0x30c, 0x201,
+ 0x53, 0x301, 0x201, 0x73, 0x301, 0x201, 0x53, 0x302,
+ 0x201, 0x73, 0x302, 0x201, 0x53, 0x327, 0x201, 0x73,
+ 0x327, 0x201, 0x53, 0x30c, 0x201, 0x73, 0x30c, 0x201,
+ 0x54, 0x327, 0x201, 0x74, 0x327, 0x201, 0x54, 0x30c,
+ 0x201, 0x74, 0x30c, 0x201, 0x55, 0x303, 0x201, 0x75,
+ 0x303, 0x201, 0x55, 0x304, 0x201, 0x75, 0x304, 0x201,
+ 0x55, 0x306, 0x201, 0x75, 0x306, 0x201, 0x55, 0x30a,
+ 0x201, 0x75, 0x30a, 0x201, 0x55, 0x30b, 0x201, 0x75,
+ 0x30b, 0x201, 0x55, 0x328, 0x201, 0x75, 0x328, 0x201,
+ 0x57, 0x302, 0x201, 0x77, 0x302, 0x201, 0x59, 0x302,
+ 0x201, 0x79, 0x302, 0x201, 0x59, 0x308, 0x201, 0x5a,
+ 0x301, 0x201, 0x7a, 0x301, 0x201, 0x5a, 0x307, 0x201,
+ 0x7a, 0x307, 0x201, 0x5a, 0x30c, 0x201, 0x7a, 0x30c,
+ 0x110, 0x73, 0x201, 0x4f, 0x31b, 0x201, 0x6f, 0x31b,
+ 0x201, 0x55, 0x31b, 0x201, 0x75, 0x31b, 0x210, 0x44,
+ 0x17d, 0x210, 0x44, 0x17e, 0x210, 0x64, 0x17e, 0x210,
+ 0x4c, 0x4a, 0x210, 0x4c, 0x6a, 0x210, 0x6c, 0x6a,
+ 0x210, 0x4e, 0x4a, 0x210, 0x4e, 0x6a, 0x210, 0x6e,
+ 0x6a, 0x201, 0x41, 0x30c, 0x201, 0x61, 0x30c, 0x201,
+ 0x49, 0x30c, 0x201, 0x69, 0x30c, 0x201, 0x4f, 0x30c,
+ 0x201, 0x6f, 0x30c, 0x201, 0x55, 0x30c, 0x201, 0x75,
+ 0x30c, 0x201, 0xdc, 0x304, 0x201, 0xfc, 0x304, 0x201,
+ 0xdc, 0x301, 0x201, 0xfc, 0x301, 0x201, 0xdc, 0x30c,
+ 0x201, 0xfc, 0x30c, 0x201, 0xdc, 0x300, 0x201, 0xfc,
+ 0x300, 0x201, 0xc4, 0x304, 0x201, 0xe4, 0x304, 0x201,
+ 0x226, 0x304, 0x201, 0x227, 0x304, 0x201, 0xc6, 0x304,
+ 0x201, 0xe6, 0x304, 0x201, 0x47, 0x30c, 0x201, 0x67,
+ 0x30c, 0x201, 0x4b, 0x30c, 0x201, 0x6b, 0x30c, 0x201,
+ 0x4f, 0x328, 0x201, 0x6f, 0x328, 0x201, 0x1ea, 0x304,
+ 0x201, 0x1eb, 0x304, 0x201, 0x1b7, 0x30c, 0x201, 0x292,
+ 0x30c, 0x201, 0x6a, 0x30c, 0x210, 0x44, 0x5a, 0x210,
+ 0x44, 0x7a, 0x210, 0x64, 0x7a, 0x201, 0x47, 0x301,
+ 0x201, 0x67, 0x301, 0x201, 0x4e, 0x300, 0x201, 0x6e,
+ 0x300, 0x201, 0xc5, 0x301, 0x201, 0xe5, 0x301, 0x201,
+ 0xc6, 0x301, 0x201, 0xe6, 0x301, 0x201, 0xd8, 0x301,
+ 0x201, 0xf8, 0x301, 0x201, 0x41, 0x30f, 0x201, 0x61,
+ 0x30f, 0x201, 0x41, 0x311, 0x201, 0x61, 0x311, 0x201,
+ 0x45, 0x30f, 0x201, 0x65, 0x30f, 0x201, 0x45, 0x311,
+ 0x201, 0x65, 0x311, 0x201, 0x49, 0x30f, 0x201, 0x69,
+ 0x30f, 0x201, 0x49, 0x311, 0x201, 0x69, 0x311, 0x201,
+ 0x4f, 0x30f, 0x201, 0x6f, 0x30f, 0x201, 0x4f, 0x311,
+ 0x201, 0x6f, 0x311, 0x201, 0x52, 0x30f, 0x201, 0x72,
+ 0x30f, 0x201, 0x52, 0x311, 0x201, 0x72, 0x311, 0x201,
+ 0x55, 0x30f, 0x201, 0x75, 0x30f, 0x201, 0x55, 0x311,
+ 0x201, 0x75, 0x311, 0x201, 0x53, 0x326, 0x201, 0x73,
+ 0x326, 0x201, 0x54, 0x326, 0x201, 0x74, 0x326, 0x201,
+ 0x48, 0x30c, 0x201, 0x68, 0x30c, 0x201, 0x41, 0x307,
+ 0x201, 0x61, 0x307, 0x201, 0x45, 0x327, 0x201, 0x65,
+ 0x327, 0x201, 0xd6, 0x304, 0x201, 0xf6, 0x304, 0x201,
+ 0xd5, 0x304, 0x201, 0xf5, 0x304, 0x201, 0x4f, 0x307,
+ 0x201, 0x6f, 0x307, 0x201, 0x22e, 0x304, 0x201, 0x22f,
+ 0x304, 0x201, 0x59, 0x304, 0x201, 0x79, 0x304, 0x109,
+ 0x68, 0x109, 0x266, 0x109, 0x6a, 0x109, 0x72, 0x109,
+ 0x279, 0x109, 0x27b, 0x109, 0x281, 0x109, 0x77, 0x109,
+ 0x79, 0x210, 0x20, 0x306, 0x210, 0x20, 0x307, 0x210,
+ 0x20, 0x30a, 0x210, 0x20, 0x328, 0x210, 0x20, 0x303,
+ 0x210, 0x20, 0x30b, 0x109, 0x263, 0x109, 0x6c, 0x109,
+ 0x73, 0x109, 0x78, 0x109, 0x295, 0x101, 0x300, 0x101,
+ 0x301, 0x101, 0x313, 0x201, 0x308, 0x301, 0x101, 0x2b9,
+ 0x210, 0x20, 0x345, 0x101, 0x3b, 0x210, 0x20, 0x301,
+ 0x201, 0xa8, 0x301, 0x201, 0x391, 0x301, 0x101, 0xb7,
+ 0x201, 0x395, 0x301, 0x201, 0x397, 0x301, 0x201, 0x399,
+ 0x301, 0x201, 0x39f, 0x301, 0x201, 0x3a5, 0x301, 0x201,
+ 0x3a9, 0x301, 0x201, 0x3ca, 0x301, 0x201, 0x399, 0x308,
+ 0x201, 0x3a5, 0x308, 0x201, 0x3b1, 0x301, 0x201, 0x3b5,
+ 0x301, 0x201, 0x3b7, 0x301, 0x201, 0x3b9, 0x301, 0x201,
+ 0x3cb, 0x301, 0x201, 0x3b9, 0x308, 0x201, 0x3c5, 0x308,
+ 0x201, 0x3bf, 0x301, 0x201, 0x3c5, 0x301, 0x201, 0x3c9,
+ 0x301, 0x110, 0x3b2, 0x110, 0x3b8, 0x110, 0x3a5, 0x201,
+ 0x3d2, 0x301, 0x201, 0x3d2, 0x308, 0x110, 0x3c6, 0x110,
+ 0x3c0, 0x110, 0x3ba, 0x110, 0x3c1, 0x110, 0x3c2, 0x110,
+ 0x398, 0x110, 0x3b5, 0x110, 0x3a3, 0x201, 0x415, 0x300,
+ 0x201, 0x415, 0x308, 0x201, 0x413, 0x301, 0x201, 0x406,
+ 0x308, 0x201, 0x41a, 0x301, 0x201, 0x418, 0x300, 0x201,
+ 0x423, 0x306, 0x201, 0x418, 0x306, 0x201, 0x438, 0x306,
+ 0x201, 0x435, 0x300, 0x201, 0x435, 0x308, 0x201, 0x433,
+ 0x301, 0x201, 0x456, 0x308, 0x201, 0x43a, 0x301, 0x201,
+ 0x438, 0x300, 0x201, 0x443, 0x306, 0x201, 0x474, 0x30f,
+ 0x201, 0x475, 0x30f, 0x201, 0x416, 0x306, 0x201, 0x436,
+ 0x306, 0x201, 0x410, 0x306, 0x201, 0x430, 0x306, 0x201,
+ 0x410, 0x308, 0x201, 0x430, 0x308, 0x201, 0x415, 0x306,
+ 0x201, 0x435, 0x306, 0x201, 0x4d8, 0x308, 0x201, 0x4d9,
+ 0x308, 0x201, 0x416, 0x308, 0x201, 0x436, 0x308, 0x201,
+ 0x417, 0x308, 0x201, 0x437, 0x308, 0x201, 0x418, 0x304,
+ 0x201, 0x438, 0x304, 0x201, 0x418, 0x308, 0x201, 0x438,
+ 0x308, 0x201, 0x41e, 0x308, 0x201, 0x43e, 0x308, 0x201,
+ 0x4e8, 0x308, 0x201, 0x4e9, 0x308, 0x201, 0x42d, 0x308,
+ 0x201, 0x44d, 0x308, 0x201, 0x423, 0x304, 0x201, 0x443,
+ 0x304, 0x201, 0x423, 0x308, 0x201, 0x443, 0x308, 0x201,
+ 0x423, 0x30b, 0x201, 0x443, 0x30b, 0x201, 0x427, 0x308,
+ 0x201, 0x447, 0x308, 0x201, 0x42b, 0x308, 0x201, 0x44b,
+ 0x308, 0x210, 0x565, 0x582, 0x201, 0x627, 0x653, 0x201,
+ 0x627, 0x654, 0x201, 0x648, 0x654, 0x201, 0x627, 0x655,
+ 0x201, 0x64a, 0x654, 0x210, 0x627, 0x674, 0x210, 0x648,
+ 0x674, 0x210, 0x6c7, 0x674, 0x210, 0x64a, 0x674, 0x201,
+ 0x6d5, 0x654, 0x201, 0x6c1, 0x654, 0x201, 0x6d2, 0x654,
+ 0x201, 0x928, 0x93c, 0x201, 0x930, 0x93c, 0x201, 0x933,
+ 0x93c, 0x201, 0x915, 0x93c, 0x201, 0x916, 0x93c, 0x201,
+ 0x917, 0x93c, 0x201, 0x91c, 0x93c, 0x201, 0x921, 0x93c,
+ 0x201, 0x922, 0x93c, 0x201, 0x92b, 0x93c, 0x201, 0x92f,
+ 0x93c, 0x201, 0x9c7, 0x9be, 0x201, 0x9c7, 0x9d7, 0x201,
+ 0x9a1, 0x9bc, 0x201, 0x9a2, 0x9bc, 0x201, 0x9af, 0x9bc,
+ 0x201, 0xa32, 0xa3c, 0x201, 0xa38, 0xa3c, 0x201, 0xa16,
+ 0xa3c, 0x201, 0xa17, 0xa3c, 0x201, 0xa1c, 0xa3c, 0x201,
+ 0xa2b, 0xa3c, 0x201, 0xb47, 0xb56, 0x201, 0xb47, 0xb3e,
+ 0x201, 0xb47, 0xb57, 0x201, 0xb21, 0xb3c, 0x201, 0xb22,
+ 0xb3c, 0x201, 0xb92, 0xbd7, 0x201, 0xbc6, 0xbbe, 0x201,
+ 0xbc7, 0xbbe, 0x201, 0xbc6, 0xbd7, 0x201, 0xc46, 0xc56,
+ 0x201, 0xcbf, 0xcd5, 0x201, 0xcc6, 0xcd5, 0x201, 0xcc6,
+ 0xcd6, 0x201, 0xcc6, 0xcc2, 0x201, 0xcca, 0xcd5, 0x201,
+ 0xd46, 0xd3e, 0x201, 0xd47, 0xd3e, 0x201, 0xd46, 0xd57,
+ 0x201, 0xdd9, 0xdca, 0x201, 0xdd9, 0xdcf, 0x201, 0xddc,
+ 0xdca, 0x201, 0xdd9, 0xddf, 0x210, 0xe4d, 0xe32, 0x210,
+ 0xecd, 0xeb2, 0x210, 0xeab, 0xe99, 0x210, 0xeab, 0xea1,
+ 0x103, 0xf0b, 0x201, 0xf42, 0xfb7, 0x201, 0xf4c, 0xfb7,
+ 0x201, 0xf51, 0xfb7, 0x201, 0xf56, 0xfb7, 0x201, 0xf5b,
+ 0xfb7, 0x201, 0xf40, 0xfb5, 0x201, 0xf71, 0xf72, 0x201,
+ 0xf71, 0xf74, 0x201, 0xfb2, 0xf80, 0x210, 0xfb2, 0xf81,
+ 0x201, 0xfb3, 0xf80, 0x210, 0xfb3, 0xf81, 0x201, 0xf71,
+ 0xf80, 0x201, 0xf92, 0xfb7, 0x201, 0xf9c, 0xfb7, 0x201,
+ 0xfa1, 0xfb7, 0x201, 0xfa6, 0xfb7, 0x201, 0xfab, 0xfb7,
+ 0x201, 0xf90, 0xfb5, 0x201, 0x1025, 0x102e, 0x109, 0x10dc,
+ 0x201, 0x1b05, 0x1b35, 0x201, 0x1b07, 0x1b35, 0x201, 0x1b09,
+ 0x1b35, 0x201, 0x1b0b, 0x1b35, 0x201, 0x1b0d, 0x1b35, 0x201,
+ 0x1b11, 0x1b35, 0x201, 0x1b3a, 0x1b35, 0x201, 0x1b3c, 0x1b35,
+ 0x201, 0x1b3e, 0x1b35, 0x201, 0x1b3f, 0x1b35, 0x201, 0x1b42,
+ 0x1b35, 0x109, 0x41, 0x109, 0xc6, 0x109, 0x42, 0x109,
+ 0x44, 0x109, 0x45, 0x109, 0x18e, 0x109, 0x47, 0x109,
+ 0x48, 0x109, 0x49, 0x109, 0x4a, 0x109, 0x4b, 0x109,
+ 0x4c, 0x109, 0x4d, 0x109, 0x4e, 0x109, 0x4f, 0x109,
+ 0x222, 0x109, 0x50, 0x109, 0x52, 0x109, 0x54, 0x109,
+ 0x55, 0x109, 0x57, 0x109, 0x61, 0x109, 0x250, 0x109,
+ 0x251, 0x109, 0x1d02, 0x109, 0x62, 0x109, 0x64, 0x109,
+ 0x65, 0x109, 0x259, 0x109, 0x25b, 0x109, 0x25c, 0x109,
+ 0x67, 0x109, 0x6b, 0x109, 0x6d, 0x109, 0x14b, 0x109,
+ 0x6f, 0x109, 0x254, 0x109, 0x1d16, 0x109, 0x1d17, 0x109,
+ 0x70, 0x109, 0x74, 0x109, 0x75, 0x109, 0x1d1d, 0x109,
+ 0x26f, 0x109, 0x76, 0x109, 0x1d25, 0x109, 0x3b2, 0x109,
+ 0x3b3, 0x109, 0x3b4, 0x109, 0x3c6, 0x109, 0x3c7, 0x10a,
+ 0x69, 0x10a, 0x72, 0x10a, 0x75, 0x10a, 0x76, 0x10a,
+ 0x3b2, 0x10a, 0x3b3, 0x10a, 0x3c1, 0x10a, 0x3c6, 0x10a,
+ 0x3c7, 0x109, 0x43d, 0x109, 0x252, 0x109, 0x63, 0x109,
+ 0x255, 0x109, 0xf0, 0x109, 0x25c, 0x109, 0x66, 0x109,
+ 0x25f, 0x109, 0x261, 0x109, 0x265, 0x109, 0x268, 0x109,
+ 0x269, 0x109, 0x26a, 0x109, 0x1d7b, 0x109, 0x29d, 0x109,
+ 0x26d, 0x109, 0x1d85, 0x109, 0x29f, 0x109, 0x271, 0x109,
+ 0x270, 0x109, 0x272, 0x109, 0x273, 0x109, 0x274, 0x109,
+ 0x275, 0x109, 0x278, 0x109, 0x282, 0x109, 0x283, 0x109,
+ 0x1ab, 0x109, 0x289, 0x109, 0x28a, 0x109, 0x1d1c, 0x109,
+ 0x28b, 0x109, 0x28c, 0x109, 0x7a, 0x109, 0x290, 0x109,
+ 0x291, 0x109, 0x292, 0x109, 0x3b8, 0x201, 0x41, 0x325,
+ 0x201, 0x61, 0x325, 0x201, 0x42, 0x307, 0x201, 0x62,
+ 0x307, 0x201, 0x42, 0x323, 0x201, 0x62, 0x323, 0x201,
+ 0x42, 0x331, 0x201, 0x62, 0x331, 0x201, 0xc7, 0x301,
+ 0x201, 0xe7, 0x301, 0x201, 0x44, 0x307, 0x201, 0x64,
+ 0x307, 0x201, 0x44, 0x323, 0x201, 0x64, 0x323, 0x201,
+ 0x44, 0x331, 0x201, 0x64, 0x331, 0x201, 0x44, 0x327,
+ 0x201, 0x64, 0x327, 0x201, 0x44, 0x32d, 0x201, 0x64,
+ 0x32d, 0x201, 0x112, 0x300, 0x201, 0x113, 0x300, 0x201,
+ 0x112, 0x301, 0x201, 0x113, 0x301, 0x201, 0x45, 0x32d,
+ 0x201, 0x65, 0x32d, 0x201, 0x45, 0x330, 0x201, 0x65,
+ 0x330, 0x201, 0x228, 0x306, 0x201, 0x229, 0x306, 0x201,
+ 0x46, 0x307, 0x201, 0x66, 0x307, 0x201, 0x47, 0x304,
+ 0x201, 0x67, 0x304, 0x201, 0x48, 0x307, 0x201, 0x68,
+ 0x307, 0x201, 0x48, 0x323, 0x201, 0x68, 0x323, 0x201,
+ 0x48, 0x308, 0x201, 0x68, 0x308, 0x201, 0x48, 0x327,
+ 0x201, 0x68, 0x327, 0x201, 0x48, 0x32e, 0x201, 0x68,
+ 0x32e, 0x201, 0x49, 0x330, 0x201, 0x69, 0x330, 0x201,
+ 0xcf, 0x301, 0x201, 0xef, 0x301, 0x201, 0x4b, 0x301,
+ 0x201, 0x6b, 0x301, 0x201, 0x4b, 0x323, 0x201, 0x6b,
+ 0x323, 0x201, 0x4b, 0x331, 0x201, 0x6b, 0x331, 0x201,
+ 0x4c, 0x323, 0x201, 0x6c, 0x323, 0x201, 0x1e36, 0x304,
+ 0x201, 0x1e37, 0x304, 0x201, 0x4c, 0x331, 0x201, 0x6c,
+ 0x331, 0x201, 0x4c, 0x32d, 0x201, 0x6c, 0x32d, 0x201,
+ 0x4d, 0x301, 0x201, 0x6d, 0x301, 0x201, 0x4d, 0x307,
+ 0x201, 0x6d, 0x307, 0x201, 0x4d, 0x323, 0x201, 0x6d,
+ 0x323, 0x201, 0x4e, 0x307, 0x201, 0x6e, 0x307, 0x201,
+ 0x4e, 0x323, 0x201, 0x6e, 0x323, 0x201, 0x4e, 0x331,
+ 0x201, 0x6e, 0x331, 0x201, 0x4e, 0x32d, 0x201, 0x6e,
+ 0x32d, 0x201, 0xd5, 0x301, 0x201, 0xf5, 0x301, 0x201,
+ 0xd5, 0x308, 0x201, 0xf5, 0x308, 0x201, 0x14c, 0x300,
+ 0x201, 0x14d, 0x300, 0x201, 0x14c, 0x301, 0x201, 0x14d,
+ 0x301, 0x201, 0x50, 0x301, 0x201, 0x70, 0x301, 0x201,
+ 0x50, 0x307, 0x201, 0x70, 0x307, 0x201, 0x52, 0x307,
+ 0x201, 0x72, 0x307, 0x201, 0x52, 0x323, 0x201, 0x72,
+ 0x323, 0x201, 0x1e5a, 0x304, 0x201, 0x1e5b, 0x304, 0x201,
+ 0x52, 0x331, 0x201, 0x72, 0x331, 0x201, 0x53, 0x307,
+ 0x201, 0x73, 0x307, 0x201, 0x53, 0x323, 0x201, 0x73,
+ 0x323, 0x201, 0x15a, 0x307, 0x201, 0x15b, 0x307, 0x201,
+ 0x160, 0x307, 0x201, 0x161, 0x307, 0x201, 0x1e62, 0x307,
+ 0x201, 0x1e63, 0x307, 0x201, 0x54, 0x307, 0x201, 0x74,
+ 0x307, 0x201, 0x54, 0x323, 0x201, 0x74, 0x323, 0x201,
+ 0x54, 0x331, 0x201, 0x74, 0x331, 0x201, 0x54, 0x32d,
+ 0x201, 0x74, 0x32d, 0x201, 0x55, 0x324, 0x201, 0x75,
+ 0x324, 0x201, 0x55, 0x330, 0x201, 0x75, 0x330, 0x201,
+ 0x55, 0x32d, 0x201, 0x75, 0x32d, 0x201, 0x168, 0x301,
+ 0x201, 0x169, 0x301, 0x201, 0x16a, 0x308, 0x201, 0x16b,
+ 0x308, 0x201, 0x56, 0x303, 0x201, 0x76, 0x303, 0x201,
+ 0x56, 0x323, 0x201, 0x76, 0x323, 0x201, 0x57, 0x300,
+ 0x201, 0x77, 0x300, 0x201, 0x57, 0x301, 0x201, 0x77,
+ 0x301, 0x201, 0x57, 0x308, 0x201, 0x77, 0x308, 0x201,
+ 0x57, 0x307, 0x201, 0x77, 0x307, 0x201, 0x57, 0x323,
+ 0x201, 0x77, 0x323, 0x201, 0x58, 0x307, 0x201, 0x78,
+ 0x307, 0x201, 0x58, 0x308, 0x201, 0x78, 0x308, 0x201,
+ 0x59, 0x307, 0x201, 0x79, 0x307, 0x201, 0x5a, 0x302,
+ 0x201, 0x7a, 0x302, 0x201, 0x5a, 0x323, 0x201, 0x7a,
+ 0x323, 0x201, 0x5a, 0x331, 0x201, 0x7a, 0x331, 0x201,
+ 0x68, 0x331, 0x201, 0x74, 0x308, 0x201, 0x77, 0x30a,
+ 0x201, 0x79, 0x30a, 0x210, 0x61, 0x2be, 0x201, 0x17f,
+ 0x307, 0x201, 0x41, 0x323, 0x201, 0x61, 0x323, 0x201,
+ 0x41, 0x309, 0x201, 0x61, 0x309, 0x201, 0xc2, 0x301,
+ 0x201, 0xe2, 0x301, 0x201, 0xc2, 0x300, 0x201, 0xe2,
+ 0x300, 0x201, 0xc2, 0x309, 0x201, 0xe2, 0x309, 0x201,
+ 0xc2, 0x303, 0x201, 0xe2, 0x303, 0x201, 0x1ea0, 0x302,
+ 0x201, 0x1ea1, 0x302, 0x201, 0x102, 0x301, 0x201, 0x103,
+ 0x301, 0x201, 0x102, 0x300, 0x201, 0x103, 0x300, 0x201,
+ 0x102, 0x309, 0x201, 0x103, 0x309, 0x201, 0x102, 0x303,
+ 0x201, 0x103, 0x303, 0x201, 0x1ea0, 0x306, 0x201, 0x1ea1,
+ 0x306, 0x201, 0x45, 0x323, 0x201, 0x65, 0x323, 0x201,
+ 0x45, 0x309, 0x201, 0x65, 0x309, 0x201, 0x45, 0x303,
+ 0x201, 0x65, 0x303, 0x201, 0xca, 0x301, 0x201, 0xea,
+ 0x301, 0x201, 0xca, 0x300, 0x201, 0xea, 0x300, 0x201,
+ 0xca, 0x309, 0x201, 0xea, 0x309, 0x201, 0xca, 0x303,
+ 0x201, 0xea, 0x303, 0x201, 0x1eb8, 0x302, 0x201, 0x1eb9,
+ 0x302, 0x201, 0x49, 0x309, 0x201, 0x69, 0x309, 0x201,
+ 0x49, 0x323, 0x201, 0x69, 0x323, 0x201, 0x4f, 0x323,
+ 0x201, 0x6f, 0x323, 0x201, 0x4f, 0x309, 0x201, 0x6f,
+ 0x309, 0x201, 0xd4, 0x301, 0x201, 0xf4, 0x301, 0x201,
+ 0xd4, 0x300, 0x201, 0xf4, 0x300, 0x201, 0xd4, 0x309,
+ 0x201, 0xf4, 0x309, 0x201, 0xd4, 0x303, 0x201, 0xf4,
+ 0x303, 0x201, 0x1ecc, 0x302, 0x201, 0x1ecd, 0x302, 0x201,
+ 0x1a0, 0x301, 0x201, 0x1a1, 0x301, 0x201, 0x1a0, 0x300,
+ 0x201, 0x1a1, 0x300, 0x201, 0x1a0, 0x309, 0x201, 0x1a1,
+ 0x309, 0x201, 0x1a0, 0x303, 0x201, 0x1a1, 0x303, 0x201,
+ 0x1a0, 0x323, 0x201, 0x1a1, 0x323, 0x201, 0x55, 0x323,
+ 0x201, 0x75, 0x323, 0x201, 0x55, 0x309, 0x201, 0x75,
+ 0x309, 0x201, 0x1af, 0x301, 0x201, 0x1b0, 0x301, 0x201,
+ 0x1af, 0x300, 0x201, 0x1b0, 0x300, 0x201, 0x1af, 0x309,
+ 0x201, 0x1b0, 0x309, 0x201, 0x1af, 0x303, 0x201, 0x1b0,
+ 0x303, 0x201, 0x1af, 0x323, 0x201, 0x1b0, 0x323, 0x201,
+ 0x59, 0x300, 0x201, 0x79, 0x300, 0x201, 0x59, 0x323,
+ 0x201, 0x79, 0x323, 0x201, 0x59, 0x309, 0x201, 0x79,
+ 0x309, 0x201, 0x59, 0x303, 0x201, 0x79, 0x303, 0x201,
+ 0x3b1, 0x313, 0x201, 0x3b1, 0x314, 0x201, 0x1f00, 0x300,
+ 0x201, 0x1f01, 0x300, 0x201, 0x1f00, 0x301, 0x201, 0x1f01,
+ 0x301, 0x201, 0x1f00, 0x342, 0x201, 0x1f01, 0x342, 0x201,
+ 0x391, 0x313, 0x201, 0x391, 0x314, 0x201, 0x1f08, 0x300,
+ 0x201, 0x1f09, 0x300, 0x201, 0x1f08, 0x301, 0x201, 0x1f09,
+ 0x301, 0x201, 0x1f08, 0x342, 0x201, 0x1f09, 0x342, 0x201,
+ 0x3b5, 0x313, 0x201, 0x3b5, 0x314, 0x201, 0x1f10, 0x300,
+ 0x201, 0x1f11, 0x300, 0x201, 0x1f10, 0x301, 0x201, 0x1f11,
+ 0x301, 0x201, 0x395, 0x313, 0x201, 0x395, 0x314, 0x201,
+ 0x1f18, 0x300, 0x201, 0x1f19, 0x300, 0x201, 0x1f18, 0x301,
+ 0x201, 0x1f19, 0x301, 0x201, 0x3b7, 0x313, 0x201, 0x3b7,
+ 0x314, 0x201, 0x1f20, 0x300, 0x201, 0x1f21, 0x300, 0x201,
+ 0x1f20, 0x301, 0x201, 0x1f21, 0x301, 0x201, 0x1f20, 0x342,
+ 0x201, 0x1f21, 0x342, 0x201, 0x397, 0x313, 0x201, 0x397,
+ 0x314, 0x201, 0x1f28, 0x300, 0x201, 0x1f29, 0x300, 0x201,
+ 0x1f28, 0x301, 0x201, 0x1f29, 0x301, 0x201, 0x1f28, 0x342,
+ 0x201, 0x1f29, 0x342, 0x201, 0x3b9, 0x313, 0x201, 0x3b9,
+ 0x314, 0x201, 0x1f30, 0x300, 0x201, 0x1f31, 0x300, 0x201,
+ 0x1f30, 0x301, 0x201, 0x1f31, 0x301, 0x201, 0x1f30, 0x342,
+ 0x201, 0x1f31, 0x342, 0x201, 0x399, 0x313, 0x201, 0x399,
+ 0x314, 0x201, 0x1f38, 0x300, 0x201, 0x1f39, 0x300, 0x201,
+ 0x1f38, 0x301, 0x201, 0x1f39, 0x301, 0x201, 0x1f38, 0x342,
+ 0x201, 0x1f39, 0x342, 0x201, 0x3bf, 0x313, 0x201, 0x3bf,
+ 0x314, 0x201, 0x1f40, 0x300, 0x201, 0x1f41, 0x300, 0x201,
+ 0x1f40, 0x301, 0x201, 0x1f41, 0x301, 0x201, 0x39f, 0x313,
+ 0x201, 0x39f, 0x314, 0x201, 0x1f48, 0x300, 0x201, 0x1f49,
+ 0x300, 0x201, 0x1f48, 0x301, 0x201, 0x1f49, 0x301, 0x201,
+ 0x3c5, 0x313, 0x201, 0x3c5, 0x314, 0x201, 0x1f50, 0x300,
+ 0x201, 0x1f51, 0x300, 0x201, 0x1f50, 0x301, 0x201, 0x1f51,
+ 0x301, 0x201, 0x1f50, 0x342, 0x201, 0x1f51, 0x342, 0x201,
+ 0x3a5, 0x314, 0x201, 0x1f59, 0x300, 0x201, 0x1f59, 0x301,
+ 0x201, 0x1f59, 0x342, 0x201, 0x3c9, 0x313, 0x201, 0x3c9,
+ 0x314, 0x201, 0x1f60, 0x300, 0x201, 0x1f61, 0x300, 0x201,
+ 0x1f60, 0x301, 0x201, 0x1f61, 0x301, 0x201, 0x1f60, 0x342,
+ 0x201, 0x1f61, 0x342, 0x201, 0x3a9, 0x313, 0x201, 0x3a9,
+ 0x314, 0x201, 0x1f68, 0x300, 0x201, 0x1f69, 0x300, 0x201,
+ 0x1f68, 0x301, 0x201, 0x1f69, 0x301, 0x201, 0x1f68, 0x342,
+ 0x201, 0x1f69, 0x342, 0x201, 0x3b1, 0x300, 0x101, 0x3ac,
+ 0x201, 0x3b5, 0x300, 0x101, 0x3ad, 0x201, 0x3b7, 0x300,
+ 0x101, 0x3ae, 0x201, 0x3b9, 0x300, 0x101, 0x3af, 0x201,
+ 0x3bf, 0x300, 0x101, 0x3cc, 0x201, 0x3c5, 0x300, 0x101,
+ 0x3cd, 0x201, 0x3c9, 0x300, 0x101, 0x3ce, 0x201, 0x1f00,
+ 0x345, 0x201, 0x1f01, 0x345, 0x201, 0x1f02, 0x345, 0x201,
+ 0x1f03, 0x345, 0x201, 0x1f04, 0x345, 0x201, 0x1f05, 0x345,
+ 0x201, 0x1f06, 0x345, 0x201, 0x1f07, 0x345, 0x201, 0x1f08,
+ 0x345, 0x201, 0x1f09, 0x345, 0x201, 0x1f0a, 0x345, 0x201,
+ 0x1f0b, 0x345, 0x201, 0x1f0c, 0x345, 0x201, 0x1f0d, 0x345,
+ 0x201, 0x1f0e, 0x345, 0x201, 0x1f0f, 0x345, 0x201, 0x1f20,
+ 0x345, 0x201, 0x1f21, 0x345, 0x201, 0x1f22, 0x345, 0x201,
+ 0x1f23, 0x345, 0x201, 0x1f24, 0x345, 0x201, 0x1f25, 0x345,
+ 0x201, 0x1f26, 0x345, 0x201, 0x1f27, 0x345, 0x201, 0x1f28,
+ 0x345, 0x201, 0x1f29, 0x345, 0x201, 0x1f2a, 0x345, 0x201,
+ 0x1f2b, 0x345, 0x201, 0x1f2c, 0x345, 0x201, 0x1f2d, 0x345,
+ 0x201, 0x1f2e, 0x345, 0x201, 0x1f2f, 0x345, 0x201, 0x1f60,
+ 0x345, 0x201, 0x1f61, 0x345, 0x201, 0x1f62, 0x345, 0x201,
+ 0x1f63, 0x345, 0x201, 0x1f64, 0x345, 0x201, 0x1f65, 0x345,
+ 0x201, 0x1f66, 0x345, 0x201, 0x1f67, 0x345, 0x201, 0x1f68,
+ 0x345, 0x201, 0x1f69, 0x345, 0x201, 0x1f6a, 0x345, 0x201,
+ 0x1f6b, 0x345, 0x201, 0x1f6c, 0x345, 0x201, 0x1f6d, 0x345,
+ 0x201, 0x1f6e, 0x345, 0x201, 0x1f6f, 0x345, 0x201, 0x3b1,
+ 0x306, 0x201, 0x3b1, 0x304, 0x201, 0x1f70, 0x345, 0x201,
+ 0x3b1, 0x345, 0x201, 0x3ac, 0x345, 0x201, 0x3b1, 0x342,
+ 0x201, 0x1fb6, 0x345, 0x201, 0x391, 0x306, 0x201, 0x391,
+ 0x304, 0x201, 0x391, 0x300, 0x101, 0x386, 0x201, 0x391,
+ 0x345, 0x210, 0x20, 0x313, 0x101, 0x3b9, 0x210, 0x20,
+ 0x313, 0x210, 0x20, 0x342, 0x201, 0xa8, 0x342, 0x201,
+ 0x1f74, 0x345, 0x201, 0x3b7, 0x345, 0x201, 0x3ae, 0x345,
+ 0x201, 0x3b7, 0x342, 0x201, 0x1fc6, 0x345, 0x201, 0x395,
+ 0x300, 0x101, 0x388, 0x201, 0x397, 0x300, 0x101, 0x389,
+ 0x201, 0x397, 0x345, 0x201, 0x1fbf, 0x300, 0x201, 0x1fbf,
+ 0x301, 0x201, 0x1fbf, 0x342, 0x201, 0x3b9, 0x306, 0x201,
+ 0x3b9, 0x304, 0x201, 0x3ca, 0x300, 0x101, 0x390, 0x201,
+ 0x3b9, 0x342, 0x201, 0x3ca, 0x342, 0x201, 0x399, 0x306,
+ 0x201, 0x399, 0x304, 0x201, 0x399, 0x300, 0x101, 0x38a,
+ 0x201, 0x1ffe, 0x300, 0x201, 0x1ffe, 0x301, 0x201, 0x1ffe,
+ 0x342, 0x201, 0x3c5, 0x306, 0x201, 0x3c5, 0x304, 0x201,
+ 0x3cb, 0x300, 0x101, 0x3b0, 0x201, 0x3c1, 0x313, 0x201,
+ 0x3c1, 0x314, 0x201, 0x3c5, 0x342, 0x201, 0x3cb, 0x342,
+ 0x201, 0x3a5, 0x306, 0x201, 0x3a5, 0x304, 0x201, 0x3a5,
+ 0x300, 0x101, 0x38e, 0x201, 0x3a1, 0x314, 0x201, 0xa8,
+ 0x300, 0x101, 0x385, 0x101, 0x60, 0x201, 0x1f7c, 0x345,
+ 0x201, 0x3c9, 0x345, 0x201, 0x3ce, 0x345, 0x201, 0x3c9,
+ 0x342, 0x201, 0x1ff6, 0x345, 0x201, 0x39f, 0x300, 0x101,
+ 0x38c, 0x201, 0x3a9, 0x300, 0x101, 0x38f, 0x201, 0x3a9,
+ 0x345, 0x101, 0xb4, 0x210, 0x20, 0x314, 0x101, 0x2002,
+ 0x101, 0x2003, 0x110, 0x20, 0x110, 0x20, 0x110, 0x20,
+ 0x110, 0x20, 0x110, 0x20, 0x103, 0x20, 0x110, 0x20,
+ 0x110, 0x20, 0x110, 0x20, 0x103, 0x2010, 0x210, 0x20,
+ 0x333, 0x110, 0x2e, 0x210, 0x2e, 0x2e, 0x310, 0x2e,
+ 0x2e, 0x2e, 0x103, 0x20, 0x210, 0x2032, 0x2032, 0x310,
+ 0x2032, 0x2032, 0x2032, 0x210, 0x2035, 0x2035, 0x310, 0x2035,
+ 0x2035, 0x2035, 0x210, 0x21, 0x21, 0x210, 0x20, 0x305,
+ 0x210, 0x3f, 0x3f, 0x210, 0x3f, 0x21, 0x210, 0x21,
+ 0x3f, 0x410, 0x2032, 0x2032, 0x2032, 0x2032, 0x110, 0x20,
+ 0x109, 0x30, 0x109, 0x69, 0x109, 0x34, 0x109, 0x35,
+ 0x109, 0x36, 0x109, 0x37, 0x109, 0x38, 0x109, 0x39,
+ 0x109, 0x2b, 0x109, 0x2212, 0x109, 0x3d, 0x109, 0x28,
+ 0x109, 0x29, 0x109, 0x6e, 0x10a, 0x30, 0x10a, 0x31,
+ 0x10a, 0x32, 0x10a, 0x33, 0x10a, 0x34, 0x10a, 0x35,
+ 0x10a, 0x36, 0x10a, 0x37, 0x10a, 0x38, 0x10a, 0x39,
+ 0x10a, 0x2b, 0x10a, 0x2212, 0x10a, 0x3d, 0x10a, 0x28,
+ 0x10a, 0x29, 0x10a, 0x61, 0x10a, 0x65, 0x10a, 0x6f,
+ 0x10a, 0x78, 0x10a, 0x259, 0x210, 0x52, 0x73, 0x310,
+ 0x61, 0x2f, 0x63, 0x310, 0x61, 0x2f, 0x73, 0x102,
+ 0x43, 0x210, 0xb0, 0x43, 0x310, 0x63, 0x2f, 0x6f,
+ 0x310, 0x63, 0x2f, 0x75, 0x110, 0x190, 0x210, 0xb0,
+ 0x46, 0x102, 0x67, 0x102, 0x48, 0x102, 0x48, 0x102,
+ 0x48, 0x102, 0x68, 0x102, 0x127, 0x102, 0x49, 0x102,
+ 0x49, 0x102, 0x4c, 0x102, 0x6c, 0x102, 0x4e, 0x210,
+ 0x4e, 0x6f, 0x102, 0x50, 0x102, 0x51, 0x102, 0x52,
+ 0x102, 0x52, 0x102, 0x52, 0x209, 0x53, 0x4d, 0x310,
+ 0x54, 0x45, 0x4c, 0x209, 0x54, 0x4d, 0x102, 0x5a,
+ 0x101, 0x3a9, 0x102, 0x5a, 0x101, 0x4b, 0x101, 0xc5,
+ 0x102, 0x42, 0x102, 0x43, 0x102, 0x65, 0x102, 0x45,
+ 0x102, 0x46, 0x102, 0x4d, 0x102, 0x6f, 0x110, 0x5d0,
+ 0x110, 0x5d1, 0x110, 0x5d2, 0x110, 0x5d3, 0x102, 0x69,
+ 0x310, 0x46, 0x41, 0x58, 0x102, 0x3c0, 0x102, 0x3b3,
+ 0x102, 0x393, 0x102, 0x3a0, 0x102, 0x2211, 0x102, 0x44,
+ 0x102, 0x64, 0x102, 0x65, 0x102, 0x69, 0x102, 0x6a,
+ 0x311, 0x31, 0x2044, 0x33, 0x311, 0x32, 0x2044, 0x33,
+ 0x311, 0x31, 0x2044, 0x35, 0x311, 0x32, 0x2044, 0x35,
+ 0x311, 0x33, 0x2044, 0x35, 0x311, 0x34, 0x2044, 0x35,
+ 0x311, 0x31, 0x2044, 0x36, 0x311, 0x35, 0x2044, 0x36,
+ 0x311, 0x31, 0x2044, 0x38, 0x311, 0x33, 0x2044, 0x38,
+ 0x311, 0x35, 0x2044, 0x38, 0x311, 0x37, 0x2044, 0x38,
+ 0x211, 0x31, 0x2044, 0x110, 0x49, 0x210, 0x49, 0x49,
+ 0x310, 0x49, 0x49, 0x49, 0x210, 0x49, 0x56, 0x110,
+ 0x56, 0x210, 0x56, 0x49, 0x310, 0x56, 0x49, 0x49,
+ 0x410, 0x56, 0x49, 0x49, 0x49, 0x210, 0x49, 0x58,
+ 0x110, 0x58, 0x210, 0x58, 0x49, 0x310, 0x58, 0x49,
+ 0x49, 0x110, 0x4c, 0x110, 0x43, 0x110, 0x44, 0x110,
+ 0x4d, 0x110, 0x69, 0x210, 0x69, 0x69, 0x310, 0x69,
+ 0x69, 0x69, 0x210, 0x69, 0x76, 0x110, 0x76, 0x210,
+ 0x76, 0x69, 0x310, 0x76, 0x69, 0x69, 0x410, 0x76,
+ 0x69, 0x69, 0x69, 0x210, 0x69, 0x78, 0x110, 0x78,
+ 0x210, 0x78, 0x69, 0x310, 0x78, 0x69, 0x69, 0x110,
+ 0x6c, 0x110, 0x63, 0x110, 0x64, 0x110, 0x6d, 0x201,
+ 0x2190, 0x338, 0x201, 0x2192, 0x338, 0x201, 0x2194, 0x338,
+ 0x201, 0x21d0, 0x338, 0x201, 0x21d4, 0x338, 0x201, 0x21d2,
+ 0x338, 0x201, 0x2203, 0x338, 0x201, 0x2208, 0x338, 0x201,
+ 0x220b, 0x338, 0x201, 0x2223, 0x338, 0x201, 0x2225, 0x338,
+ 0x210, 0x222b, 0x222b, 0x310, 0x222b, 0x222b, 0x222b, 0x210,
+ 0x222e, 0x222e, 0x310, 0x222e, 0x222e, 0x222e, 0x201, 0x223c,
+ 0x338, 0x201, 0x2243, 0x338, 0x201, 0x2245, 0x338, 0x201,
+ 0x2248, 0x338, 0x201, 0x3d, 0x338, 0x201, 0x2261, 0x338,
+ 0x201, 0x224d, 0x338, 0x201, 0x3c, 0x338, 0x201, 0x3e,
+ 0x338, 0x201, 0x2264, 0x338, 0x201, 0x2265, 0x338, 0x201,
+ 0x2272, 0x338, 0x201, 0x2273, 0x338, 0x201, 0x2276, 0x338,
+ 0x201, 0x2277, 0x338, 0x201, 0x227a, 0x338, 0x201, 0x227b,
+ 0x338, 0x201, 0x2282, 0x338, 0x201, 0x2283, 0x338, 0x201,
+ 0x2286, 0x338, 0x201, 0x2287, 0x338, 0x201, 0x22a2, 0x338,
+ 0x201, 0x22a8, 0x338, 0x201, 0x22a9, 0x338, 0x201, 0x22ab,
+ 0x338, 0x201, 0x227c, 0x338, 0x201, 0x227d, 0x338, 0x201,
+ 0x2291, 0x338, 0x201, 0x2292, 0x338, 0x201, 0x22b2, 0x338,
+ 0x201, 0x22b3, 0x338, 0x201, 0x22b4, 0x338, 0x201, 0x22b5,
+ 0x338, 0x101, 0x3008, 0x101, 0x3009, 0x108, 0x31, 0x108,
+ 0x32, 0x108, 0x33, 0x108, 0x34, 0x108, 0x35, 0x108,
+ 0x36, 0x108, 0x37, 0x108, 0x38, 0x108, 0x39, 0x208,
+ 0x31, 0x30, 0x208, 0x31, 0x31, 0x208, 0x31, 0x32,
+ 0x208, 0x31, 0x33, 0x208, 0x31, 0x34, 0x208, 0x31,
+ 0x35, 0x208, 0x31, 0x36, 0x208, 0x31, 0x37, 0x208,
+ 0x31, 0x38, 0x208, 0x31, 0x39, 0x208, 0x32, 0x30,
+ 0x310, 0x28, 0x31, 0x29, 0x310, 0x28, 0x32, 0x29,
+ 0x310, 0x28, 0x33, 0x29, 0x310, 0x28, 0x34, 0x29,
+ 0x310, 0x28, 0x35, 0x29, 0x310, 0x28, 0x36, 0x29,
+ 0x310, 0x28, 0x37, 0x29, 0x310, 0x28, 0x38, 0x29,
+ 0x310, 0x28, 0x39, 0x29, 0x410, 0x28, 0x31, 0x30,
+ 0x29, 0x410, 0x28, 0x31, 0x31, 0x29, 0x410, 0x28,
+ 0x31, 0x32, 0x29, 0x410, 0x28, 0x31, 0x33, 0x29,
+ 0x410, 0x28, 0x31, 0x34, 0x29, 0x410, 0x28, 0x31,
+ 0x35, 0x29, 0x410, 0x28, 0x31, 0x36, 0x29, 0x410,
+ 0x28, 0x31, 0x37, 0x29, 0x410, 0x28, 0x31, 0x38,
+ 0x29, 0x410, 0x28, 0x31, 0x39, 0x29, 0x410, 0x28,
+ 0x32, 0x30, 0x29, 0x210, 0x31, 0x2e, 0x210, 0x32,
+ 0x2e, 0x210, 0x33, 0x2e, 0x210, 0x34, 0x2e, 0x210,
+ 0x35, 0x2e, 0x210, 0x36, 0x2e, 0x210, 0x37, 0x2e,
+ 0x210, 0x38, 0x2e, 0x210, 0x39, 0x2e, 0x310, 0x31,
+ 0x30, 0x2e, 0x310, 0x31, 0x31, 0x2e, 0x310, 0x31,
+ 0x32, 0x2e, 0x310, 0x31, 0x33, 0x2e, 0x310, 0x31,
+ 0x34, 0x2e, 0x310, 0x31, 0x35, 0x2e, 0x310, 0x31,
+ 0x36, 0x2e, 0x310, 0x31, 0x37, 0x2e, 0x310, 0x31,
+ 0x38, 0x2e, 0x310, 0x31, 0x39, 0x2e, 0x310, 0x32,
+ 0x30, 0x2e, 0x310, 0x28, 0x61, 0x29, 0x310, 0x28,
+ 0x62, 0x29, 0x310, 0x28, 0x63, 0x29, 0x310, 0x28,
+ 0x64, 0x29, 0x310, 0x28, 0x65, 0x29, 0x310, 0x28,
+ 0x66, 0x29, 0x310, 0x28, 0x67, 0x29, 0x310, 0x28,
+ 0x68, 0x29, 0x310, 0x28, 0x69, 0x29, 0x310, 0x28,
+ 0x6a, 0x29, 0x310, 0x28, 0x6b, 0x29, 0x310, 0x28,
+ 0x6c, 0x29, 0x310, 0x28, 0x6d, 0x29, 0x310, 0x28,
+ 0x6e, 0x29, 0x310, 0x28, 0x6f, 0x29, 0x310, 0x28,
+ 0x70, 0x29, 0x310, 0x28, 0x71, 0x29, 0x310, 0x28,
+ 0x72, 0x29, 0x310, 0x28, 0x73, 0x29, 0x310, 0x28,
+ 0x74, 0x29, 0x310, 0x28, 0x75, 0x29, 0x310, 0x28,
+ 0x76, 0x29, 0x310, 0x28, 0x77, 0x29, 0x310, 0x28,
+ 0x78, 0x29, 0x310, 0x28, 0x79, 0x29, 0x310, 0x28,
+ 0x7a, 0x29, 0x108, 0x41, 0x108, 0x42, 0x108, 0x43,
+ 0x108, 0x44, 0x108, 0x45, 0x108, 0x46, 0x108, 0x47,
+ 0x108, 0x48, 0x108, 0x49, 0x108, 0x4a, 0x108, 0x4b,
+ 0x108, 0x4c, 0x108, 0x4d, 0x108, 0x4e, 0x108, 0x4f,
+ 0x108, 0x50, 0x108, 0x51, 0x108, 0x52, 0x108, 0x53,
+ 0x108, 0x54, 0x108, 0x55, 0x108, 0x56, 0x108, 0x57,
+ 0x108, 0x58, 0x108, 0x59, 0x108, 0x5a, 0x108, 0x61,
+ 0x108, 0x62, 0x108, 0x63, 0x108, 0x64, 0x108, 0x65,
+ 0x108, 0x66, 0x108, 0x67, 0x108, 0x68, 0x108, 0x69,
+ 0x108, 0x6a, 0x108, 0x6b, 0x108, 0x6c, 0x108, 0x6d,
+ 0x108, 0x6e, 0x108, 0x6f, 0x108, 0x70, 0x108, 0x71,
+ 0x108, 0x72, 0x108, 0x73, 0x108, 0x74, 0x108, 0x75,
+ 0x108, 0x76, 0x108, 0x77, 0x108, 0x78, 0x108, 0x79,
+ 0x108, 0x7a, 0x108, 0x30, 0x410, 0x222b, 0x222b, 0x222b,
+ 0x222b, 0x310, 0x3a, 0x3a, 0x3d, 0x210, 0x3d, 0x3d,
+ 0x310, 0x3d, 0x3d, 0x3d, 0x201, 0x2add, 0x338, 0x109,
+ 0x2d61, 0x110, 0x6bcd, 0x110, 0x9f9f, 0x110, 0x4e00, 0x110,
+ 0x4e28, 0x110, 0x4e36, 0x110, 0x4e3f, 0x110, 0x4e59, 0x110,
+ 0x4e85, 0x110, 0x4e8c, 0x110, 0x4ea0, 0x110, 0x4eba, 0x110,
+ 0x513f, 0x110, 0x5165, 0x110, 0x516b, 0x110, 0x5182, 0x110,
+ 0x5196, 0x110, 0x51ab, 0x110, 0x51e0, 0x110, 0x51f5, 0x110,
+ 0x5200, 0x110, 0x529b, 0x110, 0x52f9, 0x110, 0x5315, 0x110,
+ 0x531a, 0x110, 0x5338, 0x110, 0x5341, 0x110, 0x535c, 0x110,
+ 0x5369, 0x110, 0x5382, 0x110, 0x53b6, 0x110, 0x53c8, 0x110,
+ 0x53e3, 0x110, 0x56d7, 0x110, 0x571f, 0x110, 0x58eb, 0x110,
+ 0x5902, 0x110, 0x590a, 0x110, 0x5915, 0x110, 0x5927, 0x110,
+ 0x5973, 0x110, 0x5b50, 0x110, 0x5b80, 0x110, 0x5bf8, 0x110,
+ 0x5c0f, 0x110, 0x5c22, 0x110, 0x5c38, 0x110, 0x5c6e, 0x110,
+ 0x5c71, 0x110, 0x5ddb, 0x110, 0x5de5, 0x110, 0x5df1, 0x110,
+ 0x5dfe, 0x110, 0x5e72, 0x110, 0x5e7a, 0x110, 0x5e7f, 0x110,
+ 0x5ef4, 0x110, 0x5efe, 0x110, 0x5f0b, 0x110, 0x5f13, 0x110,
+ 0x5f50, 0x110, 0x5f61, 0x110, 0x5f73, 0x110, 0x5fc3, 0x110,
+ 0x6208, 0x110, 0x6236, 0x110, 0x624b, 0x110, 0x652f, 0x110,
+ 0x6534, 0x110, 0x6587, 0x110, 0x6597, 0x110, 0x65a4, 0x110,
+ 0x65b9, 0x110, 0x65e0, 0x110, 0x65e5, 0x110, 0x66f0, 0x110,
+ 0x6708, 0x110, 0x6728, 0x110, 0x6b20, 0x110, 0x6b62, 0x110,
+ 0x6b79, 0x110, 0x6bb3, 0x110, 0x6bcb, 0x110, 0x6bd4, 0x110,
+ 0x6bdb, 0x110, 0x6c0f, 0x110, 0x6c14, 0x110, 0x6c34, 0x110,
+ 0x706b, 0x110, 0x722a, 0x110, 0x7236, 0x110, 0x723b, 0x110,
+ 0x723f, 0x110, 0x7247, 0x110, 0x7259, 0x110, 0x725b, 0x110,
+ 0x72ac, 0x110, 0x7384, 0x110, 0x7389, 0x110, 0x74dc, 0x110,
+ 0x74e6, 0x110, 0x7518, 0x110, 0x751f, 0x110, 0x7528, 0x110,
+ 0x7530, 0x110, 0x758b, 0x110, 0x7592, 0x110, 0x7676, 0x110,
+ 0x767d, 0x110, 0x76ae, 0x110, 0x76bf, 0x110, 0x76ee, 0x110,
+ 0x77db, 0x110, 0x77e2, 0x110, 0x77f3, 0x110, 0x793a, 0x110,
+ 0x79b8, 0x110, 0x79be, 0x110, 0x7a74, 0x110, 0x7acb, 0x110,
+ 0x7af9, 0x110, 0x7c73, 0x110, 0x7cf8, 0x110, 0x7f36, 0x110,
+ 0x7f51, 0x110, 0x7f8a, 0x110, 0x7fbd, 0x110, 0x8001, 0x110,
+ 0x800c, 0x110, 0x8012, 0x110, 0x8033, 0x110, 0x807f, 0x110,
+ 0x8089, 0x110, 0x81e3, 0x110, 0x81ea, 0x110, 0x81f3, 0x110,
+ 0x81fc, 0x110, 0x820c, 0x110, 0x821b, 0x110, 0x821f, 0x110,
+ 0x826e, 0x110, 0x8272, 0x110, 0x8278, 0x110, 0x864d, 0x110,
+ 0x866b, 0x110, 0x8840, 0x110, 0x884c, 0x110, 0x8863, 0x110,
+ 0x897e, 0x110, 0x898b, 0x110, 0x89d2, 0x110, 0x8a00, 0x110,
+ 0x8c37, 0x110, 0x8c46, 0x110, 0x8c55, 0x110, 0x8c78, 0x110,
+ 0x8c9d, 0x110, 0x8d64, 0x110, 0x8d70, 0x110, 0x8db3, 0x110,
+ 0x8eab, 0x110, 0x8eca, 0x110, 0x8f9b, 0x110, 0x8fb0, 0x110,
+ 0x8fb5, 0x110, 0x9091, 0x110, 0x9149, 0x110, 0x91c6, 0x110,
+ 0x91cc, 0x110, 0x91d1, 0x110, 0x9577, 0x110, 0x9580, 0x110,
+ 0x961c, 0x110, 0x96b6, 0x110, 0x96b9, 0x110, 0x96e8, 0x110,
+ 0x9751, 0x110, 0x975e, 0x110, 0x9762, 0x110, 0x9769, 0x110,
+ 0x97cb, 0x110, 0x97ed, 0x110, 0x97f3, 0x110, 0x9801, 0x110,
+ 0x98a8, 0x110, 0x98db, 0x110, 0x98df, 0x110, 0x9996, 0x110,
+ 0x9999, 0x110, 0x99ac, 0x110, 0x9aa8, 0x110, 0x9ad8, 0x110,
+ 0x9adf, 0x110, 0x9b25, 0x110, 0x9b2f, 0x110, 0x9b32, 0x110,
+ 0x9b3c, 0x110, 0x9b5a, 0x110, 0x9ce5, 0x110, 0x9e75, 0x110,
+ 0x9e7f, 0x110, 0x9ea5, 0x110, 0x9ebb, 0x110, 0x9ec3, 0x110,
+ 0x9ecd, 0x110, 0x9ed1, 0x110, 0x9ef9, 0x110, 0x9efd, 0x110,
+ 0x9f0e, 0x110, 0x9f13, 0x110, 0x9f20, 0x110, 0x9f3b, 0x110,
+ 0x9f4a, 0x110, 0x9f52, 0x110, 0x9f8d, 0x110, 0x9f9c, 0x110,
+ 0x9fa0, 0x10c, 0x20, 0x110, 0x3012, 0x110, 0x5341, 0x110,
+ 0x5344, 0x110, 0x5345, 0x201, 0x304b, 0x3099, 0x201, 0x304d,
+ 0x3099, 0x201, 0x304f, 0x3099, 0x201, 0x3051, 0x3099, 0x201,
+ 0x3053, 0x3099, 0x201, 0x3055, 0x3099, 0x201, 0x3057, 0x3099,
+ 0x201, 0x3059, 0x3099, 0x201, 0x305b, 0x3099, 0x201, 0x305d,
+ 0x3099, 0x201, 0x305f, 0x3099, 0x201, 0x3061, 0x3099, 0x201,
+ 0x3064, 0x3099, 0x201, 0x3066, 0x3099, 0x201, 0x3068, 0x3099,
+ 0x201, 0x306f, 0x3099, 0x201, 0x306f, 0x309a, 0x201, 0x3072,
+ 0x3099, 0x201, 0x3072, 0x309a, 0x201, 0x3075, 0x3099, 0x201,
+ 0x3075, 0x309a, 0x201, 0x3078, 0x3099, 0x201, 0x3078, 0x309a,
+ 0x201, 0x307b, 0x3099, 0x201, 0x307b, 0x309a, 0x201, 0x3046,
+ 0x3099, 0x210, 0x20, 0x3099, 0x210, 0x20, 0x309a, 0x201,
+ 0x309d, 0x3099, 0x20b, 0x3088, 0x308a, 0x201, 0x30ab, 0x3099,
+ 0x201, 0x30ad, 0x3099, 0x201, 0x30af, 0x3099, 0x201, 0x30b1,
+ 0x3099, 0x201, 0x30b3, 0x3099, 0x201, 0x30b5, 0x3099, 0x201,
+ 0x30b7, 0x3099, 0x201, 0x30b9, 0x3099, 0x201, 0x30bb, 0x3099,
+ 0x201, 0x30bd, 0x3099, 0x201, 0x30bf, 0x3099, 0x201, 0x30c1,
+ 0x3099, 0x201, 0x30c4, 0x3099, 0x201, 0x30c6, 0x3099, 0x201,
+ 0x30c8, 0x3099, 0x201, 0x30cf, 0x3099, 0x201, 0x30cf, 0x309a,
+ 0x201, 0x30d2, 0x3099, 0x201, 0x30d2, 0x309a, 0x201, 0x30d5,
+ 0x3099, 0x201, 0x30d5, 0x309a, 0x201, 0x30d8, 0x3099, 0x201,
+ 0x30d8, 0x309a, 0x201, 0x30db, 0x3099, 0x201, 0x30db, 0x309a,
+ 0x201, 0x30a6, 0x3099, 0x201, 0x30ef, 0x3099, 0x201, 0x30f0,
+ 0x3099, 0x201, 0x30f1, 0x3099, 0x201, 0x30f2, 0x3099, 0x201,
+ 0x30fd, 0x3099, 0x20b, 0x30b3, 0x30c8, 0x110, 0x1100, 0x110,
+ 0x1101, 0x110, 0x11aa, 0x110, 0x1102, 0x110, 0x11ac, 0x110,
+ 0x11ad, 0x110, 0x1103, 0x110, 0x1104, 0x110, 0x1105, 0x110,
+ 0x11b0, 0x110, 0x11b1, 0x110, 0x11b2, 0x110, 0x11b3, 0x110,
+ 0x11b4, 0x110, 0x11b5, 0x110, 0x111a, 0x110, 0x1106, 0x110,
+ 0x1107, 0x110, 0x1108, 0x110, 0x1121, 0x110, 0x1109, 0x110,
+ 0x110a, 0x110, 0x110b, 0x110, 0x110c, 0x110, 0x110d, 0x110,
+ 0x110e, 0x110, 0x110f, 0x110, 0x1110, 0x110, 0x1111, 0x110,
+ 0x1112, 0x110, 0x1161, 0x110, 0x1162, 0x110, 0x1163, 0x110,
+ 0x1164, 0x110, 0x1165, 0x110, 0x1166, 0x110, 0x1167, 0x110,
+ 0x1168, 0x110, 0x1169, 0x110, 0x116a, 0x110, 0x116b, 0x110,
+ 0x116c, 0x110, 0x116d, 0x110, 0x116e, 0x110, 0x116f, 0x110,
+ 0x1170, 0x110, 0x1171, 0x110, 0x1172, 0x110, 0x1173, 0x110,
+ 0x1174, 0x110, 0x1175, 0x110, 0x1160, 0x110, 0x1114, 0x110,
+ 0x1115, 0x110, 0x11c7, 0x110, 0x11c8, 0x110, 0x11cc, 0x110,
+ 0x11ce, 0x110, 0x11d3, 0x110, 0x11d7, 0x110, 0x11d9, 0x110,
+ 0x111c, 0x110, 0x11dd, 0x110, 0x11df, 0x110, 0x111d, 0x110,
+ 0x111e, 0x110, 0x1120, 0x110, 0x1122, 0x110, 0x1123, 0x110,
+ 0x1127, 0x110, 0x1129, 0x110, 0x112b, 0x110, 0x112c, 0x110,
+ 0x112d, 0x110, 0x112e, 0x110, 0x112f, 0x110, 0x1132, 0x110,
+ 0x1136, 0x110, 0x1140, 0x110, 0x1147, 0x110, 0x114c, 0x110,
+ 0x11f1, 0x110, 0x11f2, 0x110, 0x1157, 0x110, 0x1158, 0x110,
+ 0x1159, 0x110, 0x1184, 0x110, 0x1185, 0x110, 0x1188, 0x110,
+ 0x1191, 0x110, 0x1192, 0x110, 0x1194, 0x110, 0x119e, 0x110,
+ 0x11a1, 0x109, 0x4e00, 0x109, 0x4e8c, 0x109, 0x4e09, 0x109,
+ 0x56db, 0x109, 0x4e0a, 0x109, 0x4e2d, 0x109, 0x4e0b, 0x109,
+ 0x7532, 0x109, 0x4e59, 0x109, 0x4e19, 0x109, 0x4e01, 0x109,
+ 0x5929, 0x109, 0x5730, 0x109, 0x4eba, 0x310, 0x28, 0x1100,
+ 0x29, 0x310, 0x28, 0x1102, 0x29, 0x310, 0x28, 0x1103,
+ 0x29, 0x310, 0x28, 0x1105, 0x29, 0x310, 0x28, 0x1106,
+ 0x29, 0x310, 0x28, 0x1107, 0x29, 0x310, 0x28, 0x1109,
+ 0x29, 0x310, 0x28, 0x110b, 0x29, 0x310, 0x28, 0x110c,
+ 0x29, 0x310, 0x28, 0x110e, 0x29, 0x310, 0x28, 0x110f,
+ 0x29, 0x310, 0x28, 0x1110, 0x29, 0x310, 0x28, 0x1111,
+ 0x29, 0x310, 0x28, 0x1112, 0x29, 0x410, 0x28, 0x1100,
+ 0x1161, 0x29, 0x410, 0x28, 0x1102, 0x1161, 0x29, 0x410,
+ 0x28, 0x1103, 0x1161, 0x29, 0x410, 0x28, 0x1105, 0x1161,
+ 0x29, 0x410, 0x28, 0x1106, 0x1161, 0x29, 0x410, 0x28,
+ 0x1107, 0x1161, 0x29, 0x410, 0x28, 0x1109, 0x1161, 0x29,
+ 0x410, 0x28, 0x110b, 0x1161, 0x29, 0x410, 0x28, 0x110c,
+ 0x1161, 0x29, 0x410, 0x28, 0x110e, 0x1161, 0x29, 0x410,
+ 0x28, 0x110f, 0x1161, 0x29, 0x410, 0x28, 0x1110, 0x1161,
+ 0x29, 0x410, 0x28, 0x1111, 0x1161, 0x29, 0x410, 0x28,
+ 0x1112, 0x1161, 0x29, 0x410, 0x28, 0x110c, 0x116e, 0x29,
+ 0x710, 0x28, 0x110b, 0x1169, 0x110c, 0x1165, 0x11ab, 0x29,
+ 0x610, 0x28, 0x110b, 0x1169, 0x1112, 0x116e, 0x29, 0x310,
+ 0x28, 0x4e00, 0x29, 0x310, 0x28, 0x4e8c, 0x29, 0x310,
+ 0x28, 0x4e09, 0x29, 0x310, 0x28, 0x56db, 0x29, 0x310,
+ 0x28, 0x4e94, 0x29, 0x310, 0x28, 0x516d, 0x29, 0x310,
+ 0x28, 0x4e03, 0x29, 0x310, 0x28, 0x516b, 0x29, 0x310,
+ 0x28, 0x4e5d, 0x29, 0x310, 0x28, 0x5341, 0x29, 0x310,
+ 0x28, 0x6708, 0x29, 0x310, 0x28, 0x706b, 0x29, 0x310,
+ 0x28, 0x6c34, 0x29, 0x310, 0x28, 0x6728, 0x29, 0x310,
+ 0x28, 0x91d1, 0x29, 0x310, 0x28, 0x571f, 0x29, 0x310,
+ 0x28, 0x65e5, 0x29, 0x310, 0x28, 0x682a, 0x29, 0x310,
+ 0x28, 0x6709, 0x29, 0x310, 0x28, 0x793e, 0x29, 0x310,
+ 0x28, 0x540d, 0x29, 0x310, 0x28, 0x7279, 0x29, 0x310,
+ 0x28, 0x8ca1, 0x29, 0x310, 0x28, 0x795d, 0x29, 0x310,
+ 0x28, 0x52b4, 0x29, 0x310, 0x28, 0x4ee3, 0x29, 0x310,
+ 0x28, 0x547c, 0x29, 0x310, 0x28, 0x5b66, 0x29, 0x310,
+ 0x28, 0x76e3, 0x29, 0x310, 0x28, 0x4f01, 0x29, 0x310,
+ 0x28, 0x8cc7, 0x29, 0x310, 0x28, 0x5354, 0x29, 0x310,
+ 0x28, 0x796d, 0x29, 0x310, 0x28, 0x4f11, 0x29, 0x310,
+ 0x28, 0x81ea, 0x29, 0x310, 0x28, 0x81f3, 0x29, 0x30f,
+ 0x50, 0x54, 0x45, 0x208, 0x32, 0x31, 0x208, 0x32,
+ 0x32, 0x208, 0x32, 0x33, 0x208, 0x32, 0x34, 0x208,
+ 0x32, 0x35, 0x208, 0x32, 0x36, 0x208, 0x32, 0x37,
+ 0x208, 0x32, 0x38, 0x208, 0x32, 0x39, 0x208, 0x33,
+ 0x30, 0x208, 0x33, 0x31, 0x208, 0x33, 0x32, 0x208,
+ 0x33, 0x33, 0x208, 0x33, 0x34, 0x208, 0x33, 0x35,
+ 0x108, 0x1100, 0x108, 0x1102, 0x108, 0x1103, 0x108, 0x1105,
+ 0x108, 0x1106, 0x108, 0x1107, 0x108, 0x1109, 0x108, 0x110b,
+ 0x108, 0x110c, 0x108, 0x110e, 0x108, 0x110f, 0x108, 0x1110,
+ 0x108, 0x1111, 0x108, 0x1112, 0x208, 0x1100, 0x1161, 0x208,
+ 0x1102, 0x1161, 0x208, 0x1103, 0x1161, 0x208, 0x1105, 0x1161,
+ 0x208, 0x1106, 0x1161, 0x208, 0x1107, 0x1161, 0x208, 0x1109,
+ 0x1161, 0x208, 0x110b, 0x1161, 0x208, 0x110c, 0x1161, 0x208,
+ 0x110e, 0x1161, 0x208, 0x110f, 0x1161, 0x208, 0x1110, 0x1161,
+ 0x208, 0x1111, 0x1161, 0x208, 0x1112, 0x1161, 0x508, 0x110e,
+ 0x1161, 0x11b7, 0x1100, 0x1169, 0x408, 0x110c, 0x116e, 0x110b,
+ 0x1174, 0x208, 0x110b, 0x116e, 0x108, 0x4e00, 0x108, 0x4e8c,
+ 0x108, 0x4e09, 0x108, 0x56db, 0x108, 0x4e94, 0x108, 0x516d,
+ 0x108, 0x4e03, 0x108, 0x516b, 0x108, 0x4e5d, 0x108, 0x5341,
+ 0x108, 0x6708, 0x108, 0x706b, 0x108, 0x6c34, 0x108, 0x6728,
+ 0x108, 0x91d1, 0x108, 0x571f, 0x108, 0x65e5, 0x108, 0x682a,
+ 0x108, 0x6709, 0x108, 0x793e, 0x108, 0x540d, 0x108, 0x7279,
+ 0x108, 0x8ca1, 0x108, 0x795d, 0x108, 0x52b4, 0x108, 0x79d8,
+ 0x108, 0x7537, 0x108, 0x5973, 0x108, 0x9069, 0x108, 0x512a,
+ 0x108, 0x5370, 0x108, 0x6ce8, 0x108, 0x9805, 0x108, 0x4f11,
+ 0x108, 0x5199, 0x108, 0x6b63, 0x108, 0x4e0a, 0x108, 0x4e2d,
+ 0x108, 0x4e0b, 0x108, 0x5de6, 0x108, 0x53f3, 0x108, 0x533b,
+ 0x108, 0x5b97, 0x108, 0x5b66, 0x108, 0x76e3, 0x108, 0x4f01,
+ 0x108, 0x8cc7, 0x108, 0x5354, 0x108, 0x591c, 0x208, 0x33,
+ 0x36, 0x208, 0x33, 0x37, 0x208, 0x33, 0x38, 0x208,
+ 0x33, 0x39, 0x208, 0x34, 0x30, 0x208, 0x34, 0x31,
+ 0x208, 0x34, 0x32, 0x208, 0x34, 0x33, 0x208, 0x34,
+ 0x34, 0x208, 0x34, 0x35, 0x208, 0x34, 0x36, 0x208,
+ 0x34, 0x37, 0x208, 0x34, 0x38, 0x208, 0x34, 0x39,
+ 0x208, 0x35, 0x30, 0x210, 0x31, 0x6708, 0x210, 0x32,
+ 0x6708, 0x210, 0x33, 0x6708, 0x210, 0x34, 0x6708, 0x210,
+ 0x35, 0x6708, 0x210, 0x36, 0x6708, 0x210, 0x37, 0x6708,
+ 0x210, 0x38, 0x6708, 0x210, 0x39, 0x6708, 0x310, 0x31,
+ 0x30, 0x6708, 0x310, 0x31, 0x31, 0x6708, 0x310, 0x31,
+ 0x32, 0x6708, 0x20f, 0x48, 0x67, 0x30f, 0x65, 0x72,
+ 0x67, 0x20f, 0x65, 0x56, 0x30f, 0x4c, 0x54, 0x44,
+ 0x108, 0x30a2, 0x108, 0x30a4, 0x108, 0x30a6, 0x108, 0x30a8,
+ 0x108, 0x30aa, 0x108, 0x30ab, 0x108, 0x30ad, 0x108, 0x30af,
+ 0x108, 0x30b1, 0x108, 0x30b3, 0x108, 0x30b5, 0x108, 0x30b7,
+ 0x108, 0x30b9, 0x108, 0x30bb, 0x108, 0x30bd, 0x108, 0x30bf,
+ 0x108, 0x30c1, 0x108, 0x30c4, 0x108, 0x30c6, 0x108, 0x30c8,
+ 0x108, 0x30ca, 0x108, 0x30cb, 0x108, 0x30cc, 0x108, 0x30cd,
+ 0x108, 0x30ce, 0x108, 0x30cf, 0x108, 0x30d2, 0x108, 0x30d5,
+ 0x108, 0x30d8, 0x108, 0x30db, 0x108, 0x30de, 0x108, 0x30df,
+ 0x108, 0x30e0, 0x108, 0x30e1, 0x108, 0x30e2, 0x108, 0x30e4,
+ 0x108, 0x30e6, 0x108, 0x30e8, 0x108, 0x30e9, 0x108, 0x30ea,
+ 0x108, 0x30eb, 0x108, 0x30ec, 0x108, 0x30ed, 0x108, 0x30ef,
+ 0x108, 0x30f0, 0x108, 0x30f1, 0x108, 0x30f2, 0x40f, 0x30a2,
+ 0x30d1, 0x30fc, 0x30c8, 0x40f, 0x30a2, 0x30eb, 0x30d5, 0x30a1,
+ 0x40f, 0x30a2, 0x30f3, 0x30da, 0x30a2, 0x30f, 0x30a2, 0x30fc,
+ 0x30eb, 0x40f, 0x30a4, 0x30cb, 0x30f3, 0x30b0, 0x30f, 0x30a4,
+ 0x30f3, 0x30c1, 0x30f, 0x30a6, 0x30a9, 0x30f3, 0x50f, 0x30a8,
+ 0x30b9, 0x30af, 0x30fc, 0x30c9, 0x40f, 0x30a8, 0x30fc, 0x30ab,
+ 0x30fc, 0x30f, 0x30aa, 0x30f3, 0x30b9, 0x30f, 0x30aa, 0x30fc,
+ 0x30e0, 0x30f, 0x30ab, 0x30a4, 0x30ea, 0x40f, 0x30ab, 0x30e9,
+ 0x30c3, 0x30c8, 0x40f, 0x30ab, 0x30ed, 0x30ea, 0x30fc, 0x30f,
+ 0x30ac, 0x30ed, 0x30f3, 0x30f, 0x30ac, 0x30f3, 0x30de, 0x20f,
+ 0x30ae, 0x30ac, 0x30f, 0x30ae, 0x30cb, 0x30fc, 0x40f, 0x30ad,
+ 0x30e5, 0x30ea, 0x30fc, 0x40f, 0x30ae, 0x30eb, 0x30c0, 0x30fc,
+ 0x20f, 0x30ad, 0x30ed, 0x50f, 0x30ad, 0x30ed, 0x30b0, 0x30e9,
+ 0x30e0, 0x60f, 0x30ad, 0x30ed, 0x30e1, 0x30fc, 0x30c8, 0x30eb,
+ 0x50f, 0x30ad, 0x30ed, 0x30ef, 0x30c3, 0x30c8, 0x30f, 0x30b0,
+ 0x30e9, 0x30e0, 0x50f, 0x30b0, 0x30e9, 0x30e0, 0x30c8, 0x30f3,
+ 0x50f, 0x30af, 0x30eb, 0x30bc, 0x30a4, 0x30ed, 0x40f, 0x30af,
+ 0x30ed, 0x30fc, 0x30cd, 0x30f, 0x30b1, 0x30fc, 0x30b9, 0x30f,
+ 0x30b3, 0x30eb, 0x30ca, 0x30f, 0x30b3, 0x30fc, 0x30dd, 0x40f,
+ 0x30b5, 0x30a4, 0x30af, 0x30eb, 0x50f, 0x30b5, 0x30f3, 0x30c1,
+ 0x30fc, 0x30e0, 0x40f, 0x30b7, 0x30ea, 0x30f3, 0x30b0, 0x30f,
+ 0x30bb, 0x30f3, 0x30c1, 0x30f, 0x30bb, 0x30f3, 0x30c8, 0x30f,
+ 0x30c0, 0x30fc, 0x30b9, 0x20f, 0x30c7, 0x30b7, 0x20f, 0x30c9,
+ 0x30eb, 0x20f, 0x30c8, 0x30f3, 0x20f, 0x30ca, 0x30ce, 0x30f,
+ 0x30ce, 0x30c3, 0x30c8, 0x30f, 0x30cf, 0x30a4, 0x30c4, 0x50f,
+ 0x30d1, 0x30fc, 0x30bb, 0x30f3, 0x30c8, 0x30f, 0x30d1, 0x30fc,
+ 0x30c4, 0x40f, 0x30d0, 0x30fc, 0x30ec, 0x30eb, 0x50f, 0x30d4,
+ 0x30a2, 0x30b9, 0x30c8, 0x30eb, 0x30f, 0x30d4, 0x30af, 0x30eb,
+ 0x20f, 0x30d4, 0x30b3, 0x20f, 0x30d3, 0x30eb, 0x50f, 0x30d5,
+ 0x30a1, 0x30e9, 0x30c3, 0x30c9, 0x40f, 0x30d5, 0x30a3, 0x30fc,
+ 0x30c8, 0x50f, 0x30d6, 0x30c3, 0x30b7, 0x30a7, 0x30eb, 0x30f,
+ 0x30d5, 0x30e9, 0x30f3, 0x50f, 0x30d8, 0x30af, 0x30bf, 0x30fc,
+ 0x30eb, 0x20f, 0x30da, 0x30bd, 0x30f, 0x30da, 0x30cb, 0x30d2,
+ 0x30f, 0x30d8, 0x30eb, 0x30c4, 0x30f, 0x30da, 0x30f3, 0x30b9,
+ 0x30f, 0x30da, 0x30fc, 0x30b8, 0x30f, 0x30d9, 0x30fc, 0x30bf,
+ 0x40f, 0x30dd, 0x30a4, 0x30f3, 0x30c8, 0x30f, 0x30dc, 0x30eb,
+ 0x30c8, 0x20f, 0x30db, 0x30f3, 0x30f, 0x30dd, 0x30f3, 0x30c9,
+ 0x30f, 0x30db, 0x30fc, 0x30eb, 0x30f, 0x30db, 0x30fc, 0x30f3,
+ 0x40f, 0x30de, 0x30a4, 0x30af, 0x30ed, 0x30f, 0x30de, 0x30a4,
+ 0x30eb, 0x30f, 0x30de, 0x30c3, 0x30cf, 0x30f, 0x30de, 0x30eb,
+ 0x30af, 0x50f, 0x30de, 0x30f3, 0x30b7, 0x30e7, 0x30f3, 0x40f,
+ 0x30df, 0x30af, 0x30ed, 0x30f3, 0x20f, 0x30df, 0x30ea, 0x50f,
+ 0x30df, 0x30ea, 0x30d0, 0x30fc, 0x30eb, 0x20f, 0x30e1, 0x30ac,
+ 0x40f, 0x30e1, 0x30ac, 0x30c8, 0x30f3, 0x40f, 0x30e1, 0x30fc,
+ 0x30c8, 0x30eb, 0x30f, 0x30e4, 0x30fc, 0x30c9, 0x30f, 0x30e4,
+ 0x30fc, 0x30eb, 0x30f, 0x30e6, 0x30a2, 0x30f3, 0x40f, 0x30ea,
+ 0x30c3, 0x30c8, 0x30eb, 0x20f, 0x30ea, 0x30e9, 0x30f, 0x30eb,
+ 0x30d4, 0x30fc, 0x40f, 0x30eb, 0x30fc, 0x30d6, 0x30eb, 0x20f,
+ 0x30ec, 0x30e0, 0x50f, 0x30ec, 0x30f3, 0x30c8, 0x30b2, 0x30f3,
+ 0x30f, 0x30ef, 0x30c3, 0x30c8, 0x210, 0x30, 0x70b9, 0x210,
+ 0x31, 0x70b9, 0x210, 0x32, 0x70b9, 0x210, 0x33, 0x70b9,
+ 0x210, 0x34, 0x70b9, 0x210, 0x35, 0x70b9, 0x210, 0x36,
+ 0x70b9, 0x210, 0x37, 0x70b9, 0x210, 0x38, 0x70b9, 0x210,
+ 0x39, 0x70b9, 0x310, 0x31, 0x30, 0x70b9, 0x310, 0x31,
+ 0x31, 0x70b9, 0x310, 0x31, 0x32, 0x70b9, 0x310, 0x31,
+ 0x33, 0x70b9, 0x310, 0x31, 0x34, 0x70b9, 0x310, 0x31,
+ 0x35, 0x70b9, 0x310, 0x31, 0x36, 0x70b9, 0x310, 0x31,
+ 0x37, 0x70b9, 0x310, 0x31, 0x38, 0x70b9, 0x310, 0x31,
+ 0x39, 0x70b9, 0x310, 0x32, 0x30, 0x70b9, 0x310, 0x32,
+ 0x31, 0x70b9, 0x310, 0x32, 0x32, 0x70b9, 0x310, 0x32,
+ 0x33, 0x70b9, 0x310, 0x32, 0x34, 0x70b9, 0x30f, 0x68,
+ 0x50, 0x61, 0x20f, 0x64, 0x61, 0x20f, 0x41, 0x55,
+ 0x30f, 0x62, 0x61, 0x72, 0x20f, 0x6f, 0x56, 0x20f,
+ 0x70, 0x63, 0x20f, 0x64, 0x6d, 0x30f, 0x64, 0x6d,
+ 0xb2, 0x30f, 0x64, 0x6d, 0xb3, 0x20f, 0x49, 0x55,
+ 0x20f, 0x5e73, 0x6210, 0x20f, 0x662d, 0x548c, 0x20f, 0x5927,
+ 0x6b63, 0x20f, 0x660e, 0x6cbb, 0x40f, 0x682a, 0x5f0f, 0x4f1a,
+ 0x793e, 0x20f, 0x70, 0x41, 0x20f, 0x6e, 0x41, 0x20f,
+ 0x3bc, 0x41, 0x20f, 0x6d, 0x41, 0x20f, 0x6b, 0x41,
+ 0x20f, 0x4b, 0x42, 0x20f, 0x4d, 0x42, 0x20f, 0x47,
+ 0x42, 0x30f, 0x63, 0x61, 0x6c, 0x40f, 0x6b, 0x63,
+ 0x61, 0x6c, 0x20f, 0x70, 0x46, 0x20f, 0x6e, 0x46,
+ 0x20f, 0x3bc, 0x46, 0x20f, 0x3bc, 0x67, 0x20f, 0x6d,
+ 0x67, 0x20f, 0x6b, 0x67, 0x20f, 0x48, 0x7a, 0x30f,
+ 0x6b, 0x48, 0x7a, 0x30f, 0x4d, 0x48, 0x7a, 0x30f,
+ 0x47, 0x48, 0x7a, 0x30f, 0x54, 0x48, 0x7a, 0x20f,
+ 0x3bc, 0x2113, 0x20f, 0x6d, 0x2113, 0x20f, 0x64, 0x2113,
+ 0x20f, 0x6b, 0x2113, 0x20f, 0x66, 0x6d, 0x20f, 0x6e,
+ 0x6d, 0x20f, 0x3bc, 0x6d, 0x20f, 0x6d, 0x6d, 0x20f,
+ 0x63, 0x6d, 0x20f, 0x6b, 0x6d, 0x30f, 0x6d, 0x6d,
+ 0xb2, 0x30f, 0x63, 0x6d, 0xb2, 0x20f, 0x6d, 0xb2,
+ 0x30f, 0x6b, 0x6d, 0xb2, 0x30f, 0x6d, 0x6d, 0xb3,
+ 0x30f, 0x63, 0x6d, 0xb3, 0x20f, 0x6d, 0xb3, 0x30f,
+ 0x6b, 0x6d, 0xb3, 0x30f, 0x6d, 0x2215, 0x73, 0x40f,
+ 0x6d, 0x2215, 0x73, 0xb2, 0x20f, 0x50, 0x61, 0x30f,
+ 0x6b, 0x50, 0x61, 0x30f, 0x4d, 0x50, 0x61, 0x30f,
+ 0x47, 0x50, 0x61, 0x30f, 0x72, 0x61, 0x64, 0x50f,
+ 0x72, 0x61, 0x64, 0x2215, 0x73, 0x60f, 0x72, 0x61,
+ 0x64, 0x2215, 0x73, 0xb2, 0x20f, 0x70, 0x73, 0x20f,
+ 0x6e, 0x73, 0x20f, 0x3bc, 0x73, 0x20f, 0x6d, 0x73,
+ 0x20f, 0x70, 0x56, 0x20f, 0x6e, 0x56, 0x20f, 0x3bc,
+ 0x56, 0x20f, 0x6d, 0x56, 0x20f, 0x6b, 0x56, 0x20f,
+ 0x4d, 0x56, 0x20f, 0x70, 0x57, 0x20f, 0x6e, 0x57,
+ 0x20f, 0x3bc, 0x57, 0x20f, 0x6d, 0x57, 0x20f, 0x6b,
+ 0x57, 0x20f, 0x4d, 0x57, 0x20f, 0x6b, 0x3a9, 0x20f,
+ 0x4d, 0x3a9, 0x40f, 0x61, 0x2e, 0x6d, 0x2e, 0x20f,
+ 0x42, 0x71, 0x20f, 0x63, 0x63, 0x20f, 0x63, 0x64,
+ 0x40f, 0x43, 0x2215, 0x6b, 0x67, 0x30f, 0x43, 0x6f,
+ 0x2e, 0x20f, 0x64, 0x42, 0x20f, 0x47, 0x79, 0x20f,
+ 0x68, 0x61, 0x20f, 0x48, 0x50, 0x20f, 0x69, 0x6e,
+ 0x20f, 0x4b, 0x4b, 0x20f, 0x4b, 0x4d, 0x20f, 0x6b,
+ 0x74, 0x20f, 0x6c, 0x6d, 0x20f, 0x6c, 0x6e, 0x30f,
+ 0x6c, 0x6f, 0x67, 0x20f, 0x6c, 0x78, 0x20f, 0x6d,
+ 0x62, 0x30f, 0x6d, 0x69, 0x6c, 0x30f, 0x6d, 0x6f,
+ 0x6c, 0x20f, 0x50, 0x48, 0x40f, 0x70, 0x2e, 0x6d,
+ 0x2e, 0x30f, 0x50, 0x50, 0x4d, 0x20f, 0x50, 0x52,
+ 0x20f, 0x73, 0x72, 0x20f, 0x53, 0x76, 0x20f, 0x57,
+ 0x62, 0x30f, 0x56, 0x2215, 0x6d, 0x30f, 0x41, 0x2215,
+ 0x6d, 0x210, 0x31, 0x65e5, 0x210, 0x32, 0x65e5, 0x210,
+ 0x33, 0x65e5, 0x210, 0x34, 0x65e5, 0x210, 0x35, 0x65e5,
+ 0x210, 0x36, 0x65e5, 0x210, 0x37, 0x65e5, 0x210, 0x38,
+ 0x65e5, 0x210, 0x39, 0x65e5, 0x310, 0x31, 0x30, 0x65e5,
+ 0x310, 0x31, 0x31, 0x65e5, 0x310, 0x31, 0x32, 0x65e5,
+ 0x310, 0x31, 0x33, 0x65e5, 0x310, 0x31, 0x34, 0x65e5,
+ 0x310, 0x31, 0x35, 0x65e5, 0x310, 0x31, 0x36, 0x65e5,
+ 0x310, 0x31, 0x37, 0x65e5, 0x310, 0x31, 0x38, 0x65e5,
+ 0x310, 0x31, 0x39, 0x65e5, 0x310, 0x32, 0x30, 0x65e5,
+ 0x310, 0x32, 0x31, 0x65e5, 0x310, 0x32, 0x32, 0x65e5,
+ 0x310, 0x32, 0x33, 0x65e5, 0x310, 0x32, 0x34, 0x65e5,
+ 0x310, 0x32, 0x35, 0x65e5, 0x310, 0x32, 0x36, 0x65e5,
+ 0x310, 0x32, 0x37, 0x65e5, 0x310, 0x32, 0x38, 0x65e5,
+ 0x310, 0x32, 0x39, 0x65e5, 0x310, 0x33, 0x30, 0x65e5,
+ 0x310, 0x33, 0x31, 0x65e5, 0x30f, 0x67, 0x61, 0x6c,
+ 0x101, 0x8c48, 0x101, 0x66f4, 0x101, 0x8eca, 0x101, 0x8cc8,
+ 0x101, 0x6ed1, 0x101, 0x4e32, 0x101, 0x53e5, 0x101, 0x9f9c,
+ 0x101, 0x9f9c, 0x101, 0x5951, 0x101, 0x91d1, 0x101, 0x5587,
+ 0x101, 0x5948, 0x101, 0x61f6, 0x101, 0x7669, 0x101, 0x7f85,
+ 0x101, 0x863f, 0x101, 0x87ba, 0x101, 0x88f8, 0x101, 0x908f,
+ 0x101, 0x6a02, 0x101, 0x6d1b, 0x101, 0x70d9, 0x101, 0x73de,
+ 0x101, 0x843d, 0x101, 0x916a, 0x101, 0x99f1, 0x101, 0x4e82,
+ 0x101, 0x5375, 0x101, 0x6b04, 0x101, 0x721b, 0x101, 0x862d,
+ 0x101, 0x9e1e, 0x101, 0x5d50, 0x101, 0x6feb, 0x101, 0x85cd,
+ 0x101, 0x8964, 0x101, 0x62c9, 0x101, 0x81d8, 0x101, 0x881f,
+ 0x101, 0x5eca, 0x101, 0x6717, 0x101, 0x6d6a, 0x101, 0x72fc,
+ 0x101, 0x90ce, 0x101, 0x4f86, 0x101, 0x51b7, 0x101, 0x52de,
+ 0x101, 0x64c4, 0x101, 0x6ad3, 0x101, 0x7210, 0x101, 0x76e7,
+ 0x101, 0x8001, 0x101, 0x8606, 0x101, 0x865c, 0x101, 0x8def,
+ 0x101, 0x9732, 0x101, 0x9b6f, 0x101, 0x9dfa, 0x101, 0x788c,
+ 0x101, 0x797f, 0x101, 0x7da0, 0x101, 0x83c9, 0x101, 0x9304,
+ 0x101, 0x9e7f, 0x101, 0x8ad6, 0x101, 0x58df, 0x101, 0x5f04,
+ 0x101, 0x7c60, 0x101, 0x807e, 0x101, 0x7262, 0x101, 0x78ca,
+ 0x101, 0x8cc2, 0x101, 0x96f7, 0x101, 0x58d8, 0x101, 0x5c62,
+ 0x101, 0x6a13, 0x101, 0x6dda, 0x101, 0x6f0f, 0x101, 0x7d2f,
+ 0x101, 0x7e37, 0x101, 0x964b, 0x101, 0x52d2, 0x101, 0x808b,
+ 0x101, 0x51dc, 0x101, 0x51cc, 0x101, 0x7a1c, 0x101, 0x7dbe,
+ 0x101, 0x83f1, 0x101, 0x9675, 0x101, 0x8b80, 0x101, 0x62cf,
+ 0x101, 0x6a02, 0x101, 0x8afe, 0x101, 0x4e39, 0x101, 0x5be7,
+ 0x101, 0x6012, 0x101, 0x7387, 0x101, 0x7570, 0x101, 0x5317,
+ 0x101, 0x78fb, 0x101, 0x4fbf, 0x101, 0x5fa9, 0x101, 0x4e0d,
+ 0x101, 0x6ccc, 0x101, 0x6578, 0x101, 0x7d22, 0x101, 0x53c3,
+ 0x101, 0x585e, 0x101, 0x7701, 0x101, 0x8449, 0x101, 0x8aaa,
+ 0x101, 0x6bba, 0x101, 0x8fb0, 0x101, 0x6c88, 0x101, 0x62fe,
+ 0x101, 0x82e5, 0x101, 0x63a0, 0x101, 0x7565, 0x101, 0x4eae,
+ 0x101, 0x5169, 0x101, 0x51c9, 0x101, 0x6881, 0x101, 0x7ce7,
+ 0x101, 0x826f, 0x101, 0x8ad2, 0x101, 0x91cf, 0x101, 0x52f5,
+ 0x101, 0x5442, 0x101, 0x5973, 0x101, 0x5eec, 0x101, 0x65c5,
+ 0x101, 0x6ffe, 0x101, 0x792a, 0x101, 0x95ad, 0x101, 0x9a6a,
+ 0x101, 0x9e97, 0x101, 0x9ece, 0x101, 0x529b, 0x101, 0x66c6,
+ 0x101, 0x6b77, 0x101, 0x8f62, 0x101, 0x5e74, 0x101, 0x6190,
+ 0x101, 0x6200, 0x101, 0x649a, 0x101, 0x6f23, 0x101, 0x7149,
+ 0x101, 0x7489, 0x101, 0x79ca, 0x101, 0x7df4, 0x101, 0x806f,
+ 0x101, 0x8f26, 0x101, 0x84ee, 0x101, 0x9023, 0x101, 0x934a,
+ 0x101, 0x5217, 0x101, 0x52a3, 0x101, 0x54bd, 0x101, 0x70c8,
+ 0x101, 0x88c2, 0x101, 0x8aaa, 0x101, 0x5ec9, 0x101, 0x5ff5,
+ 0x101, 0x637b, 0x101, 0x6bae, 0x101, 0x7c3e, 0x101, 0x7375,
+ 0x101, 0x4ee4, 0x101, 0x56f9, 0x101, 0x5be7, 0x101, 0x5dba,
+ 0x101, 0x601c, 0x101, 0x73b2, 0x101, 0x7469, 0x101, 0x7f9a,
+ 0x101, 0x8046, 0x101, 0x9234, 0x101, 0x96f6, 0x101, 0x9748,
+ 0x101, 0x9818, 0x101, 0x4f8b, 0x101, 0x79ae, 0x101, 0x91b4,
+ 0x101, 0x96b8, 0x101, 0x60e1, 0x101, 0x4e86, 0x101, 0x50da,
+ 0x101, 0x5bee, 0x101, 0x5c3f, 0x101, 0x6599, 0x101, 0x6a02,
+ 0x101, 0x71ce, 0x101, 0x7642, 0x101, 0x84fc, 0x101, 0x907c,
+ 0x101, 0x9f8d, 0x101, 0x6688, 0x101, 0x962e, 0x101, 0x5289,
+ 0x101, 0x677b, 0x101, 0x67f3, 0x101, 0x6d41, 0x101, 0x6e9c,
+ 0x101, 0x7409, 0x101, 0x7559, 0x101, 0x786b, 0x101, 0x7d10,
+ 0x101, 0x985e, 0x101, 0x516d, 0x101, 0x622e, 0x101, 0x9678,
+ 0x101, 0x502b, 0x101, 0x5d19, 0x101, 0x6dea, 0x101, 0x8f2a,
+ 0x101, 0x5f8b, 0x101, 0x6144, 0x101, 0x6817, 0x101, 0x7387,
+ 0x101, 0x9686, 0x101, 0x5229, 0x101, 0x540f, 0x101, 0x5c65,
+ 0x101, 0x6613, 0x101, 0x674e, 0x101, 0x68a8, 0x101, 0x6ce5,
+ 0x101, 0x7406, 0x101, 0x75e2, 0x101, 0x7f79, 0x101, 0x88cf,
+ 0x101, 0x88e1, 0x101, 0x91cc, 0x101, 0x96e2, 0x101, 0x533f,
+ 0x101, 0x6eba, 0x101, 0x541d, 0x101, 0x71d0, 0x101, 0x7498,
+ 0x101, 0x85fa, 0x101, 0x96a3, 0x101, 0x9c57, 0x101, 0x9e9f,
+ 0x101, 0x6797, 0x101, 0x6dcb, 0x101, 0x81e8, 0x101, 0x7acb,
+ 0x101, 0x7b20, 0x101, 0x7c92, 0x101, 0x72c0, 0x101, 0x7099,
+ 0x101, 0x8b58, 0x101, 0x4ec0, 0x101, 0x8336, 0x101, 0x523a,
+ 0x101, 0x5207, 0x101, 0x5ea6, 0x101, 0x62d3, 0x101, 0x7cd6,
+ 0x101, 0x5b85, 0x101, 0x6d1e, 0x101, 0x66b4, 0x101, 0x8f3b,
+ 0x101, 0x884c, 0x101, 0x964d, 0x101, 0x898b, 0x101, 0x5ed3,
+ 0x101, 0x5140, 0x101, 0x55c0, 0x101, 0x585a, 0x101, 0x6674,
+ 0x101, 0x51de, 0x101, 0x732a, 0x101, 0x76ca, 0x101, 0x793c,
+ 0x101, 0x795e, 0x101, 0x7965, 0x101, 0x798f, 0x101, 0x9756,
+ 0x101, 0x7cbe, 0x101, 0x7fbd, 0x101, 0x8612, 0x101, 0x8af8,
+ 0x101, 0x9038, 0x101, 0x90fd, 0x101, 0x98ef, 0x101, 0x98fc,
+ 0x101, 0x9928, 0x101, 0x9db4, 0x101, 0x4fae, 0x101, 0x50e7,
+ 0x101, 0x514d, 0x101, 0x52c9, 0x101, 0x52e4, 0x101, 0x5351,
+ 0x101, 0x559d, 0x101, 0x5606, 0x101, 0x5668, 0x101, 0x5840,
+ 0x101, 0x58a8, 0x101, 0x5c64, 0x101, 0x5c6e, 0x101, 0x6094,
+ 0x101, 0x6168, 0x101, 0x618e, 0x101, 0x61f2, 0x101, 0x654f,
+ 0x101, 0x65e2, 0x101, 0x6691, 0x101, 0x6885, 0x101, 0x6d77,
+ 0x101, 0x6e1a, 0x101, 0x6f22, 0x101, 0x716e, 0x101, 0x722b,
+ 0x101, 0x7422, 0x101, 0x7891, 0x101, 0x793e, 0x101, 0x7949,
+ 0x101, 0x7948, 0x101, 0x7950, 0x101, 0x7956, 0x101, 0x795d,
+ 0x101, 0x798d, 0x101, 0x798e, 0x101, 0x7a40, 0x101, 0x7a81,
+ 0x101, 0x7bc0, 0x101, 0x7df4, 0x101, 0x7e09, 0x101, 0x7e41,
+ 0x101, 0x7f72, 0x101, 0x8005, 0x101, 0x81ed, 0x101, 0x8279,
+ 0x101, 0x8279, 0x101, 0x8457, 0x101, 0x8910, 0x101, 0x8996,
+ 0x101, 0x8b01, 0x101, 0x8b39, 0x101, 0x8cd3, 0x101, 0x8d08,
+ 0x101, 0x8fb6, 0x101, 0x9038, 0x101, 0x96e3, 0x101, 0x97ff,
+ 0x101, 0x983b, 0x101, 0x4e26, 0x101, 0x51b5, 0x101, 0x5168,
+ 0x101, 0x4f80, 0x101, 0x5145, 0x101, 0x5180, 0x101, 0x52c7,
+ 0x101, 0x52fa, 0x101, 0x559d, 0x101, 0x5555, 0x101, 0x5599,
+ 0x101, 0x55e2, 0x101, 0x585a, 0x101, 0x58b3, 0x101, 0x5944,
+ 0x101, 0x5954, 0x101, 0x5a62, 0x101, 0x5b28, 0x101, 0x5ed2,
+ 0x101, 0x5ed9, 0x101, 0x5f69, 0x101, 0x5fad, 0x101, 0x60d8,
+ 0x101, 0x614e, 0x101, 0x6108, 0x101, 0x618e, 0x101, 0x6160,
+ 0x101, 0x61f2, 0x101, 0x6234, 0x101, 0x63c4, 0x101, 0x641c,
+ 0x101, 0x6452, 0x101, 0x6556, 0x101, 0x6674, 0x101, 0x6717,
+ 0x101, 0x671b, 0x101, 0x6756, 0x101, 0x6b79, 0x101, 0x6bba,
+ 0x101, 0x6d41, 0x101, 0x6edb, 0x101, 0x6ecb, 0x101, 0x6f22,
+ 0x101, 0x701e, 0x101, 0x716e, 0x101, 0x77a7, 0x101, 0x7235,
+ 0x101, 0x72af, 0x101, 0x732a, 0x101, 0x7471, 0x101, 0x7506,
+ 0x101, 0x753b, 0x101, 0x761d, 0x101, 0x761f, 0x101, 0x76ca,
+ 0x101, 0x76db, 0x101, 0x76f4, 0x101, 0x774a, 0x101, 0x7740,
+ 0x101, 0x78cc, 0x101, 0x7ab1, 0x101, 0x7bc0, 0x101, 0x7c7b,
+ 0x101, 0x7d5b, 0x101, 0x7df4, 0x101, 0x7f3e, 0x101, 0x8005,
+ 0x101, 0x8352, 0x101, 0x83ef, 0x101, 0x8779, 0x101, 0x8941,
+ 0x101, 0x8986, 0x101, 0x8996, 0x101, 0x8abf, 0x101, 0x8af8,
+ 0x101, 0x8acb, 0x101, 0x8b01, 0x101, 0x8afe, 0x101, 0x8aed,
+ 0x101, 0x8b39, 0x101, 0x8b8a, 0x101, 0x8d08, 0x101, 0x8f38,
+ 0x101, 0x9072, 0x101, 0x9199, 0x101, 0x9276, 0x101, 0x967c,
+ 0x101, 0x96e3, 0x101, 0x9756, 0x101, 0x97db, 0x101, 0x97ff,
+ 0x101, 0x980b, 0x101, 0x983b, 0x101, 0x9b12, 0x101, 0x9f9c,
+ 0x201, 0xd84a, 0xdc4a, 0x201, 0xd84a, 0xdc44, 0x201, 0xd84c,
+ 0xdfd5, 0x101, 0x3b9d, 0x101, 0x4018, 0x101, 0x4039, 0x201,
+ 0xd854, 0xde49, 0x201, 0xd857, 0xdcd0, 0x201, 0xd85f, 0xded3,
+ 0x101, 0x9f43, 0x101, 0x9f8e, 0x210, 0x66, 0x66, 0x210,
+ 0x66, 0x69, 0x210, 0x66, 0x6c, 0x310, 0x66, 0x66,
+ 0x69, 0x310, 0x66, 0x66, 0x6c, 0x210, 0x17f, 0x74,
+ 0x210, 0x73, 0x74, 0x210, 0x574, 0x576, 0x210, 0x574,
+ 0x565, 0x210, 0x574, 0x56b, 0x210, 0x57e, 0x576, 0x210,
+ 0x574, 0x56d, 0x201, 0x5d9, 0x5b4, 0x201, 0x5f2, 0x5b7,
+ 0x102, 0x5e2, 0x102, 0x5d0, 0x102, 0x5d3, 0x102, 0x5d4,
+ 0x102, 0x5db, 0x102, 0x5dc, 0x102, 0x5dd, 0x102, 0x5e8,
+ 0x102, 0x5ea, 0x102, 0x2b, 0x201, 0x5e9, 0x5c1, 0x201,
+ 0x5e9, 0x5c2, 0x201, 0xfb49, 0x5c1, 0x201, 0xfb49, 0x5c2,
+ 0x201, 0x5d0, 0x5b7, 0x201, 0x5d0, 0x5b8, 0x201, 0x5d0,
+ 0x5bc, 0x201, 0x5d1, 0x5bc, 0x201, 0x5d2, 0x5bc, 0x201,
+ 0x5d3, 0x5bc, 0x201, 0x5d4, 0x5bc, 0x201, 0x5d5, 0x5bc,
+ 0x201, 0x5d6, 0x5bc, 0x201, 0x5d8, 0x5bc, 0x201, 0x5d9,
+ 0x5bc, 0x201, 0x5da, 0x5bc, 0x201, 0x5db, 0x5bc, 0x201,
+ 0x5dc, 0x5bc, 0x201, 0x5de, 0x5bc, 0x201, 0x5e0, 0x5bc,
+ 0x201, 0x5e1, 0x5bc, 0x201, 0x5e3, 0x5bc, 0x201, 0x5e4,
+ 0x5bc, 0x201, 0x5e6, 0x5bc, 0x201, 0x5e7, 0x5bc, 0x201,
+ 0x5e8, 0x5bc, 0x201, 0x5e9, 0x5bc, 0x201, 0x5ea, 0x5bc,
+ 0x201, 0x5d5, 0x5b9, 0x201, 0x5d1, 0x5bf, 0x201, 0x5db,
+ 0x5bf, 0x201, 0x5e4, 0x5bf, 0x210, 0x5d0, 0x5dc, 0x107,
+ 0x671, 0x106, 0x671, 0x107, 0x67b, 0x106, 0x67b, 0x104,
+ 0x67b, 0x105, 0x67b, 0x107, 0x67e, 0x106, 0x67e, 0x104,
+ 0x67e, 0x105, 0x67e, 0x107, 0x680, 0x106, 0x680, 0x104,
+ 0x680, 0x105, 0x680, 0x107, 0x67a, 0x106, 0x67a, 0x104,
+ 0x67a, 0x105, 0x67a, 0x107, 0x67f, 0x106, 0x67f, 0x104,
+ 0x67f, 0x105, 0x67f, 0x107, 0x679, 0x106, 0x679, 0x104,
+ 0x679, 0x105, 0x679, 0x107, 0x6a4, 0x106, 0x6a4, 0x104,
+ 0x6a4, 0x105, 0x6a4, 0x107, 0x6a6, 0x106, 0x6a6, 0x104,
+ 0x6a6, 0x105, 0x6a6, 0x107, 0x684, 0x106, 0x684, 0x104,
+ 0x684, 0x105, 0x684, 0x107, 0x683, 0x106, 0x683, 0x104,
+ 0x683, 0x105, 0x683, 0x107, 0x686, 0x106, 0x686, 0x104,
+ 0x686, 0x105, 0x686, 0x107, 0x687, 0x106, 0x687, 0x104,
+ 0x687, 0x105, 0x687, 0x107, 0x68d, 0x106, 0x68d, 0x107,
+ 0x68c, 0x106, 0x68c, 0x107, 0x68e, 0x106, 0x68e, 0x107,
+ 0x688, 0x106, 0x688, 0x107, 0x698, 0x106, 0x698, 0x107,
+ 0x691, 0x106, 0x691, 0x107, 0x6a9, 0x106, 0x6a9, 0x104,
+ 0x6a9, 0x105, 0x6a9, 0x107, 0x6af, 0x106, 0x6af, 0x104,
+ 0x6af, 0x105, 0x6af, 0x107, 0x6b3, 0x106, 0x6b3, 0x104,
+ 0x6b3, 0x105, 0x6b3, 0x107, 0x6b1, 0x106, 0x6b1, 0x104,
+ 0x6b1, 0x105, 0x6b1, 0x107, 0x6ba, 0x106, 0x6ba, 0x107,
+ 0x6bb, 0x106, 0x6bb, 0x104, 0x6bb, 0x105, 0x6bb, 0x107,
+ 0x6c0, 0x106, 0x6c0, 0x107, 0x6c1, 0x106, 0x6c1, 0x104,
+ 0x6c1, 0x105, 0x6c1, 0x107, 0x6be, 0x106, 0x6be, 0x104,
+ 0x6be, 0x105, 0x6be, 0x107, 0x6d2, 0x106, 0x6d2, 0x107,
+ 0x6d3, 0x106, 0x6d3, 0x107, 0x6ad, 0x106, 0x6ad, 0x104,
+ 0x6ad, 0x105, 0x6ad, 0x107, 0x6c7, 0x106, 0x6c7, 0x107,
+ 0x6c6, 0x106, 0x6c6, 0x107, 0x6c8, 0x106, 0x6c8, 0x107,
+ 0x677, 0x107, 0x6cb, 0x106, 0x6cb, 0x107, 0x6c5, 0x106,
+ 0x6c5, 0x107, 0x6c9, 0x106, 0x6c9, 0x107, 0x6d0, 0x106,
+ 0x6d0, 0x104, 0x6d0, 0x105, 0x6d0, 0x104, 0x649, 0x105,
+ 0x649, 0x207, 0x626, 0x627, 0x206, 0x626, 0x627, 0x207,
+ 0x626, 0x6d5, 0x206, 0x626, 0x6d5, 0x207, 0x626, 0x648,
+ 0x206, 0x626, 0x648, 0x207, 0x626, 0x6c7, 0x206, 0x626,
+ 0x6c7, 0x207, 0x626, 0x6c6, 0x206, 0x626, 0x6c6, 0x207,
+ 0x626, 0x6c8, 0x206, 0x626, 0x6c8, 0x207, 0x626, 0x6d0,
+ 0x206, 0x626, 0x6d0, 0x204, 0x626, 0x6d0, 0x207, 0x626,
+ 0x649, 0x206, 0x626, 0x649, 0x204, 0x626, 0x649, 0x107,
+ 0x6cc, 0x106, 0x6cc, 0x104, 0x6cc, 0x105, 0x6cc, 0x207,
+ 0x626, 0x62c, 0x207, 0x626, 0x62d, 0x207, 0x626, 0x645,
+ 0x207, 0x626, 0x649, 0x207, 0x626, 0x64a, 0x207, 0x628,
+ 0x62c, 0x207, 0x628, 0x62d, 0x207, 0x628, 0x62e, 0x207,
+ 0x628, 0x645, 0x207, 0x628, 0x649, 0x207, 0x628, 0x64a,
+ 0x207, 0x62a, 0x62c, 0x207, 0x62a, 0x62d, 0x207, 0x62a,
+ 0x62e, 0x207, 0x62a, 0x645, 0x207, 0x62a, 0x649, 0x207,
+ 0x62a, 0x64a, 0x207, 0x62b, 0x62c, 0x207, 0x62b, 0x645,
+ 0x207, 0x62b, 0x649, 0x207, 0x62b, 0x64a, 0x207, 0x62c,
+ 0x62d, 0x207, 0x62c, 0x645, 0x207, 0x62d, 0x62c, 0x207,
+ 0x62d, 0x645, 0x207, 0x62e, 0x62c, 0x207, 0x62e, 0x62d,
+ 0x207, 0x62e, 0x645, 0x207, 0x633, 0x62c, 0x207, 0x633,
+ 0x62d, 0x207, 0x633, 0x62e, 0x207, 0x633, 0x645, 0x207,
+ 0x635, 0x62d, 0x207, 0x635, 0x645, 0x207, 0x636, 0x62c,
+ 0x207, 0x636, 0x62d, 0x207, 0x636, 0x62e, 0x207, 0x636,
+ 0x645, 0x207, 0x637, 0x62d, 0x207, 0x637, 0x645, 0x207,
+ 0x638, 0x645, 0x207, 0x639, 0x62c, 0x207, 0x639, 0x645,
+ 0x207, 0x63a, 0x62c, 0x207, 0x63a, 0x645, 0x207, 0x641,
+ 0x62c, 0x207, 0x641, 0x62d, 0x207, 0x641, 0x62e, 0x207,
+ 0x641, 0x645, 0x207, 0x641, 0x649, 0x207, 0x641, 0x64a,
+ 0x207, 0x642, 0x62d, 0x207, 0x642, 0x645, 0x207, 0x642,
+ 0x649, 0x207, 0x642, 0x64a, 0x207, 0x643, 0x627, 0x207,
+ 0x643, 0x62c, 0x207, 0x643, 0x62d, 0x207, 0x643, 0x62e,
+ 0x207, 0x643, 0x644, 0x207, 0x643, 0x645, 0x207, 0x643,
+ 0x649, 0x207, 0x643, 0x64a, 0x207, 0x644, 0x62c, 0x207,
+ 0x644, 0x62d, 0x207, 0x644, 0x62e, 0x207, 0x644, 0x645,
+ 0x207, 0x644, 0x649, 0x207, 0x644, 0x64a, 0x207, 0x645,
+ 0x62c, 0x207, 0x645, 0x62d, 0x207, 0x645, 0x62e, 0x207,
+ 0x645, 0x645, 0x207, 0x645, 0x649, 0x207, 0x645, 0x64a,
+ 0x207, 0x646, 0x62c, 0x207, 0x646, 0x62d, 0x207, 0x646,
+ 0x62e, 0x207, 0x646, 0x645, 0x207, 0x646, 0x649, 0x207,
+ 0x646, 0x64a, 0x207, 0x647, 0x62c, 0x207, 0x647, 0x645,
+ 0x207, 0x647, 0x649, 0x207, 0x647, 0x64a, 0x207, 0x64a,
+ 0x62c, 0x207, 0x64a, 0x62d, 0x207, 0x64a, 0x62e, 0x207,
+ 0x64a, 0x645, 0x207, 0x64a, 0x649, 0x207, 0x64a, 0x64a,
+ 0x207, 0x630, 0x670, 0x207, 0x631, 0x670, 0x207, 0x649,
+ 0x670, 0x307, 0x20, 0x64c, 0x651, 0x307, 0x20, 0x64d,
+ 0x651, 0x307, 0x20, 0x64e, 0x651, 0x307, 0x20, 0x64f,
+ 0x651, 0x307, 0x20, 0x650, 0x651, 0x307, 0x20, 0x651,
+ 0x670, 0x206, 0x626, 0x631, 0x206, 0x626, 0x632, 0x206,
+ 0x626, 0x645, 0x206, 0x626, 0x646, 0x206, 0x626, 0x649,
+ 0x206, 0x626, 0x64a, 0x206, 0x628, 0x631, 0x206, 0x628,
+ 0x632, 0x206, 0x628, 0x645, 0x206, 0x628, 0x646, 0x206,
+ 0x628, 0x649, 0x206, 0x628, 0x64a, 0x206, 0x62a, 0x631,
+ 0x206, 0x62a, 0x632, 0x206, 0x62a, 0x645, 0x206, 0x62a,
+ 0x646, 0x206, 0x62a, 0x649, 0x206, 0x62a, 0x64a, 0x206,
+ 0x62b, 0x631, 0x206, 0x62b, 0x632, 0x206, 0x62b, 0x645,
+ 0x206, 0x62b, 0x646, 0x206, 0x62b, 0x649, 0x206, 0x62b,
+ 0x64a, 0x206, 0x641, 0x649, 0x206, 0x641, 0x64a, 0x206,
+ 0x642, 0x649, 0x206, 0x642, 0x64a, 0x206, 0x643, 0x627,
+ 0x206, 0x643, 0x644, 0x206, 0x643, 0x645, 0x206, 0x643,
+ 0x649, 0x206, 0x643, 0x64a, 0x206, 0x644, 0x645, 0x206,
+ 0x644, 0x649, 0x206, 0x644, 0x64a, 0x206, 0x645, 0x627,
+ 0x206, 0x645, 0x645, 0x206, 0x646, 0x631, 0x206, 0x646,
+ 0x632, 0x206, 0x646, 0x645, 0x206, 0x646, 0x646, 0x206,
+ 0x646, 0x649, 0x206, 0x646, 0x64a, 0x206, 0x649, 0x670,
+ 0x206, 0x64a, 0x631, 0x206, 0x64a, 0x632, 0x206, 0x64a,
+ 0x645, 0x206, 0x64a, 0x646, 0x206, 0x64a, 0x649, 0x206,
+ 0x64a, 0x64a, 0x204, 0x626, 0x62c, 0x204, 0x626, 0x62d,
+ 0x204, 0x626, 0x62e, 0x204, 0x626, 0x645, 0x204, 0x626,
+ 0x647, 0x204, 0x628, 0x62c, 0x204, 0x628, 0x62d, 0x204,
+ 0x628, 0x62e, 0x204, 0x628, 0x645, 0x204, 0x628, 0x647,
+ 0x204, 0x62a, 0x62c, 0x204, 0x62a, 0x62d, 0x204, 0x62a,
+ 0x62e, 0x204, 0x62a, 0x645, 0x204, 0x62a, 0x647, 0x204,
+ 0x62b, 0x645, 0x204, 0x62c, 0x62d, 0x204, 0x62c, 0x645,
+ 0x204, 0x62d, 0x62c, 0x204, 0x62d, 0x645, 0x204, 0x62e,
+ 0x62c, 0x204, 0x62e, 0x645, 0x204, 0x633, 0x62c, 0x204,
+ 0x633, 0x62d, 0x204, 0x633, 0x62e, 0x204, 0x633, 0x645,
+ 0x204, 0x635, 0x62d, 0x204, 0x635, 0x62e, 0x204, 0x635,
+ 0x645, 0x204, 0x636, 0x62c, 0x204, 0x636, 0x62d, 0x204,
+ 0x636, 0x62e, 0x204, 0x636, 0x645, 0x204, 0x637, 0x62d,
+ 0x204, 0x638, 0x645, 0x204, 0x639, 0x62c, 0x204, 0x639,
+ 0x645, 0x204, 0x63a, 0x62c, 0x204, 0x63a, 0x645, 0x204,
+ 0x641, 0x62c, 0x204, 0x641, 0x62d, 0x204, 0x641, 0x62e,
+ 0x204, 0x641, 0x645, 0x204, 0x642, 0x62d, 0x204, 0x642,
+ 0x645, 0x204, 0x643, 0x62c, 0x204, 0x643, 0x62d, 0x204,
+ 0x643, 0x62e, 0x204, 0x643, 0x644, 0x204, 0x643, 0x645,
+ 0x204, 0x644, 0x62c, 0x204, 0x644, 0x62d, 0x204, 0x644,
+ 0x62e, 0x204, 0x644, 0x645, 0x204, 0x644, 0x647, 0x204,
+ 0x645, 0x62c, 0x204, 0x645, 0x62d, 0x204, 0x645, 0x62e,
+ 0x204, 0x645, 0x645, 0x204, 0x646, 0x62c, 0x204, 0x646,
+ 0x62d, 0x204, 0x646, 0x62e, 0x204, 0x646, 0x645, 0x204,
+ 0x646, 0x647, 0x204, 0x647, 0x62c, 0x204, 0x647, 0x645,
+ 0x204, 0x647, 0x670, 0x204, 0x64a, 0x62c, 0x204, 0x64a,
+ 0x62d, 0x204, 0x64a, 0x62e, 0x204, 0x64a, 0x645, 0x204,
+ 0x64a, 0x647, 0x205, 0x626, 0x645, 0x205, 0x626, 0x647,
+ 0x205, 0x628, 0x645, 0x205, 0x628, 0x647, 0x205, 0x62a,
+ 0x645, 0x205, 0x62a, 0x647, 0x205, 0x62b, 0x645, 0x205,
+ 0x62b, 0x647, 0x205, 0x633, 0x645, 0x205, 0x633, 0x647,
+ 0x205, 0x634, 0x645, 0x205, 0x634, 0x647, 0x205, 0x643,
+ 0x644, 0x205, 0x643, 0x645, 0x205, 0x644, 0x645, 0x205,
+ 0x646, 0x645, 0x205, 0x646, 0x647, 0x205, 0x64a, 0x645,
+ 0x205, 0x64a, 0x647, 0x305, 0x640, 0x64e, 0x651, 0x305,
+ 0x640, 0x64f, 0x651, 0x305, 0x640, 0x650, 0x651, 0x207,
+ 0x637, 0x649, 0x207, 0x637, 0x64a, 0x207, 0x639, 0x649,
+ 0x207, 0x639, 0x64a, 0x207, 0x63a, 0x649, 0x207, 0x63a,
+ 0x64a, 0x207, 0x633, 0x649, 0x207, 0x633, 0x64a, 0x207,
+ 0x634, 0x649, 0x207, 0x634, 0x64a, 0x207, 0x62d, 0x649,
+ 0x207, 0x62d, 0x64a, 0x207, 0x62c, 0x649, 0x207, 0x62c,
+ 0x64a, 0x207, 0x62e, 0x649, 0x207, 0x62e, 0x64a, 0x207,
+ 0x635, 0x649, 0x207, 0x635, 0x64a, 0x207, 0x636, 0x649,
+ 0x207, 0x636, 0x64a, 0x207, 0x634, 0x62c, 0x207, 0x634,
+ 0x62d, 0x207, 0x634, 0x62e, 0x207, 0x634, 0x645, 0x207,
+ 0x634, 0x631, 0x207, 0x633, 0x631, 0x207, 0x635, 0x631,
+ 0x207, 0x636, 0x631, 0x206, 0x637, 0x649, 0x206, 0x637,
+ 0x64a, 0x206, 0x639, 0x649, 0x206, 0x639, 0x64a, 0x206,
+ 0x63a, 0x649, 0x206, 0x63a, 0x64a, 0x206, 0x633, 0x649,
+ 0x206, 0x633, 0x64a, 0x206, 0x634, 0x649, 0x206, 0x634,
+ 0x64a, 0x206, 0x62d, 0x649, 0x206, 0x62d, 0x64a, 0x206,
+ 0x62c, 0x649, 0x206, 0x62c, 0x64a, 0x206, 0x62e, 0x649,
+ 0x206, 0x62e, 0x64a, 0x206, 0x635, 0x649, 0x206, 0x635,
+ 0x64a, 0x206, 0x636, 0x649, 0x206, 0x636, 0x64a, 0x206,
+ 0x634, 0x62c, 0x206, 0x634, 0x62d, 0x206, 0x634, 0x62e,
+ 0x206, 0x634, 0x645, 0x206, 0x634, 0x631, 0x206, 0x633,
+ 0x631, 0x206, 0x635, 0x631, 0x206, 0x636, 0x631, 0x204,
+ 0x634, 0x62c, 0x204, 0x634, 0x62d, 0x204, 0x634, 0x62e,
+ 0x204, 0x634, 0x645, 0x204, 0x633, 0x647, 0x204, 0x634,
+ 0x647, 0x204, 0x637, 0x645, 0x205, 0x633, 0x62c, 0x205,
+ 0x633, 0x62d, 0x205, 0x633, 0x62e, 0x205, 0x634, 0x62c,
+ 0x205, 0x634, 0x62d, 0x205, 0x634, 0x62e, 0x205, 0x637,
+ 0x645, 0x205, 0x638, 0x645, 0x206, 0x627, 0x64b, 0x207,
+ 0x627, 0x64b, 0x304, 0x62a, 0x62c, 0x645, 0x306, 0x62a,
+ 0x62d, 0x62c, 0x304, 0x62a, 0x62d, 0x62c, 0x304, 0x62a,
+ 0x62d, 0x645, 0x304, 0x62a, 0x62e, 0x645, 0x304, 0x62a,
+ 0x645, 0x62c, 0x304, 0x62a, 0x645, 0x62d, 0x304, 0x62a,
+ 0x645, 0x62e, 0x306, 0x62c, 0x645, 0x62d, 0x304, 0x62c,
+ 0x645, 0x62d, 0x306, 0x62d, 0x645, 0x64a, 0x306, 0x62d,
+ 0x645, 0x649, 0x304, 0x633, 0x62d, 0x62c, 0x304, 0x633,
+ 0x62c, 0x62d, 0x306, 0x633, 0x62c, 0x649, 0x306, 0x633,
+ 0x645, 0x62d, 0x304, 0x633, 0x645, 0x62d, 0x304, 0x633,
+ 0x645, 0x62c, 0x306, 0x633, 0x645, 0x645, 0x304, 0x633,
+ 0x645, 0x645, 0x306, 0x635, 0x62d, 0x62d, 0x304, 0x635,
+ 0x62d, 0x62d, 0x306, 0x635, 0x645, 0x645, 0x306, 0x634,
+ 0x62d, 0x645, 0x304, 0x634, 0x62d, 0x645, 0x306, 0x634,
+ 0x62c, 0x64a, 0x306, 0x634, 0x645, 0x62e, 0x304, 0x634,
+ 0x645, 0x62e, 0x306, 0x634, 0x645, 0x645, 0x304, 0x634,
+ 0x645, 0x645, 0x306, 0x636, 0x62d, 0x649, 0x306, 0x636,
+ 0x62e, 0x645, 0x304, 0x636, 0x62e, 0x645, 0x306, 0x637,
+ 0x645, 0x62d, 0x304, 0x637, 0x645, 0x62d, 0x304, 0x637,
+ 0x645, 0x645, 0x306, 0x637, 0x645, 0x64a, 0x306, 0x639,
+ 0x62c, 0x645, 0x306, 0x639, 0x645, 0x645, 0x304, 0x639,
+ 0x645, 0x645, 0x306, 0x639, 0x645, 0x649, 0x306, 0x63a,
+ 0x645, 0x645, 0x306, 0x63a, 0x645, 0x64a, 0x306, 0x63a,
+ 0x645, 0x649, 0x306, 0x641, 0x62e, 0x645, 0x304, 0x641,
+ 0x62e, 0x645, 0x306, 0x642, 0x645, 0x62d, 0x306, 0x642,
+ 0x645, 0x645, 0x306, 0x644, 0x62d, 0x645, 0x306, 0x644,
+ 0x62d, 0x64a, 0x306, 0x644, 0x62d, 0x649, 0x304, 0x644,
+ 0x62c, 0x62c, 0x306, 0x644, 0x62c, 0x62c, 0x306, 0x644,
+ 0x62e, 0x645, 0x304, 0x644, 0x62e, 0x645, 0x306, 0x644,
+ 0x645, 0x62d, 0x304, 0x644, 0x645, 0x62d, 0x304, 0x645,
+ 0x62d, 0x62c, 0x304, 0x645, 0x62d, 0x645, 0x306, 0x645,
+ 0x62d, 0x64a, 0x304, 0x645, 0x62c, 0x62d, 0x304, 0x645,
+ 0x62c, 0x645, 0x304, 0x645, 0x62e, 0x62c, 0x304, 0x645,
+ 0x62e, 0x645, 0x304, 0x645, 0x62c, 0x62e, 0x304, 0x647,
+ 0x645, 0x62c, 0x304, 0x647, 0x645, 0x645, 0x304, 0x646,
+ 0x62d, 0x645, 0x306, 0x646, 0x62d, 0x649, 0x306, 0x646,
+ 0x62c, 0x645, 0x304, 0x646, 0x62c, 0x645, 0x306, 0x646,
+ 0x62c, 0x649, 0x306, 0x646, 0x645, 0x64a, 0x306, 0x646,
+ 0x645, 0x649, 0x306, 0x64a, 0x645, 0x645, 0x304, 0x64a,
+ 0x645, 0x645, 0x306, 0x628, 0x62e, 0x64a, 0x306, 0x62a,
+ 0x62c, 0x64a, 0x306, 0x62a, 0x62c, 0x649, 0x306, 0x62a,
+ 0x62e, 0x64a, 0x306, 0x62a, 0x62e, 0x649, 0x306, 0x62a,
+ 0x645, 0x64a, 0x306, 0x62a, 0x645, 0x649, 0x306, 0x62c,
+ 0x645, 0x64a, 0x306, 0x62c, 0x62d, 0x649, 0x306, 0x62c,
+ 0x645, 0x649, 0x306, 0x633, 0x62e, 0x649, 0x306, 0x635,
+ 0x62d, 0x64a, 0x306, 0x634, 0x62d, 0x64a, 0x306, 0x636,
+ 0x62d, 0x64a, 0x306, 0x644, 0x62c, 0x64a, 0x306, 0x644,
+ 0x645, 0x64a, 0x306, 0x64a, 0x62d, 0x64a, 0x306, 0x64a,
+ 0x62c, 0x64a, 0x306, 0x64a, 0x645, 0x64a, 0x306, 0x645,
+ 0x645, 0x64a, 0x306, 0x642, 0x645, 0x64a, 0x306, 0x646,
+ 0x62d, 0x64a, 0x304, 0x642, 0x645, 0x62d, 0x304, 0x644,
+ 0x62d, 0x645, 0x306, 0x639, 0x645, 0x64a, 0x306, 0x643,
+ 0x645, 0x64a, 0x304, 0x646, 0x62c, 0x62d, 0x306, 0x645,
+ 0x62e, 0x64a, 0x304, 0x644, 0x62c, 0x645, 0x306, 0x643,
+ 0x645, 0x645, 0x306, 0x644, 0x62c, 0x645, 0x306, 0x646,
+ 0x62c, 0x62d, 0x306, 0x62c, 0x62d, 0x64a, 0x306, 0x62d,
+ 0x62c, 0x64a, 0x306, 0x645, 0x62c, 0x64a, 0x306, 0x641,
+ 0x645, 0x64a, 0x306, 0x628, 0x62d, 0x64a, 0x304, 0x643,
+ 0x645, 0x645, 0x304, 0x639, 0x62c, 0x645, 0x304, 0x635,
+ 0x645, 0x645, 0x306, 0x633, 0x62e, 0x64a, 0x306, 0x646,
+ 0x62c, 0x64a, 0x307, 0x635, 0x644, 0x6d2, 0x307, 0x642,
+ 0x644, 0x6d2, 0x407, 0x627, 0x644, 0x644, 0x647, 0x407,
+ 0x627, 0x643, 0x628, 0x631, 0x407, 0x645, 0x62d, 0x645,
+ 0x62f, 0x407, 0x635, 0x644, 0x639, 0x645, 0x407, 0x631,
+ 0x633, 0x648, 0x644, 0x407, 0x639, 0x644, 0x64a, 0x647,
+ 0x407, 0x648, 0x633, 0x644, 0x645, 0x307, 0x635, 0x644,
+ 0x649, 0x1207, 0x635, 0x644, 0x649, 0x20, 0x627, 0x644,
+ 0x644, 0x647, 0x20, 0x639, 0x644, 0x64a, 0x647, 0x20,
+ 0x648, 0x633, 0x644, 0x645, 0x807, 0x62c, 0x644, 0x20,
+ 0x62c, 0x644, 0x627, 0x644, 0x647, 0x407, 0x631, 0x6cc,
+ 0x627, 0x644, 0x10b, 0x2c, 0x10b, 0x3001, 0x10b, 0x3002,
+ 0x10b, 0x3a, 0x10b, 0x3b, 0x10b, 0x21, 0x10b, 0x3f,
+ 0x10b, 0x3016, 0x10b, 0x3017, 0x10b, 0x2026, 0x10b, 0x2025,
+ 0x10b, 0x2014, 0x10b, 0x2013, 0x10b, 0x5f, 0x10b, 0x5f,
+ 0x10b, 0x28, 0x10b, 0x29, 0x10b, 0x7b, 0x10b, 0x7d,
+ 0x10b, 0x3014, 0x10b, 0x3015, 0x10b, 0x3010, 0x10b, 0x3011,
+ 0x10b, 0x300a, 0x10b, 0x300b, 0x10b, 0x3008, 0x10b, 0x3009,
+ 0x10b, 0x300c, 0x10b, 0x300d, 0x10b, 0x300e, 0x10b, 0x300f,
+ 0x10b, 0x5b, 0x10b, 0x5d, 0x110, 0x203e, 0x110, 0x203e,
+ 0x110, 0x203e, 0x110, 0x203e, 0x110, 0x5f, 0x110, 0x5f,
+ 0x110, 0x5f, 0x10e, 0x2c, 0x10e, 0x3001, 0x10e, 0x2e,
+ 0x10e, 0x3b, 0x10e, 0x3a, 0x10e, 0x3f, 0x10e, 0x21,
+ 0x10e, 0x2014, 0x10e, 0x28, 0x10e, 0x29, 0x10e, 0x7b,
+ 0x10e, 0x7d, 0x10e, 0x3014, 0x10e, 0x3015, 0x10e, 0x23,
+ 0x10e, 0x26, 0x10e, 0x2a, 0x10e, 0x2b, 0x10e, 0x2d,
+ 0x10e, 0x3c, 0x10e, 0x3e, 0x10e, 0x3d, 0x10e, 0x5c,
+ 0x10e, 0x24, 0x10e, 0x25, 0x10e, 0x40, 0x207, 0x20,
+ 0x64b, 0x205, 0x640, 0x64b, 0x207, 0x20, 0x64c, 0x207,
+ 0x20, 0x64d, 0x207, 0x20, 0x64e, 0x205, 0x640, 0x64e,
+ 0x207, 0x20, 0x64f, 0x205, 0x640, 0x64f, 0x207, 0x20,
+ 0x650, 0x205, 0x640, 0x650, 0x207, 0x20, 0x651, 0x205,
+ 0x640, 0x651, 0x207, 0x20, 0x652, 0x205, 0x640, 0x652,
+ 0x107, 0x621, 0x107, 0x622, 0x106, 0x622, 0x107, 0x623,
+ 0x106, 0x623, 0x107, 0x624, 0x106, 0x624, 0x107, 0x625,
+ 0x106, 0x625, 0x107, 0x626, 0x106, 0x626, 0x104, 0x626,
+ 0x105, 0x626, 0x107, 0x627, 0x106, 0x627, 0x107, 0x628,
+ 0x106, 0x628, 0x104, 0x628, 0x105, 0x628, 0x107, 0x629,
+ 0x106, 0x629, 0x107, 0x62a, 0x106, 0x62a, 0x104, 0x62a,
+ 0x105, 0x62a, 0x107, 0x62b, 0x106, 0x62b, 0x104, 0x62b,
+ 0x105, 0x62b, 0x107, 0x62c, 0x106, 0x62c, 0x104, 0x62c,
+ 0x105, 0x62c, 0x107, 0x62d, 0x106, 0x62d, 0x104, 0x62d,
+ 0x105, 0x62d, 0x107, 0x62e, 0x106, 0x62e, 0x104, 0x62e,
+ 0x105, 0x62e, 0x107, 0x62f, 0x106, 0x62f, 0x107, 0x630,
+ 0x106, 0x630, 0x107, 0x631, 0x106, 0x631, 0x107, 0x632,
+ 0x106, 0x632, 0x107, 0x633, 0x106, 0x633, 0x104, 0x633,
+ 0x105, 0x633, 0x107, 0x634, 0x106, 0x634, 0x104, 0x634,
+ 0x105, 0x634, 0x107, 0x635, 0x106, 0x635, 0x104, 0x635,
+ 0x105, 0x635, 0x107, 0x636, 0x106, 0x636, 0x104, 0x636,
+ 0x105, 0x636, 0x107, 0x637, 0x106, 0x637, 0x104, 0x637,
+ 0x105, 0x637, 0x107, 0x638, 0x106, 0x638, 0x104, 0x638,
+ 0x105, 0x638, 0x107, 0x639, 0x106, 0x639, 0x104, 0x639,
+ 0x105, 0x639, 0x107, 0x63a, 0x106, 0x63a, 0x104, 0x63a,
+ 0x105, 0x63a, 0x107, 0x641, 0x106, 0x641, 0x104, 0x641,
+ 0x105, 0x641, 0x107, 0x642, 0x106, 0x642, 0x104, 0x642,
+ 0x105, 0x642, 0x107, 0x643, 0x106, 0x643, 0x104, 0x643,
+ 0x105, 0x643, 0x107, 0x644, 0x106, 0x644, 0x104, 0x644,
+ 0x105, 0x644, 0x107, 0x645, 0x106, 0x645, 0x104, 0x645,
+ 0x105, 0x645, 0x107, 0x646, 0x106, 0x646, 0x104, 0x646,
+ 0x105, 0x646, 0x107, 0x647, 0x106, 0x647, 0x104, 0x647,
+ 0x105, 0x647, 0x107, 0x648, 0x106, 0x648, 0x107, 0x649,
+ 0x106, 0x649, 0x107, 0x64a, 0x106, 0x64a, 0x104, 0x64a,
+ 0x105, 0x64a, 0x207, 0x644, 0x622, 0x206, 0x644, 0x622,
+ 0x207, 0x644, 0x623, 0x206, 0x644, 0x623, 0x207, 0x644,
+ 0x625, 0x206, 0x644, 0x625, 0x207, 0x644, 0x627, 0x206,
+ 0x644, 0x627, 0x10c, 0x21, 0x10c, 0x22, 0x10c, 0x23,
+ 0x10c, 0x24, 0x10c, 0x25, 0x10c, 0x26, 0x10c, 0x27,
+ 0x10c, 0x28, 0x10c, 0x29, 0x10c, 0x2a, 0x10c, 0x2b,
+ 0x10c, 0x2c, 0x10c, 0x2d, 0x10c, 0x2e, 0x10c, 0x2f,
+ 0x10c, 0x30, 0x10c, 0x31, 0x10c, 0x32, 0x10c, 0x33,
+ 0x10c, 0x34, 0x10c, 0x35, 0x10c, 0x36, 0x10c, 0x37,
+ 0x10c, 0x38, 0x10c, 0x39, 0x10c, 0x3a, 0x10c, 0x3b,
+ 0x10c, 0x3c, 0x10c, 0x3d, 0x10c, 0x3e, 0x10c, 0x3f,
+ 0x10c, 0x40, 0x10c, 0x41, 0x10c, 0x42, 0x10c, 0x43,
+ 0x10c, 0x44, 0x10c, 0x45, 0x10c, 0x46, 0x10c, 0x47,
+ 0x10c, 0x48, 0x10c, 0x49, 0x10c, 0x4a, 0x10c, 0x4b,
+ 0x10c, 0x4c, 0x10c, 0x4d, 0x10c, 0x4e, 0x10c, 0x4f,
+ 0x10c, 0x50, 0x10c, 0x51, 0x10c, 0x52, 0x10c, 0x53,
+ 0x10c, 0x54, 0x10c, 0x55, 0x10c, 0x56, 0x10c, 0x57,
+ 0x10c, 0x58, 0x10c, 0x59, 0x10c, 0x5a, 0x10c, 0x5b,
+ 0x10c, 0x5c, 0x10c, 0x5d, 0x10c, 0x5e, 0x10c, 0x5f,
+ 0x10c, 0x60, 0x10c, 0x61, 0x10c, 0x62, 0x10c, 0x63,
+ 0x10c, 0x64, 0x10c, 0x65, 0x10c, 0x66, 0x10c, 0x67,
+ 0x10c, 0x68, 0x10c, 0x69, 0x10c, 0x6a, 0x10c, 0x6b,
+ 0x10c, 0x6c, 0x10c, 0x6d, 0x10c, 0x6e, 0x10c, 0x6f,
+ 0x10c, 0x70, 0x10c, 0x71, 0x10c, 0x72, 0x10c, 0x73,
+ 0x10c, 0x74, 0x10c, 0x75, 0x10c, 0x76, 0x10c, 0x77,
+ 0x10c, 0x78, 0x10c, 0x79, 0x10c, 0x7a, 0x10c, 0x7b,
+ 0x10c, 0x7c, 0x10c, 0x7d, 0x10c, 0x7e, 0x10c, 0x2985,
+ 0x10c, 0x2986, 0x10d, 0x3002, 0x10d, 0x300c, 0x10d, 0x300d,
+ 0x10d, 0x3001, 0x10d, 0x30fb, 0x10d, 0x30f2, 0x10d, 0x30a1,
+ 0x10d, 0x30a3, 0x10d, 0x30a5, 0x10d, 0x30a7, 0x10d, 0x30a9,
+ 0x10d, 0x30e3, 0x10d, 0x30e5, 0x10d, 0x30e7, 0x10d, 0x30c3,
+ 0x10d, 0x30fc, 0x10d, 0x30a2, 0x10d, 0x30a4, 0x10d, 0x30a6,
+ 0x10d, 0x30a8, 0x10d, 0x30aa, 0x10d, 0x30ab, 0x10d, 0x30ad,
+ 0x10d, 0x30af, 0x10d, 0x30b1, 0x10d, 0x30b3, 0x10d, 0x30b5,
+ 0x10d, 0x30b7, 0x10d, 0x30b9, 0x10d, 0x30bb, 0x10d, 0x30bd,
+ 0x10d, 0x30bf, 0x10d, 0x30c1, 0x10d, 0x30c4, 0x10d, 0x30c6,
+ 0x10d, 0x30c8, 0x10d, 0x30ca, 0x10d, 0x30cb, 0x10d, 0x30cc,
+ 0x10d, 0x30cd, 0x10d, 0x30ce, 0x10d, 0x30cf, 0x10d, 0x30d2,
+ 0x10d, 0x30d5, 0x10d, 0x30d8, 0x10d, 0x30db, 0x10d, 0x30de,
+ 0x10d, 0x30df, 0x10d, 0x30e0, 0x10d, 0x30e1, 0x10d, 0x30e2,
+ 0x10d, 0x30e4, 0x10d, 0x30e6, 0x10d, 0x30e8, 0x10d, 0x30e9,
+ 0x10d, 0x30ea, 0x10d, 0x30eb, 0x10d, 0x30ec, 0x10d, 0x30ed,
+ 0x10d, 0x30ef, 0x10d, 0x30f3, 0x10d, 0x3099, 0x10d, 0x309a,
+ 0x10d, 0x3164, 0x10d, 0x3131, 0x10d, 0x3132, 0x10d, 0x3133,
+ 0x10d, 0x3134, 0x10d, 0x3135, 0x10d, 0x3136, 0x10d, 0x3137,
+ 0x10d, 0x3138, 0x10d, 0x3139, 0x10d, 0x313a, 0x10d, 0x313b,
+ 0x10d, 0x313c, 0x10d, 0x313d, 0x10d, 0x313e, 0x10d, 0x313f,
+ 0x10d, 0x3140, 0x10d, 0x3141, 0x10d, 0x3142, 0x10d, 0x3143,
+ 0x10d, 0x3144, 0x10d, 0x3145, 0x10d, 0x3146, 0x10d, 0x3147,
+ 0x10d, 0x3148, 0x10d, 0x3149, 0x10d, 0x314a, 0x10d, 0x314b,
+ 0x10d, 0x314c, 0x10d, 0x314d, 0x10d, 0x314e, 0x10d, 0x314f,
+ 0x10d, 0x3150, 0x10d, 0x3151, 0x10d, 0x3152, 0x10d, 0x3153,
+ 0x10d, 0x3154, 0x10d, 0x3155, 0x10d, 0x3156, 0x10d, 0x3157,
+ 0x10d, 0x3158, 0x10d, 0x3159, 0x10d, 0x315a, 0x10d, 0x315b,
+ 0x10d, 0x315c, 0x10d, 0x315d, 0x10d, 0x315e, 0x10d, 0x315f,
+ 0x10d, 0x3160, 0x10d, 0x3161, 0x10d, 0x3162, 0x10d, 0x3163,
+ 0x10c, 0xa2, 0x10c, 0xa3, 0x10c, 0xac, 0x10c, 0xaf,
+ 0x10c, 0xa6, 0x10c, 0xa5, 0x10c, 0x20a9, 0x10d, 0x2502,
+ 0x10d, 0x2190, 0x10d, 0x2191, 0x10d, 0x2192, 0x10d, 0x2193,
+ 0x10d, 0x25a0, 0x10d, 0x25cb, 0x401, 0xd834, 0xdd57, 0xd834,
+ 0xdd65, 0x401, 0xd834, 0xdd58, 0xd834, 0xdd65, 0x401, 0xd834,
+ 0xdd5f, 0xd834, 0xdd6e, 0x401, 0xd834, 0xdd5f, 0xd834, 0xdd6f,
+ 0x401, 0xd834, 0xdd5f, 0xd834, 0xdd70, 0x401, 0xd834, 0xdd5f,
+ 0xd834, 0xdd71, 0x401, 0xd834, 0xdd5f, 0xd834, 0xdd72, 0x401,
+ 0xd834, 0xddb9, 0xd834, 0xdd65, 0x401, 0xd834, 0xddba, 0xd834,
+ 0xdd65, 0x401, 0xd834, 0xddbb, 0xd834, 0xdd6e, 0x401, 0xd834,
+ 0xddbc, 0xd834, 0xdd6e, 0x401, 0xd834, 0xddbb, 0xd834, 0xdd6f,
+ 0x401, 0xd834, 0xddbc, 0xd834, 0xdd6f, 0x102, 0x41, 0x102,
+ 0x42, 0x102, 0x43, 0x102, 0x44, 0x102, 0x45, 0x102,
+ 0x46, 0x102, 0x47, 0x102, 0x48, 0x102, 0x49, 0x102,
+ 0x4a, 0x102, 0x4b, 0x102, 0x4c, 0x102, 0x4d, 0x102,
+ 0x4e, 0x102, 0x4f, 0x102, 0x50, 0x102, 0x51, 0x102,
+ 0x52, 0x102, 0x53, 0x102, 0x54, 0x102, 0x55, 0x102,
+ 0x56, 0x102, 0x57, 0x102, 0x58, 0x102, 0x59, 0x102,
+ 0x5a, 0x102, 0x61, 0x102, 0x62, 0x102, 0x63, 0x102,
+ 0x64, 0x102, 0x65, 0x102, 0x66, 0x102, 0x67, 0x102,
+ 0x68, 0x102, 0x69, 0x102, 0x6a, 0x102, 0x6b, 0x102,
+ 0x6c, 0x102, 0x6d, 0x102, 0x6e, 0x102, 0x6f, 0x102,
+ 0x70, 0x102, 0x71, 0x102, 0x72, 0x102, 0x73, 0x102,
+ 0x74, 0x102, 0x75, 0x102, 0x76, 0x102, 0x77, 0x102,
+ 0x78, 0x102, 0x79, 0x102, 0x7a, 0x102, 0x41, 0x102,
+ 0x42, 0x102, 0x43, 0x102, 0x44, 0x102, 0x45, 0x102,
+ 0x46, 0x102, 0x47, 0x102, 0x48, 0x102, 0x49, 0x102,
+ 0x4a, 0x102, 0x4b, 0x102, 0x4c, 0x102, 0x4d, 0x102,
+ 0x4e, 0x102, 0x4f, 0x102, 0x50, 0x102, 0x51, 0x102,
+ 0x52, 0x102, 0x53, 0x102, 0x54, 0x102, 0x55, 0x102,
+ 0x56, 0x102, 0x57, 0x102, 0x58, 0x102, 0x59, 0x102,
+ 0x5a, 0x102, 0x61, 0x102, 0x62, 0x102, 0x63, 0x102,
+ 0x64, 0x102, 0x65, 0x102, 0x66, 0x102, 0x67, 0x102,
+ 0x69, 0x102, 0x6a, 0x102, 0x6b, 0x102, 0x6c, 0x102,
+ 0x6d, 0x102, 0x6e, 0x102, 0x6f, 0x102, 0x70, 0x102,
+ 0x71, 0x102, 0x72, 0x102, 0x73, 0x102, 0x74, 0x102,
+ 0x75, 0x102, 0x76, 0x102, 0x77, 0x102, 0x78, 0x102,
+ 0x79, 0x102, 0x7a, 0x102, 0x41, 0x102, 0x42, 0x102,
+ 0x43, 0x102, 0x44, 0x102, 0x45, 0x102, 0x46, 0x102,
+ 0x47, 0x102, 0x48, 0x102, 0x49, 0x102, 0x4a, 0x102,
+ 0x4b, 0x102, 0x4c, 0x102, 0x4d, 0x102, 0x4e, 0x102,
+ 0x4f, 0x102, 0x50, 0x102, 0x51, 0x102, 0x52, 0x102,
+ 0x53, 0x102, 0x54, 0x102, 0x55, 0x102, 0x56, 0x102,
+ 0x57, 0x102, 0x58, 0x102, 0x59, 0x102, 0x5a, 0x102,
+ 0x61, 0x102, 0x62, 0x102, 0x63, 0x102, 0x64, 0x102,
+ 0x65, 0x102, 0x66, 0x102, 0x67, 0x102, 0x68, 0x102,
+ 0x69, 0x102, 0x6a, 0x102, 0x6b, 0x102, 0x6c, 0x102,
+ 0x6d, 0x102, 0x6e, 0x102, 0x6f, 0x102, 0x70, 0x102,
+ 0x71, 0x102, 0x72, 0x102, 0x73, 0x102, 0x74, 0x102,
+ 0x75, 0x102, 0x76, 0x102, 0x77, 0x102, 0x78, 0x102,
+ 0x79, 0x102, 0x7a, 0x102, 0x41, 0x102, 0x43, 0x102,
+ 0x44, 0x102, 0x47, 0x102, 0x4a, 0x102, 0x4b, 0x102,
+ 0x4e, 0x102, 0x4f, 0x102, 0x50, 0x102, 0x51, 0x102,
+ 0x53, 0x102, 0x54, 0x102, 0x55, 0x102, 0x56, 0x102,
+ 0x57, 0x102, 0x58, 0x102, 0x59, 0x102, 0x5a, 0x102,
+ 0x61, 0x102, 0x62, 0x102, 0x63, 0x102, 0x64, 0x102,
+ 0x66, 0x102, 0x68, 0x102, 0x69, 0x102, 0x6a, 0x102,
+ 0x6b, 0x102, 0x6c, 0x102, 0x6d, 0x102, 0x6e, 0x102,
+ 0x70, 0x102, 0x71, 0x102, 0x72, 0x102, 0x73, 0x102,
+ 0x74, 0x102, 0x75, 0x102, 0x76, 0x102, 0x77, 0x102,
+ 0x78, 0x102, 0x79, 0x102, 0x7a, 0x102, 0x41, 0x102,
+ 0x42, 0x102, 0x43, 0x102, 0x44, 0x102, 0x45, 0x102,
+ 0x46, 0x102, 0x47, 0x102, 0x48, 0x102, 0x49, 0x102,
+ 0x4a, 0x102, 0x4b, 0x102, 0x4c, 0x102, 0x4d, 0x102,
+ 0x4e, 0x102, 0x4f, 0x102, 0x50, 0x102, 0x51, 0x102,
+ 0x52, 0x102, 0x53, 0x102, 0x54, 0x102, 0x55, 0x102,
+ 0x56, 0x102, 0x57, 0x102, 0x58, 0x102, 0x59, 0x102,
+ 0x5a, 0x102, 0x61, 0x102, 0x62, 0x102, 0x63, 0x102,
+ 0x64, 0x102, 0x65, 0x102, 0x66, 0x102, 0x67, 0x102,
+ 0x68, 0x102, 0x69, 0x102, 0x6a, 0x102, 0x6b, 0x102,
+ 0x6c, 0x102, 0x6d, 0x102, 0x6e, 0x102, 0x6f, 0x102,
+ 0x70, 0x102, 0x71, 0x102, 0x72, 0x102, 0x73, 0x102,
+ 0x74, 0x102, 0x75, 0x102, 0x76, 0x102, 0x77, 0x102,
+ 0x78, 0x102, 0x79, 0x102, 0x7a, 0x102, 0x41, 0x102,
+ 0x42, 0x102, 0x44, 0x102, 0x45, 0x102, 0x46, 0x102,
+ 0x47, 0x102, 0x4a, 0x102, 0x4b, 0x102, 0x4c, 0x102,
+ 0x4d, 0x102, 0x4e, 0x102, 0x4f, 0x102, 0x50, 0x102,
+ 0x51, 0x102, 0x53, 0x102, 0x54, 0x102, 0x55, 0x102,
+ 0x56, 0x102, 0x57, 0x102, 0x58, 0x102, 0x59, 0x102,
+ 0x61, 0x102, 0x62, 0x102, 0x63, 0x102, 0x64, 0x102,
+ 0x65, 0x102, 0x66, 0x102, 0x67, 0x102, 0x68, 0x102,
+ 0x69, 0x102, 0x6a, 0x102, 0x6b, 0x102, 0x6c, 0x102,
+ 0x6d, 0x102, 0x6e, 0x102, 0x6f, 0x102, 0x70, 0x102,
+ 0x71, 0x102, 0x72, 0x102, 0x73, 0x102, 0x74, 0x102,
+ 0x75, 0x102, 0x76, 0x102, 0x77, 0x102, 0x78, 0x102,
+ 0x79, 0x102, 0x7a, 0x102, 0x41, 0x102, 0x42, 0x102,
+ 0x44, 0x102, 0x45, 0x102, 0x46, 0x102, 0x47, 0x102,
+ 0x49, 0x102, 0x4a, 0x102, 0x4b, 0x102, 0x4c, 0x102,
+ 0x4d, 0x102, 0x4f, 0x102, 0x53, 0x102, 0x54, 0x102,
+ 0x55, 0x102, 0x56, 0x102, 0x57, 0x102, 0x58, 0x102,
+ 0x59, 0x102, 0x61, 0x102, 0x62, 0x102, 0x63, 0x102,
+ 0x64, 0x102, 0x65, 0x102, 0x66, 0x102, 0x67, 0x102,
+ 0x68, 0x102, 0x69, 0x102, 0x6a, 0x102, 0x6b, 0x102,
+ 0x6c, 0x102, 0x6d, 0x102, 0x6e, 0x102, 0x6f, 0x102,
+ 0x70, 0x102, 0x71, 0x102, 0x72, 0x102, 0x73, 0x102,
+ 0x74, 0x102, 0x75, 0x102, 0x76, 0x102, 0x77, 0x102,
+ 0x78, 0x102, 0x79, 0x102, 0x7a, 0x102, 0x41, 0x102,
+ 0x42, 0x102, 0x43, 0x102, 0x44, 0x102, 0x45, 0x102,
+ 0x46, 0x102, 0x47, 0x102, 0x48, 0x102, 0x49, 0x102,
+ 0x4a, 0x102, 0x4b, 0x102, 0x4c, 0x102, 0x4d, 0x102,
+ 0x4e, 0x102, 0x4f, 0x102, 0x50, 0x102, 0x51, 0x102,
+ 0x52, 0x102, 0x53, 0x102, 0x54, 0x102, 0x55, 0x102,
+ 0x56, 0x102, 0x57, 0x102, 0x58, 0x102, 0x59, 0x102,
+ 0x5a, 0x102, 0x61, 0x102, 0x62, 0x102, 0x63, 0x102,
+ 0x64, 0x102, 0x65, 0x102, 0x66, 0x102, 0x67, 0x102,
+ 0x68, 0x102, 0x69, 0x102, 0x6a, 0x102, 0x6b, 0x102,
+ 0x6c, 0x102, 0x6d, 0x102, 0x6e, 0x102, 0x6f, 0x102,
+ 0x70, 0x102, 0x71, 0x102, 0x72, 0x102, 0x73, 0x102,
+ 0x74, 0x102, 0x75, 0x102, 0x76, 0x102, 0x77, 0x102,
+ 0x78, 0x102, 0x79, 0x102, 0x7a, 0x102, 0x41, 0x102,
+ 0x42, 0x102, 0x43, 0x102, 0x44, 0x102, 0x45, 0x102,
+ 0x46, 0x102, 0x47, 0x102, 0x48, 0x102, 0x49, 0x102,
+ 0x4a, 0x102, 0x4b, 0x102, 0x4c, 0x102, 0x4d, 0x102,
+ 0x4e, 0x102, 0x4f, 0x102, 0x50, 0x102, 0x51, 0x102,
+ 0x52, 0x102, 0x53, 0x102, 0x54, 0x102, 0x55, 0x102,
+ 0x56, 0x102, 0x57, 0x102, 0x58, 0x102, 0x59, 0x102,
+ 0x5a, 0x102, 0x61, 0x102, 0x62, 0x102, 0x63, 0x102,
+ 0x64, 0x102, 0x65, 0x102, 0x66, 0x102, 0x67, 0x102,
+ 0x68, 0x102, 0x69, 0x102, 0x6a, 0x102, 0x6b, 0x102,
+ 0x6c, 0x102, 0x6d, 0x102, 0x6e, 0x102, 0x6f, 0x102,
+ 0x70, 0x102, 0x71, 0x102, 0x72, 0x102, 0x73, 0x102,
+ 0x74, 0x102, 0x75, 0x102, 0x76, 0x102, 0x77, 0x102,
+ 0x78, 0x102, 0x79, 0x102, 0x7a, 0x102, 0x41, 0x102,
+ 0x42, 0x102, 0x43, 0x102, 0x44, 0x102, 0x45, 0x102,
+ 0x46, 0x102, 0x47, 0x102, 0x48, 0x102, 0x49, 0x102,
+ 0x4a, 0x102, 0x4b, 0x102, 0x4c, 0x102, 0x4d, 0x102,
+ 0x4e, 0x102, 0x4f, 0x102, 0x50, 0x102, 0x51, 0x102,
+ 0x52, 0x102, 0x53, 0x102, 0x54, 0x102, 0x55, 0x102,
+ 0x56, 0x102, 0x57, 0x102, 0x58, 0x102, 0x59, 0x102,
+ 0x5a, 0x102, 0x61, 0x102, 0x62, 0x102, 0x63, 0x102,
+ 0x64, 0x102, 0x65, 0x102, 0x66, 0x102, 0x67, 0x102,
+ 0x68, 0x102, 0x69, 0x102, 0x6a, 0x102, 0x6b, 0x102,
+ 0x6c, 0x102, 0x6d, 0x102, 0x6e, 0x102, 0x6f, 0x102,
+ 0x70, 0x102, 0x71, 0x102, 0x72, 0x102, 0x73, 0x102,
+ 0x74, 0x102, 0x75, 0x102, 0x76, 0x102, 0x77, 0x102,
+ 0x78, 0x102, 0x79, 0x102, 0x7a, 0x102, 0x41, 0x102,
+ 0x42, 0x102, 0x43, 0x102, 0x44, 0x102, 0x45, 0x102,
+ 0x46, 0x102, 0x47, 0x102, 0x48, 0x102, 0x49, 0x102,
+ 0x4a, 0x102, 0x4b, 0x102, 0x4c, 0x102, 0x4d, 0x102,
+ 0x4e, 0x102, 0x4f, 0x102, 0x50, 0x102, 0x51, 0x102,
+ 0x52, 0x102, 0x53, 0x102, 0x54, 0x102, 0x55, 0x102,
+ 0x56, 0x102, 0x57, 0x102, 0x58, 0x102, 0x59, 0x102,
+ 0x5a, 0x102, 0x61, 0x102, 0x62, 0x102, 0x63, 0x102,
+ 0x64, 0x102, 0x65, 0x102, 0x66, 0x102, 0x67, 0x102,
+ 0x68, 0x102, 0x69, 0x102, 0x6a, 0x102, 0x6b, 0x102,
+ 0x6c, 0x102, 0x6d, 0x102, 0x6e, 0x102, 0x6f, 0x102,
+ 0x70, 0x102, 0x71, 0x102, 0x72, 0x102, 0x73, 0x102,
+ 0x74, 0x102, 0x75, 0x102, 0x76, 0x102, 0x77, 0x102,
+ 0x78, 0x102, 0x79, 0x102, 0x7a, 0x102, 0x41, 0x102,
+ 0x42, 0x102, 0x43, 0x102, 0x44, 0x102, 0x45, 0x102,
+ 0x46, 0x102, 0x47, 0x102, 0x48, 0x102, 0x49, 0x102,
+ 0x4a, 0x102, 0x4b, 0x102, 0x4c, 0x102, 0x4d, 0x102,
+ 0x4e, 0x102, 0x4f, 0x102, 0x50, 0x102, 0x51, 0x102,
+ 0x52, 0x102, 0x53, 0x102, 0x54, 0x102, 0x55, 0x102,
+ 0x56, 0x102, 0x57, 0x102, 0x58, 0x102, 0x59, 0x102,
+ 0x5a, 0x102, 0x61, 0x102, 0x62, 0x102, 0x63, 0x102,
+ 0x64, 0x102, 0x65, 0x102, 0x66, 0x102, 0x67, 0x102,
+ 0x68, 0x102, 0x69, 0x102, 0x6a, 0x102, 0x6b, 0x102,
+ 0x6c, 0x102, 0x6d, 0x102, 0x6e, 0x102, 0x6f, 0x102,
+ 0x70, 0x102, 0x71, 0x102, 0x72, 0x102, 0x73, 0x102,
+ 0x74, 0x102, 0x75, 0x102, 0x76, 0x102, 0x77, 0x102,
+ 0x78, 0x102, 0x79, 0x102, 0x7a, 0x102, 0x41, 0x102,
+ 0x42, 0x102, 0x43, 0x102, 0x44, 0x102, 0x45, 0x102,
+ 0x46, 0x102, 0x47, 0x102, 0x48, 0x102, 0x49, 0x102,
+ 0x4a, 0x102, 0x4b, 0x102, 0x4c, 0x102, 0x4d, 0x102,
+ 0x4e, 0x102, 0x4f, 0x102, 0x50, 0x102, 0x51, 0x102,
+ 0x52, 0x102, 0x53, 0x102, 0x54, 0x102, 0x55, 0x102,
+ 0x56, 0x102, 0x57, 0x102, 0x58, 0x102, 0x59, 0x102,
+ 0x5a, 0x102, 0x61, 0x102, 0x62, 0x102, 0x63, 0x102,
+ 0x64, 0x102, 0x65, 0x102, 0x66, 0x102, 0x67, 0x102,
+ 0x68, 0x102, 0x69, 0x102, 0x6a, 0x102, 0x6b, 0x102,
+ 0x6c, 0x102, 0x6d, 0x102, 0x6e, 0x102, 0x6f, 0x102,
+ 0x70, 0x102, 0x71, 0x102, 0x72, 0x102, 0x73, 0x102,
+ 0x74, 0x102, 0x75, 0x102, 0x76, 0x102, 0x77, 0x102,
+ 0x78, 0x102, 0x79, 0x102, 0x7a, 0x102, 0x131, 0x102,
+ 0x237, 0x102, 0x391, 0x102, 0x392, 0x102, 0x393, 0x102,
+ 0x394, 0x102, 0x395, 0x102, 0x396, 0x102, 0x397, 0x102,
+ 0x398, 0x102, 0x399, 0x102, 0x39a, 0x102, 0x39b, 0x102,
+ 0x39c, 0x102, 0x39d, 0x102, 0x39e, 0x102, 0x39f, 0x102,
+ 0x3a0, 0x102, 0x3a1, 0x102, 0x3f4, 0x102, 0x3a3, 0x102,
+ 0x3a4, 0x102, 0x3a5, 0x102, 0x3a6, 0x102, 0x3a7, 0x102,
+ 0x3a8, 0x102, 0x3a9, 0x102, 0x2207, 0x102, 0x3b1, 0x102,
+ 0x3b2, 0x102, 0x3b3, 0x102, 0x3b4, 0x102, 0x3b5, 0x102,
+ 0x3b6, 0x102, 0x3b7, 0x102, 0x3b8, 0x102, 0x3b9, 0x102,
+ 0x3ba, 0x102, 0x3bb, 0x102, 0x3bc, 0x102, 0x3bd, 0x102,
+ 0x3be, 0x102, 0x3bf, 0x102, 0x3c0, 0x102, 0x3c1, 0x102,
+ 0x3c2, 0x102, 0x3c3, 0x102, 0x3c4, 0x102, 0x3c5, 0x102,
+ 0x3c6, 0x102, 0x3c7, 0x102, 0x3c8, 0x102, 0x3c9, 0x102,
+ 0x2202, 0x102, 0x3f5, 0x102, 0x3d1, 0x102, 0x3f0, 0x102,
+ 0x3d5, 0x102, 0x3f1, 0x102, 0x3d6, 0x102, 0x391, 0x102,
+ 0x392, 0x102, 0x393, 0x102, 0x394, 0x102, 0x395, 0x102,
+ 0x396, 0x102, 0x397, 0x102, 0x398, 0x102, 0x399, 0x102,
+ 0x39a, 0x102, 0x39b, 0x102, 0x39c, 0x102, 0x39d, 0x102,
+ 0x39e, 0x102, 0x39f, 0x102, 0x3a0, 0x102, 0x3a1, 0x102,
+ 0x3f4, 0x102, 0x3a3, 0x102, 0x3a4, 0x102, 0x3a5, 0x102,
+ 0x3a6, 0x102, 0x3a7, 0x102, 0x3a8, 0x102, 0x3a9, 0x102,
+ 0x2207, 0x102, 0x3b1, 0x102, 0x3b2, 0x102, 0x3b3, 0x102,
+ 0x3b4, 0x102, 0x3b5, 0x102, 0x3b6, 0x102, 0x3b7, 0x102,
+ 0x3b8, 0x102, 0x3b9, 0x102, 0x3ba, 0x102, 0x3bb, 0x102,
+ 0x3bc, 0x102, 0x3bd, 0x102, 0x3be, 0x102, 0x3bf, 0x102,
+ 0x3c0, 0x102, 0x3c1, 0x102, 0x3c2, 0x102, 0x3c3, 0x102,
+ 0x3c4, 0x102, 0x3c5, 0x102, 0x3c6, 0x102, 0x3c7, 0x102,
+ 0x3c8, 0x102, 0x3c9, 0x102, 0x2202, 0x102, 0x3f5, 0x102,
+ 0x3d1, 0x102, 0x3f0, 0x102, 0x3d5, 0x102, 0x3f1, 0x102,
+ 0x3d6, 0x102, 0x391, 0x102, 0x392, 0x102, 0x393, 0x102,
+ 0x394, 0x102, 0x395, 0x102, 0x396, 0x102, 0x397, 0x102,
+ 0x398, 0x102, 0x399, 0x102, 0x39a, 0x102, 0x39b, 0x102,
+ 0x39c, 0x102, 0x39d, 0x102, 0x39e, 0x102, 0x39f, 0x102,
+ 0x3a0, 0x102, 0x3a1, 0x102, 0x3f4, 0x102, 0x3a3, 0x102,
+ 0x3a4, 0x102, 0x3a5, 0x102, 0x3a6, 0x102, 0x3a7, 0x102,
+ 0x3a8, 0x102, 0x3a9, 0x102, 0x2207, 0x102, 0x3b1, 0x102,
+ 0x3b2, 0x102, 0x3b3, 0x102, 0x3b4, 0x102, 0x3b5, 0x102,
+ 0x3b6, 0x102, 0x3b7, 0x102, 0x3b8, 0x102, 0x3b9, 0x102,
+ 0x3ba, 0x102, 0x3bb, 0x102, 0x3bc, 0x102, 0x3bd, 0x102,
+ 0x3be, 0x102, 0x3bf, 0x102, 0x3c0, 0x102, 0x3c1, 0x102,
+ 0x3c2, 0x102, 0x3c3, 0x102, 0x3c4, 0x102, 0x3c5, 0x102,
+ 0x3c6, 0x102, 0x3c7, 0x102, 0x3c8, 0x102, 0x3c9, 0x102,
+ 0x2202, 0x102, 0x3f5, 0x102, 0x3d1, 0x102, 0x3f0, 0x102,
+ 0x3d5, 0x102, 0x3f1, 0x102, 0x3d6, 0x102, 0x391, 0x102,
+ 0x392, 0x102, 0x393, 0x102, 0x394, 0x102, 0x395, 0x102,
+ 0x396, 0x102, 0x397, 0x102, 0x398, 0x102, 0x399, 0x102,
+ 0x39a, 0x102, 0x39b, 0x102, 0x39c, 0x102, 0x39d, 0x102,
+ 0x39e, 0x102, 0x39f, 0x102, 0x3a0, 0x102, 0x3a1, 0x102,
+ 0x3f4, 0x102, 0x3a3, 0x102, 0x3a4, 0x102, 0x3a5, 0x102,
+ 0x3a6, 0x102, 0x3a7, 0x102, 0x3a8, 0x102, 0x3a9, 0x102,
+ 0x2207, 0x102, 0x3b1, 0x102, 0x3b2, 0x102, 0x3b3, 0x102,
+ 0x3b4, 0x102, 0x3b5, 0x102, 0x3b6, 0x102, 0x3b7, 0x102,
+ 0x3b8, 0x102, 0x3b9, 0x102, 0x3ba, 0x102, 0x3bb, 0x102,
+ 0x3bc, 0x102, 0x3bd, 0x102, 0x3be, 0x102, 0x3bf, 0x102,
+ 0x3c0, 0x102, 0x3c1, 0x102, 0x3c2, 0x102, 0x3c3, 0x102,
+ 0x3c4, 0x102, 0x3c5, 0x102, 0x3c6, 0x102, 0x3c7, 0x102,
+ 0x3c8, 0x102, 0x3c9, 0x102, 0x2202, 0x102, 0x3f5, 0x102,
+ 0x3d1, 0x102, 0x3f0, 0x102, 0x3d5, 0x102, 0x3f1, 0x102,
+ 0x3d6, 0x102, 0x391, 0x102, 0x392, 0x102, 0x393, 0x102,
+ 0x394, 0x102, 0x395, 0x102, 0x396, 0x102, 0x397, 0x102,
+ 0x398, 0x102, 0x399, 0x102, 0x39a, 0x102, 0x39b, 0x102,
+ 0x39c, 0x102, 0x39d, 0x102, 0x39e, 0x102, 0x39f, 0x102,
+ 0x3a0, 0x102, 0x3a1, 0x102, 0x3f4, 0x102, 0x3a3, 0x102,
+ 0x3a4, 0x102, 0x3a5, 0x102, 0x3a6, 0x102, 0x3a7, 0x102,
+ 0x3a8, 0x102, 0x3a9, 0x102, 0x2207, 0x102, 0x3b1, 0x102,
+ 0x3b2, 0x102, 0x3b3, 0x102, 0x3b4, 0x102, 0x3b5, 0x102,
+ 0x3b6, 0x102, 0x3b7, 0x102, 0x3b8, 0x102, 0x3b9, 0x102,
+ 0x3ba, 0x102, 0x3bb, 0x102, 0x3bc, 0x102, 0x3bd, 0x102,
+ 0x3be, 0x102, 0x3bf, 0x102, 0x3c0, 0x102, 0x3c1, 0x102,
+ 0x3c2, 0x102, 0x3c3, 0x102, 0x3c4, 0x102, 0x3c5, 0x102,
+ 0x3c6, 0x102, 0x3c7, 0x102, 0x3c8, 0x102, 0x3c9, 0x102,
+ 0x2202, 0x102, 0x3f5, 0x102, 0x3d1, 0x102, 0x3f0, 0x102,
+ 0x3d5, 0x102, 0x3f1, 0x102, 0x3d6, 0x102, 0x3dc, 0x102,
+ 0x3dd, 0x102, 0x30, 0x102, 0x31, 0x102, 0x32, 0x102,
+ 0x33, 0x102, 0x34, 0x102, 0x35, 0x102, 0x36, 0x102,
+ 0x37, 0x102, 0x38, 0x102, 0x39, 0x102, 0x30, 0x102,
+ 0x31, 0x102, 0x32, 0x102, 0x33, 0x102, 0x34, 0x102,
+ 0x35, 0x102, 0x36, 0x102, 0x37, 0x102, 0x38, 0x102,
+ 0x39, 0x102, 0x30, 0x102, 0x31, 0x102, 0x32, 0x102,
+ 0x33, 0x102, 0x34, 0x102, 0x35, 0x102, 0x36, 0x102,
+ 0x37, 0x102, 0x38, 0x102, 0x39, 0x102, 0x30, 0x102,
+ 0x31, 0x102, 0x32, 0x102, 0x33, 0x102, 0x34, 0x102,
+ 0x35, 0x102, 0x36, 0x102, 0x37, 0x102, 0x38, 0x102,
+ 0x39, 0x102, 0x30, 0x102, 0x31, 0x102, 0x32, 0x102,
+ 0x33, 0x102, 0x34, 0x102, 0x35, 0x102, 0x36, 0x102,
+ 0x37, 0x102, 0x38, 0x102, 0x39, 0x101, 0x4e3d, 0x101,
+ 0x4e38, 0x101, 0x4e41, 0x201, 0xd840, 0xdd22, 0x101, 0x4f60,
+ 0x101, 0x4fae, 0x101, 0x4fbb, 0x101, 0x5002, 0x101, 0x507a,
+ 0x101, 0x5099, 0x101, 0x50e7, 0x101, 0x50cf, 0x101, 0x349e,
+ 0x201, 0xd841, 0xde3a, 0x101, 0x514d, 0x101, 0x5154, 0x101,
+ 0x5164, 0x101, 0x5177, 0x201, 0xd841, 0xdd1c, 0x101, 0x34b9,
+ 0x101, 0x5167, 0x101, 0x518d, 0x201, 0xd841, 0xdd4b, 0x101,
+ 0x5197, 0x101, 0x51a4, 0x101, 0x4ecc, 0x101, 0x51ac, 0x101,
+ 0x51b5, 0x201, 0xd864, 0xdddf, 0x101, 0x51f5, 0x101, 0x5203,
+ 0x101, 0x34df, 0x101, 0x523b, 0x101, 0x5246, 0x101, 0x5272,
+ 0x101, 0x5277, 0x101, 0x3515, 0x101, 0x52c7, 0x101, 0x52c9,
+ 0x101, 0x52e4, 0x101, 0x52fa, 0x101, 0x5305, 0x101, 0x5306,
+ 0x101, 0x5317, 0x101, 0x5349, 0x101, 0x5351, 0x101, 0x535a,
+ 0x101, 0x5373, 0x101, 0x537d, 0x101, 0x537f, 0x101, 0x537f,
+ 0x101, 0x537f, 0x201, 0xd842, 0xde2c, 0x101, 0x7070, 0x101,
+ 0x53ca, 0x101, 0x53df, 0x201, 0xd842, 0xdf63, 0x101, 0x53eb,
+ 0x101, 0x53f1, 0x101, 0x5406, 0x101, 0x549e, 0x101, 0x5438,
+ 0x101, 0x5448, 0x101, 0x5468, 0x101, 0x54a2, 0x101, 0x54f6,
+ 0x101, 0x5510, 0x101, 0x5553, 0x101, 0x5563, 0x101, 0x5584,
+ 0x101, 0x5584, 0x101, 0x5599, 0x101, 0x55ab, 0x101, 0x55b3,
+ 0x101, 0x55c2, 0x101, 0x5716, 0x101, 0x5606, 0x101, 0x5717,
+ 0x101, 0x5651, 0x101, 0x5674, 0x101, 0x5207, 0x101, 0x58ee,
+ 0x101, 0x57ce, 0x101, 0x57f4, 0x101, 0x580d, 0x101, 0x578b,
+ 0x101, 0x5832, 0x101, 0x5831, 0x101, 0x58ac, 0x201, 0xd845,
+ 0xdce4, 0x101, 0x58f2, 0x101, 0x58f7, 0x101, 0x5906, 0x101,
+ 0x591a, 0x101, 0x5922, 0x101, 0x5962, 0x201, 0xd845, 0xdea8,
+ 0x201, 0xd845, 0xdeea, 0x101, 0x59ec, 0x101, 0x5a1b, 0x101,
+ 0x5a27, 0x101, 0x59d8, 0x101, 0x5a66, 0x101, 0x36ee, 0x101,
+ 0x36fc, 0x101, 0x5b08, 0x101, 0x5b3e, 0x101, 0x5b3e, 0x201,
+ 0xd846, 0xddc8, 0x101, 0x5bc3, 0x101, 0x5bd8, 0x101, 0x5be7,
+ 0x101, 0x5bf3, 0x201, 0xd846, 0xdf18, 0x101, 0x5bff, 0x101,
+ 0x5c06, 0x101, 0x5f53, 0x101, 0x5c22, 0x101, 0x3781, 0x101,
+ 0x5c60, 0x101, 0x5c6e, 0x101, 0x5cc0, 0x101, 0x5c8d, 0x201,
+ 0xd847, 0xdde4, 0x101, 0x5d43, 0x201, 0xd847, 0xdde6, 0x101,
+ 0x5d6e, 0x101, 0x5d6b, 0x101, 0x5d7c, 0x101, 0x5de1, 0x101,
+ 0x5de2, 0x101, 0x382f, 0x101, 0x5dfd, 0x101, 0x5e28, 0x101,
+ 0x5e3d, 0x101, 0x5e69, 0x101, 0x3862, 0x201, 0xd848, 0xdd83,
+ 0x101, 0x387c, 0x101, 0x5eb0, 0x101, 0x5eb3, 0x101, 0x5eb6,
+ 0x101, 0x5eca, 0x201, 0xd868, 0xdf92, 0x101, 0x5efe, 0x201,
+ 0xd848, 0xdf31, 0x201, 0xd848, 0xdf31, 0x101, 0x8201, 0x101,
+ 0x5f22, 0x101, 0x5f22, 0x101, 0x38c7, 0x201, 0xd84c, 0xdeb8,
+ 0x201, 0xd858, 0xddda, 0x101, 0x5f62, 0x101, 0x5f6b, 0x101,
+ 0x38e3, 0x101, 0x5f9a, 0x101, 0x5fcd, 0x101, 0x5fd7, 0x101,
+ 0x5ff9, 0x101, 0x6081, 0x101, 0x393a, 0x101, 0x391c, 0x101,
+ 0x6094, 0x201, 0xd849, 0xded4, 0x101, 0x60c7, 0x101, 0x6148,
+ 0x101, 0x614c, 0x101, 0x614e, 0x101, 0x614c, 0x101, 0x617a,
+ 0x101, 0x618e, 0x101, 0x61b2, 0x101, 0x61a4, 0x101, 0x61af,
+ 0x101, 0x61de, 0x101, 0x61f2, 0x101, 0x61f6, 0x101, 0x6210,
+ 0x101, 0x621b, 0x101, 0x625d, 0x101, 0x62b1, 0x101, 0x62d4,
+ 0x101, 0x6350, 0x201, 0xd84a, 0xdf0c, 0x101, 0x633d, 0x101,
+ 0x62fc, 0x101, 0x6368, 0x101, 0x6383, 0x101, 0x63e4, 0x201,
+ 0xd84a, 0xdff1, 0x101, 0x6422, 0x101, 0x63c5, 0x101, 0x63a9,
+ 0x101, 0x3a2e, 0x101, 0x6469, 0x101, 0x647e, 0x101, 0x649d,
+ 0x101, 0x6477, 0x101, 0x3a6c, 0x101, 0x654f, 0x101, 0x656c,
+ 0x201, 0xd84c, 0xdc0a, 0x101, 0x65e3, 0x101, 0x66f8, 0x101,
+ 0x6649, 0x101, 0x3b19, 0x101, 0x6691, 0x101, 0x3b08, 0x101,
+ 0x3ae4, 0x101, 0x5192, 0x101, 0x5195, 0x101, 0x6700, 0x101,
+ 0x669c, 0x101, 0x80ad, 0x101, 0x43d9, 0x101, 0x6717, 0x101,
+ 0x671b, 0x101, 0x6721, 0x101, 0x675e, 0x101, 0x6753, 0x201,
+ 0xd84c, 0xdfc3, 0x101, 0x3b49, 0x101, 0x67fa, 0x101, 0x6785,
+ 0x101, 0x6852, 0x101, 0x6885, 0x201, 0xd84d, 0xdc6d, 0x101,
+ 0x688e, 0x101, 0x681f, 0x101, 0x6914, 0x101, 0x3b9d, 0x101,
+ 0x6942, 0x101, 0x69a3, 0x101, 0x69ea, 0x101, 0x6aa8, 0x201,
+ 0xd84d, 0xdea3, 0x101, 0x6adb, 0x101, 0x3c18, 0x101, 0x6b21,
+ 0x201, 0xd84e, 0xdca7, 0x101, 0x6b54, 0x101, 0x3c4e, 0x101,
+ 0x6b72, 0x101, 0x6b9f, 0x101, 0x6bba, 0x101, 0x6bbb, 0x201,
+ 0xd84e, 0xde8d, 0x201, 0xd847, 0xdd0b, 0x201, 0xd84e, 0xdefa,
+ 0x101, 0x6c4e, 0x201, 0xd84f, 0xdcbc, 0x101, 0x6cbf, 0x101,
+ 0x6ccd, 0x101, 0x6c67, 0x101, 0x6d16, 0x101, 0x6d3e, 0x101,
+ 0x6d77, 0x101, 0x6d41, 0x101, 0x6d69, 0x101, 0x6d78, 0x101,
+ 0x6d85, 0x201, 0xd84f, 0xdd1e, 0x101, 0x6d34, 0x101, 0x6e2f,
+ 0x101, 0x6e6e, 0x101, 0x3d33, 0x101, 0x6ecb, 0x101, 0x6ec7,
+ 0x201, 0xd84f, 0xded1, 0x101, 0x6df9, 0x101, 0x6f6e, 0x201,
+ 0xd84f, 0xdf5e, 0x201, 0xd84f, 0xdf8e, 0x101, 0x6fc6, 0x101,
+ 0x7039, 0x101, 0x701e, 0x101, 0x701b, 0x101, 0x3d96, 0x101,
+ 0x704a, 0x101, 0x707d, 0x101, 0x7077, 0x101, 0x70ad, 0x201,
+ 0xd841, 0xdd25, 0x101, 0x7145, 0x201, 0xd850, 0xde63, 0x101,
+ 0x719c, 0x201, 0xd850, 0xdfab, 0x101, 0x7228, 0x101, 0x7235,
+ 0x101, 0x7250, 0x201, 0xd851, 0xde08, 0x101, 0x7280, 0x101,
+ 0x7295, 0x201, 0xd851, 0xdf35, 0x201, 0xd852, 0xdc14, 0x101,
+ 0x737a, 0x101, 0x738b, 0x101, 0x3eac, 0x101, 0x73a5, 0x101,
+ 0x3eb8, 0x101, 0x3eb8, 0x101, 0x7447, 0x101, 0x745c, 0x101,
+ 0x7471, 0x101, 0x7485, 0x101, 0x74ca, 0x101, 0x3f1b, 0x101,
+ 0x7524, 0x201, 0xd853, 0xdc36, 0x101, 0x753e, 0x201, 0xd853,
+ 0xdc92, 0x101, 0x7570, 0x201, 0xd848, 0xdd9f, 0x101, 0x7610,
+ 0x201, 0xd853, 0xdfa1, 0x201, 0xd853, 0xdfb8, 0x201, 0xd854,
+ 0xdc44, 0x101, 0x3ffc, 0x101, 0x4008, 0x101, 0x76f4, 0x201,
+ 0xd854, 0xdcf3, 0x201, 0xd854, 0xdcf2, 0x201, 0xd854, 0xdd19,
+ 0x201, 0xd854, 0xdd33, 0x101, 0x771e, 0x101, 0x771f, 0x101,
+ 0x771f, 0x101, 0x774a, 0x101, 0x4039, 0x101, 0x778b, 0x101,
+ 0x4046, 0x101, 0x4096, 0x201, 0xd855, 0xdc1d, 0x101, 0x784e,
+ 0x101, 0x788c, 0x101, 0x78cc, 0x101, 0x40e3, 0x201, 0xd855,
+ 0xde26, 0x101, 0x7956, 0x201, 0xd855, 0xde9a, 0x201, 0xd855,
+ 0xdec5, 0x101, 0x798f, 0x101, 0x79eb, 0x101, 0x412f, 0x101,
+ 0x7a40, 0x101, 0x7a4a, 0x101, 0x7a4f, 0x201, 0xd856, 0xdd7c,
+ 0x201, 0xd856, 0xdea7, 0x201, 0xd856, 0xdea7, 0x101, 0x7aee,
+ 0x101, 0x4202, 0x201, 0xd856, 0xdfab, 0x101, 0x7bc6, 0x101,
+ 0x7bc9, 0x101, 0x4227, 0x201, 0xd857, 0xdc80, 0x101, 0x7cd2,
+ 0x101, 0x42a0, 0x101, 0x7ce8, 0x101, 0x7ce3, 0x101, 0x7d00,
+ 0x201, 0xd857, 0xdf86, 0x101, 0x7d63, 0x101, 0x4301, 0x101,
+ 0x7dc7, 0x101, 0x7e02, 0x101, 0x7e45, 0x101, 0x4334, 0x201,
+ 0xd858, 0xde28, 0x201, 0xd858, 0xde47, 0x101, 0x4359, 0x201,
+ 0xd858, 0xded9, 0x101, 0x7f7a, 0x201, 0xd858, 0xdf3e, 0x101,
+ 0x7f95, 0x101, 0x7ffa, 0x101, 0x8005, 0x201, 0xd859, 0xdcda,
+ 0x201, 0xd859, 0xdd23, 0x101, 0x8060, 0x201, 0xd859, 0xdda8,
+ 0x101, 0x8070, 0x201, 0xd84c, 0xdf5f, 0x101, 0x43d5, 0x101,
+ 0x80b2, 0x101, 0x8103, 0x101, 0x440b, 0x101, 0x813e, 0x101,
+ 0x5ab5, 0x201, 0xd859, 0xdfa7, 0x201, 0xd859, 0xdfb5, 0x201,
+ 0xd84c, 0xdf93, 0x201, 0xd84c, 0xdf9c, 0x101, 0x8201, 0x101,
+ 0x8204, 0x101, 0x8f9e, 0x101, 0x446b, 0x101, 0x8291, 0x101,
+ 0x828b, 0x101, 0x829d, 0x101, 0x52b3, 0x101, 0x82b1, 0x101,
+ 0x82b3, 0x101, 0x82bd, 0x101, 0x82e6, 0x201, 0xd85a, 0xdf3c,
+ 0x101, 0x82e5, 0x101, 0x831d, 0x101, 0x8363, 0x101, 0x83ad,
+ 0x101, 0x8323, 0x101, 0x83bd, 0x101, 0x83e7, 0x101, 0x8457,
+ 0x101, 0x8353, 0x101, 0x83ca, 0x101, 0x83cc, 0x101, 0x83dc,
+ 0x201, 0xd85b, 0xdc36, 0x201, 0xd85b, 0xdd6b, 0x201, 0xd85b,
+ 0xdcd5, 0x101, 0x452b, 0x101, 0x84f1, 0x101, 0x84f3, 0x101,
+ 0x8516, 0x201, 0xd85c, 0xdfca, 0x101, 0x8564, 0x201, 0xd85b,
+ 0xdf2c, 0x101, 0x455d, 0x101, 0x4561, 0x201, 0xd85b, 0xdfb1,
+ 0x201, 0xd85c, 0xdcd2, 0x101, 0x456b, 0x101, 0x8650, 0x101,
+ 0x865c, 0x101, 0x8667, 0x101, 0x8669, 0x101, 0x86a9, 0x101,
+ 0x8688, 0x101, 0x870e, 0x101, 0x86e2, 0x101, 0x8779, 0x101,
+ 0x8728, 0x101, 0x876b, 0x101, 0x8786, 0x101, 0x45d7, 0x101,
+ 0x87e1, 0x101, 0x8801, 0x101, 0x45f9, 0x101, 0x8860, 0x101,
+ 0x8863, 0x201, 0xd85d, 0xde67, 0x101, 0x88d7, 0x101, 0x88de,
+ 0x101, 0x4635, 0x101, 0x88fa, 0x101, 0x34bb, 0x201, 0xd85e,
+ 0xdcae, 0x201, 0xd85e, 0xdd66, 0x101, 0x46be, 0x101, 0x46c7,
+ 0x101, 0x8aa0, 0x101, 0x8aed, 0x101, 0x8b8a, 0x101, 0x8c55,
+ 0x201, 0xd85f, 0xdca8, 0x101, 0x8cab, 0x101, 0x8cc1, 0x101,
+ 0x8d1b, 0x101, 0x8d77, 0x201, 0xd85f, 0xdf2f, 0x201, 0xd842,
+ 0xdc04, 0x101, 0x8dcb, 0x101, 0x8dbc, 0x101, 0x8df0, 0x201,
+ 0xd842, 0xdcde, 0x101, 0x8ed4, 0x101, 0x8f38, 0x201, 0xd861,
+ 0xddd2, 0x201, 0xd861, 0xdded, 0x101, 0x9094, 0x101, 0x90f1,
+ 0x101, 0x9111, 0x201, 0xd861, 0xdf2e, 0x101, 0x911b, 0x101,
+ 0x9238, 0x101, 0x92d7, 0x101, 0x92d8, 0x101, 0x927c, 0x101,
+ 0x93f9, 0x101, 0x9415, 0x201, 0xd862, 0xdffa, 0x101, 0x958b,
+ 0x101, 0x4995, 0x101, 0x95b7, 0x201, 0xd863, 0xdd77, 0x101,
+ 0x49e6, 0x101, 0x96c3, 0x101, 0x5db2, 0x101, 0x9723, 0x201,
+ 0xd864, 0xdd45, 0x201, 0xd864, 0xde1a, 0x101, 0x4a6e, 0x101,
+ 0x4a76, 0x101, 0x97e0, 0x201, 0xd865, 0xdc0a, 0x101, 0x4ab2,
+ 0x201, 0xd865, 0xdc96, 0x101, 0x980b, 0x101, 0x980b, 0x101,
+ 0x9829, 0x201, 0xd865, 0xddb6, 0x101, 0x98e2, 0x101, 0x4b33,
+ 0x101, 0x9929, 0x101, 0x99a7, 0x101, 0x99c2, 0x101, 0x99fe,
+ 0x101, 0x4bce, 0x201, 0xd866, 0xdf30, 0x101, 0x9b12, 0x101,
+ 0x9c40, 0x101, 0x9cfd, 0x101, 0x4cce, 0x101, 0x4ced, 0x101,
+ 0x9d67, 0x201, 0xd868, 0xdcce, 0x101, 0x4cf8, 0x201, 0xd868,
+ 0xdd05, 0x201, 0xd868, 0xde0e, 0x201, 0xd868, 0xde91, 0x101,
+ 0x9ebb, 0x101, 0x4d56, 0x101, 0x9ef9, 0x101, 0x9efe, 0x101,
+ 0x9f05, 0x101, 0x9f0f, 0x101, 0x9f16, 0x101, 0x9f3b, 0x201,
+ 0xd869, 0xde00,
+};
+
+static const unsigned short uc_ligature_trie[] = {
+ // 0 - 0x3100
+
+ 392, 392, 392, 392, 392, 392, 392, 392,
+ 392, 392, 392, 392, 392, 392, 392, 392,
+ 392, 392, 392, 392, 392, 392, 392, 392,
+ 424, 456, 488, 392, 392, 392, 392, 392,
+ 392, 392, 392, 392, 392, 392, 392, 392,
+ 392, 392, 392, 392, 392, 392, 392, 392,
+ 392, 392, 520, 392, 392, 392, 392, 392,
+ 392, 392, 392, 392, 392, 392, 392, 392,
+ 392, 392, 392, 392, 392, 392, 392, 392,
+ 392, 552, 392, 392, 392, 584, 616, 392,
+ 392, 392, 392, 392, 392, 392, 392, 392,
+ 392, 648, 680, 392, 392, 712, 744, 392,
+ 392, 392, 776, 392, 392, 392, 808, 392,
+ 392, 840, 872, 392, 392, 392, 904, 392,
+ 392, 392, 392, 392, 392, 392, 392, 392,
+ 392, 392, 392, 392, 392, 392, 392, 392,
+
+ 392, 936, 392, 392, 392, 392, 392, 392,
+ 392, 392, 392, 392, 392, 392, 392, 392,
+ 392, 392, 392, 392, 392, 392, 392, 392,
+ 392, 392, 392, 392, 392, 392, 392, 392,
+ 392, 392, 392, 392, 392, 392, 392, 392,
+ 392, 392, 392, 392, 392, 392, 392, 392,
+ 392, 392, 392, 392, 392, 392, 392, 392,
+ 392, 392, 392, 392, 392, 392, 392, 392,
+ 392, 392, 392, 392, 392, 392, 392, 392,
+ 392, 392, 392, 392, 392, 392, 392, 392,
+ 392, 392, 392, 392, 392, 392, 392, 392,
+ 392, 968, 392, 392, 392, 392, 392, 392,
+ 392, 392, 392, 392, 392, 392, 392, 392,
+ 392, 392, 392, 392, 392, 392, 392, 392,
+ 392, 392, 392, 392, 392, 392, 392, 392,
+ 392, 392, 392, 392, 392, 392, 392, 392,
+
+ 392, 392, 392, 392, 392, 392, 392, 392,
+ 392, 392, 392, 392, 392, 392, 392, 392,
+ 392, 392, 392, 392, 392, 392, 392, 392,
+ 392, 392, 392, 392, 392, 392, 392, 392,
+ 392, 392, 392, 392, 392, 392, 392, 392,
+ 392, 392, 392, 392, 392, 392, 392, 392,
+ 392, 392, 392, 392, 392, 392, 392, 392,
+ 392, 392, 392, 392, 392, 392, 392, 392,
+ 392, 392, 392, 392, 392, 392, 392, 392,
+ 392, 392, 392, 392, 392, 392, 392, 392,
+ 392, 392, 392, 392, 392, 392, 392, 392,
+ 392, 392, 392, 392, 392, 392, 392, 392,
+ 392, 392, 392, 392, 392, 392, 392, 392,
+ 392, 392, 392, 392, 392, 392, 392, 392,
+ 392, 392, 392, 392, 392, 392, 392, 392,
+ 392, 392, 392, 392, 392, 392, 392, 392,
+
+ 392, 392, 392, 392, 1000, 392, 392, 392,
+
+
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+
+ 0x0, 0xa9, 0x194, 0x1d5, 0x20e, 0xffff, 0x267, 0x2a8,
+ 0x305, 0x372, 0x3a3, 0x3b0, 0x3bd, 0xffff, 0xffff, 0x408,
+ 0xffff, 0x425, 0xffff, 0x43e, 0x45b, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0x47c, 0xffff, 0xffff, 0xffff, 0xffff,
+
+ 0xffff, 0xffff, 0xffff, 0x485, 0x4da, 0x4df, 0x4e4, 0x4ed,
+ 0x51a, 0xffff, 0xffff, 0xffff, 0xffff, 0x52f, 0x548, 0xffff,
+ 0x54d, 0x55a, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0x57d, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+
+ 0xffff, 0xffff, 0x5d6, 0xffff, 0xffff, 0x611, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0x690, 0x693, 0x6a0, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0x6a3, 0xffff, 0xffff, 0xffff,
+
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x6aa, 0xffff,
+
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x6ad,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x6b0, 0xffff,
+
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x6b3, 0x6b6,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x6b9, 0xffff,
+
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x6be,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x6c3, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+
+ 0xffff, 0xffff, 0x6c6, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x6c9, 0x6d0, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x6d3, 0xffff,
+
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x6d8,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0x6db, 0xffff, 0xffff, 0xffff, 0xffff, 0x6e0,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x6e3,
+
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x6e6, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x6e9, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0x700, 0x761, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+};
+
+#define GET_LIGATURE_INDEX(u2) (u2 < 0x3100 ? uc_ligature_trie[uc_ligature_trie[u2>>5] + (u2 & 0x1f)] : 0xffff);
+
+static const unsigned short uc_ligature_map [] = {
+
+ 0x54, 0x41, 0xc0, 0x45, 0xc8, 0x49, 0xcc, 0x4e,
+ 0x1f8, 0x4f, 0xd2, 0x55, 0xd9, 0x57, 0x1e80, 0x59,
+ 0x1ef2, 0x61, 0xe0, 0x65, 0xe8, 0x69, 0xec, 0x6e,
+ 0x1f9, 0x6f, 0xf2, 0x75, 0xf9, 0x77, 0x1e81, 0x79,
+ 0x1ef3, 0xa8, 0x1fed, 0xc2, 0x1ea6, 0xca, 0x1ec0, 0xd4,
+ 0x1ed2, 0xdc, 0x1db, 0xe2, 0x1ea7, 0xea, 0x1ec1, 0xf4,
+ 0x1ed3, 0xfc, 0x1dc, 0x102, 0x1eb0, 0x103, 0x1eb1, 0x112,
+ 0x1e14, 0x113, 0x1e15, 0x14c, 0x1e50, 0x14d, 0x1e51, 0x1a0,
+ 0x1edc, 0x1a1, 0x1edd, 0x1af, 0x1eea, 0x1b0, 0x1eeb, 0x391,
+ 0x1fba, 0x395, 0x1fc8, 0x397, 0x1fca, 0x399, 0x1fda, 0x39f,
+ 0x1ff8, 0x3a5, 0x1fea, 0x3a9, 0x1ffa, 0x3b1, 0x1f70, 0x3b5,
+ 0x1f72, 0x3b7, 0x1f74, 0x3b9, 0x1f76, 0x3bf, 0x1f78, 0x3c5,
+ 0x1f7a, 0x3c9, 0x1f7c, 0x3ca, 0x1fd2, 0x3cb, 0x1fe2, 0x415,
+ 0x400, 0x418, 0x40d, 0x435, 0x450, 0x438, 0x45d, 0x1f00,
+ 0x1f02, 0x1f01, 0x1f03, 0x1f08, 0x1f0a, 0x1f09, 0x1f0b, 0x1f10,
+ 0x1f12, 0x1f11, 0x1f13, 0x1f18, 0x1f1a, 0x1f19, 0x1f1b, 0x1f20,
+ 0x1f22, 0x1f21, 0x1f23, 0x1f28, 0x1f2a, 0x1f29, 0x1f2b, 0x1f30,
+ 0x1f32, 0x1f31, 0x1f33, 0x1f38, 0x1f3a, 0x1f39, 0x1f3b, 0x1f40,
+ 0x1f42, 0x1f41, 0x1f43, 0x1f48, 0x1f4a, 0x1f49, 0x1f4b, 0x1f50,
+ 0x1f52, 0x1f51, 0x1f53, 0x1f59, 0x1f5b, 0x1f60, 0x1f62, 0x1f61,
+ 0x1f63, 0x1f68, 0x1f6a, 0x1f69, 0x1f6b, 0x1fbf, 0x1fcd, 0x1ffe,
+ 0x1fdd, 0x75, 0x41, 0xc1, 0x43, 0x106, 0x45, 0xc9,
+ 0x47, 0x1f4, 0x49, 0xcd, 0x4b, 0x1e30, 0x4c, 0x139,
+ 0x4d, 0x1e3e, 0x4e, 0x143, 0x4f, 0xd3, 0x50, 0x1e54,
+ 0x52, 0x154, 0x53, 0x15a, 0x55, 0xda, 0x57, 0x1e82,
+ 0x59, 0xdd, 0x5a, 0x179, 0x61, 0xe1, 0x63, 0x107,
+ 0x65, 0xe9, 0x67, 0x1f5, 0x69, 0xed, 0x6b, 0x1e31,
+ 0x6c, 0x13a, 0x6d, 0x1e3f, 0x6e, 0x144, 0x6f, 0xf3,
+ 0x70, 0x1e55, 0x72, 0x155, 0x73, 0x15b, 0x75, 0xfa,
+ 0x77, 0x1e83, 0x79, 0xfd, 0x7a, 0x17a, 0xa8, 0x385,
+ 0xc2, 0x1ea4, 0xc5, 0x1fa, 0xc6, 0x1fc, 0xc7, 0x1e08,
+ 0xca, 0x1ebe, 0xcf, 0x1e2e, 0xd4, 0x1ed0, 0xd5, 0x1e4c,
+ 0xd8, 0x1fe, 0xdc, 0x1d7, 0xe2, 0x1ea5, 0xe5, 0x1fb,
+ 0xe6, 0x1fd, 0xe7, 0x1e09, 0xea, 0x1ebf, 0xef, 0x1e2f,
+ 0xf4, 0x1ed1, 0xf5, 0x1e4d, 0xf8, 0x1ff, 0xfc, 0x1d8,
+ 0x102, 0x1eae, 0x103, 0x1eaf, 0x112, 0x1e16, 0x113, 0x1e17,
+ 0x14c, 0x1e52, 0x14d, 0x1e53, 0x168, 0x1e78, 0x169, 0x1e79,
+ 0x1a0, 0x1eda, 0x1a1, 0x1edb, 0x1af, 0x1ee8, 0x1b0, 0x1ee9,
+ 0x391, 0x386, 0x395, 0x388, 0x397, 0x389, 0x399, 0x38a,
+ 0x39f, 0x38c, 0x3a5, 0x38e, 0x3a9, 0x38f, 0x3b1, 0x3ac,
+ 0x3b5, 0x3ad, 0x3b7, 0x3ae, 0x3b9, 0x3af, 0x3bf, 0x3cc,
+ 0x3c5, 0x3cd, 0x3c9, 0x3ce, 0x3ca, 0x390, 0x3cb, 0x3b0,
+ 0x3d2, 0x3d3, 0x413, 0x403, 0x41a, 0x40c, 0x433, 0x453,
+ 0x43a, 0x45c, 0x1f00, 0x1f04, 0x1f01, 0x1f05, 0x1f08, 0x1f0c,
+ 0x1f09, 0x1f0d, 0x1f10, 0x1f14, 0x1f11, 0x1f15, 0x1f18, 0x1f1c,
+ 0x1f19, 0x1f1d, 0x1f20, 0x1f24, 0x1f21, 0x1f25, 0x1f28, 0x1f2c,
+ 0x1f29, 0x1f2d, 0x1f30, 0x1f34, 0x1f31, 0x1f35, 0x1f38, 0x1f3c,
+ 0x1f39, 0x1f3d, 0x1f40, 0x1f44, 0x1f41, 0x1f45, 0x1f48, 0x1f4c,
+ 0x1f49, 0x1f4d, 0x1f50, 0x1f54, 0x1f51, 0x1f55, 0x1f59, 0x1f5d,
+ 0x1f60, 0x1f64, 0x1f61, 0x1f65, 0x1f68, 0x1f6c, 0x1f69, 0x1f6d,
+ 0x1fbf, 0x1fce, 0x1ffe, 0x1fde, 0x20, 0x41, 0xc2, 0x43,
+ 0x108, 0x45, 0xca, 0x47, 0x11c, 0x48, 0x124, 0x49,
+ 0xce, 0x4a, 0x134, 0x4f, 0xd4, 0x53, 0x15c, 0x55,
+ 0xdb, 0x57, 0x174, 0x59, 0x176, 0x5a, 0x1e90, 0x61,
+ 0xe2, 0x63, 0x109, 0x65, 0xea, 0x67, 0x11d, 0x68,
+ 0x125, 0x69, 0xee, 0x6a, 0x135, 0x6f, 0xf4, 0x73,
+ 0x15d, 0x75, 0xfb, 0x77, 0x175, 0x79, 0x177, 0x7a,
+ 0x1e91, 0x1ea0, 0x1eac, 0x1ea1, 0x1ead, 0x1eb8, 0x1ec6, 0x1eb9,
+ 0x1ec7, 0x1ecc, 0x1ed8, 0x1ecd, 0x1ed9, 0x1c, 0x41, 0xc3,
+ 0x45, 0x1ebc, 0x49, 0x128, 0x4e, 0xd1, 0x4f, 0xd5,
+ 0x55, 0x168, 0x56, 0x1e7c, 0x59, 0x1ef8, 0x61, 0xe3,
+ 0x65, 0x1ebd, 0x69, 0x129, 0x6e, 0xf1, 0x6f, 0xf5,
+ 0x75, 0x169, 0x76, 0x1e7d, 0x79, 0x1ef9, 0xc2, 0x1eaa,
+ 0xca, 0x1ec4, 0xd4, 0x1ed6, 0xe2, 0x1eab, 0xea, 0x1ec5,
+ 0xf4, 0x1ed7, 0x102, 0x1eb4, 0x103, 0x1eb5, 0x1a0, 0x1ee0,
+ 0x1a1, 0x1ee1, 0x1af, 0x1eee, 0x1b0, 0x1eef, 0x2c, 0x41,
+ 0x100, 0x45, 0x112, 0x47, 0x1e20, 0x49, 0x12a, 0x4f,
+ 0x14c, 0x55, 0x16a, 0x59, 0x232, 0x61, 0x101, 0x65,
+ 0x113, 0x67, 0x1e21, 0x69, 0x12b, 0x6f, 0x14d, 0x75,
+ 0x16b, 0x79, 0x233, 0xc4, 0x1de, 0xc6, 0x1e2, 0xd5,
+ 0x22c, 0xd6, 0x22a, 0xdc, 0x1d5, 0xe4, 0x1df, 0xe6,
+ 0x1e3, 0xf5, 0x22d, 0xf6, 0x22b, 0xfc, 0x1d6, 0x1ea,
+ 0x1ec, 0x1eb, 0x1ed, 0x226, 0x1e0, 0x227, 0x1e1, 0x22e,
+ 0x230, 0x22f, 0x231, 0x391, 0x1fb9, 0x399, 0x1fd9, 0x3a5,
+ 0x1fe9, 0x3b1, 0x1fb1, 0x3b9, 0x1fd1, 0x3c5, 0x1fe1, 0x418,
+ 0x4e2, 0x423, 0x4ee, 0x438, 0x4e3, 0x443, 0x4ef, 0x1e36,
+ 0x1e38, 0x1e37, 0x1e39, 0x1e5a, 0x1e5c, 0x1e5b, 0x1e5d, 0x20,
+ 0x41, 0x102, 0x45, 0x114, 0x47, 0x11e, 0x49, 0x12c,
+ 0x4f, 0x14e, 0x55, 0x16c, 0x61, 0x103, 0x65, 0x115,
+ 0x67, 0x11f, 0x69, 0x12d, 0x6f, 0x14f, 0x75, 0x16d,
+ 0x228, 0x1e1c, 0x229, 0x1e1d, 0x391, 0x1fb8, 0x399, 0x1fd8,
+ 0x3a5, 0x1fe8, 0x3b1, 0x1fb0, 0x3b9, 0x1fd0, 0x3c5, 0x1fe0,
+ 0x410, 0x4d0, 0x415, 0x4d6, 0x416, 0x4c1, 0x418, 0x419,
+ 0x423, 0x40e, 0x430, 0x4d1, 0x435, 0x4d7, 0x436, 0x4c2,
+ 0x438, 0x439, 0x443, 0x45e, 0x1ea0, 0x1eb6, 0x1ea1, 0x1eb7,
+ 0x2e, 0x41, 0x226, 0x42, 0x1e02, 0x43, 0x10a, 0x44,
+ 0x1e0a, 0x45, 0x116, 0x46, 0x1e1e, 0x47, 0x120, 0x48,
+ 0x1e22, 0x49, 0x130, 0x4d, 0x1e40, 0x4e, 0x1e44, 0x4f,
+ 0x22e, 0x50, 0x1e56, 0x52, 0x1e58, 0x53, 0x1e60, 0x54,
+ 0x1e6a, 0x57, 0x1e86, 0x58, 0x1e8a, 0x59, 0x1e8e, 0x5a,
+ 0x17b, 0x61, 0x227, 0x62, 0x1e03, 0x63, 0x10b, 0x64,
+ 0x1e0b, 0x65, 0x117, 0x66, 0x1e1f, 0x67, 0x121, 0x68,
+ 0x1e23, 0x6d, 0x1e41, 0x6e, 0x1e45, 0x6f, 0x22f, 0x70,
+ 0x1e57, 0x72, 0x1e59, 0x73, 0x1e61, 0x74, 0x1e6b, 0x77,
+ 0x1e87, 0x78, 0x1e8b, 0x79, 0x1e8f, 0x7a, 0x17c, 0x15a,
+ 0x1e64, 0x15b, 0x1e65, 0x160, 0x1e66, 0x161, 0x1e67, 0x17f,
+ 0x1e9b, 0x1e62, 0x1e68, 0x1e63, 0x1e69, 0x36, 0x41, 0xc4,
+ 0x45, 0xcb, 0x48, 0x1e26, 0x49, 0xcf, 0x4f, 0xd6,
+ 0x55, 0xdc, 0x57, 0x1e84, 0x58, 0x1e8c, 0x59, 0x178,
+ 0x61, 0xe4, 0x65, 0xeb, 0x68, 0x1e27, 0x69, 0xef,
+ 0x6f, 0xf6, 0x74, 0x1e97, 0x75, 0xfc, 0x77, 0x1e85,
+ 0x78, 0x1e8d, 0x79, 0xff, 0xd5, 0x1e4e, 0xf5, 0x1e4f,
+ 0x16a, 0x1e7a, 0x16b, 0x1e7b, 0x399, 0x3aa, 0x3a5, 0x3ab,
+ 0x3b9, 0x3ca, 0x3c5, 0x3cb, 0x3d2, 0x3d4, 0x406, 0x407,
+ 0x410, 0x4d2, 0x415, 0x401, 0x416, 0x4dc, 0x417, 0x4de,
+ 0x418, 0x4e4, 0x41e, 0x4e6, 0x423, 0x4f0, 0x427, 0x4f4,
+ 0x42b, 0x4f8, 0x42d, 0x4ec, 0x430, 0x4d3, 0x435, 0x451,
+ 0x436, 0x4dd, 0x437, 0x4df, 0x438, 0x4e5, 0x43e, 0x4e7,
+ 0x443, 0x4f1, 0x447, 0x4f5, 0x44b, 0x4f9, 0x44d, 0x4ed,
+ 0x456, 0x457, 0x4d8, 0x4da, 0x4d9, 0x4db, 0x4e8, 0x4ea,
+ 0x4e9, 0x4eb, 0x18, 0x41, 0x1ea2, 0x45, 0x1eba, 0x49,
+ 0x1ec8, 0x4f, 0x1ece, 0x55, 0x1ee6, 0x59, 0x1ef6, 0x61,
+ 0x1ea3, 0x65, 0x1ebb, 0x69, 0x1ec9, 0x6f, 0x1ecf, 0x75,
+ 0x1ee7, 0x79, 0x1ef7, 0xc2, 0x1ea8, 0xca, 0x1ec2, 0xd4,
+ 0x1ed4, 0xe2, 0x1ea9, 0xea, 0x1ec3, 0xf4, 0x1ed5, 0x102,
+ 0x1eb2, 0x103, 0x1eb3, 0x1a0, 0x1ede, 0x1a1, 0x1edf, 0x1af,
+ 0x1eec, 0x1b0, 0x1eed, 0x6, 0x41, 0xc5, 0x55, 0x16e,
+ 0x61, 0xe5, 0x75, 0x16f, 0x77, 0x1e98, 0x79, 0x1e99,
+ 0x6, 0x4f, 0x150, 0x55, 0x170, 0x6f, 0x151, 0x75,
+ 0x171, 0x423, 0x4f2, 0x443, 0x4f3, 0x25, 0x41, 0x1cd,
+ 0x43, 0x10c, 0x44, 0x10e, 0x45, 0x11a, 0x47, 0x1e6,
+ 0x48, 0x21e, 0x49, 0x1cf, 0x4b, 0x1e8, 0x4c, 0x13d,
+ 0x4e, 0x147, 0x4f, 0x1d1, 0x52, 0x158, 0x53, 0x160,
+ 0x54, 0x164, 0x55, 0x1d3, 0x5a, 0x17d, 0x61, 0x1ce,
+ 0x63, 0x10d, 0x64, 0x10f, 0x65, 0x11b, 0x67, 0x1e7,
+ 0x68, 0x21f, 0x69, 0x1d0, 0x6a, 0x1f0, 0x6b, 0x1e9,
+ 0x6c, 0x13e, 0x6e, 0x148, 0x6f, 0x1d2, 0x72, 0x159,
+ 0x73, 0x161, 0x74, 0x165, 0x75, 0x1d4, 0x7a, 0x17e,
+ 0xdc, 0x1d9, 0xfc, 0x1da, 0x1b7, 0x1ee, 0x292, 0x1ef,
+ 0xe, 0x41, 0x200, 0x45, 0x204, 0x49, 0x208, 0x4f,
+ 0x20c, 0x52, 0x210, 0x55, 0x214, 0x61, 0x201, 0x65,
+ 0x205, 0x69, 0x209, 0x6f, 0x20d, 0x72, 0x211, 0x75,
+ 0x215, 0x474, 0x476, 0x475, 0x477, 0xc, 0x41, 0x202,
+ 0x45, 0x206, 0x49, 0x20a, 0x4f, 0x20e, 0x52, 0x212,
+ 0x55, 0x216, 0x61, 0x203, 0x65, 0x207, 0x69, 0x20b,
+ 0x6f, 0x20f, 0x72, 0x213, 0x75, 0x217, 0xe, 0x391,
+ 0x1f08, 0x395, 0x1f18, 0x397, 0x1f28, 0x399, 0x1f38, 0x39f,
+ 0x1f48, 0x3a9, 0x1f68, 0x3b1, 0x1f00, 0x3b5, 0x1f10, 0x3b7,
+ 0x1f20, 0x3b9, 0x1f30, 0x3bf, 0x1f40, 0x3c1, 0x1fe4, 0x3c5,
+ 0x1f50, 0x3c9, 0x1f60, 0x10, 0x391, 0x1f09, 0x395, 0x1f19,
+ 0x397, 0x1f29, 0x399, 0x1f39, 0x39f, 0x1f49, 0x3a1, 0x1fec,
+ 0x3a5, 0x1f59, 0x3a9, 0x1f69, 0x3b1, 0x1f01, 0x3b5, 0x1f11,
+ 0x3b7, 0x1f21, 0x3b9, 0x1f31, 0x3bf, 0x1f41, 0x3c1, 0x1fe5,
+ 0x3c5, 0x1f51, 0x3c9, 0x1f61, 0x4, 0x4f, 0x1a0, 0x55,
+ 0x1af, 0x6f, 0x1a1, 0x75, 0x1b0, 0x2a, 0x41, 0x1ea0,
+ 0x42, 0x1e04, 0x44, 0x1e0c, 0x45, 0x1eb8, 0x48, 0x1e24,
+ 0x49, 0x1eca, 0x4b, 0x1e32, 0x4c, 0x1e36, 0x4d, 0x1e42,
+ 0x4e, 0x1e46, 0x4f, 0x1ecc, 0x52, 0x1e5a, 0x53, 0x1e62,
+ 0x54, 0x1e6c, 0x55, 0x1ee4, 0x56, 0x1e7e, 0x57, 0x1e88,
+ 0x59, 0x1ef4, 0x5a, 0x1e92, 0x61, 0x1ea1, 0x62, 0x1e05,
+ 0x64, 0x1e0d, 0x65, 0x1eb9, 0x68, 0x1e25, 0x69, 0x1ecb,
+ 0x6b, 0x1e33, 0x6c, 0x1e37, 0x6d, 0x1e43, 0x6e, 0x1e47,
+ 0x6f, 0x1ecd, 0x72, 0x1e5b, 0x73, 0x1e63, 0x74, 0x1e6d,
+ 0x75, 0x1ee5, 0x76, 0x1e7f, 0x77, 0x1e89, 0x79, 0x1ef5,
+ 0x7a, 0x1e93, 0x1a0, 0x1ee2, 0x1a1, 0x1ee3, 0x1af, 0x1ef0,
+ 0x1b0, 0x1ef1, 0x2, 0x55, 0x1e72, 0x75, 0x1e73, 0x2,
+ 0x41, 0x1e00, 0x61, 0x1e01, 0x4, 0x53, 0x218, 0x54,
+ 0x21a, 0x73, 0x219, 0x74, 0x21b, 0x16, 0x43, 0xc7,
+ 0x44, 0x1e10, 0x45, 0x228, 0x47, 0x122, 0x48, 0x1e28,
+ 0x4b, 0x136, 0x4c, 0x13b, 0x4e, 0x145, 0x52, 0x156,
+ 0x53, 0x15e, 0x54, 0x162, 0x63, 0xe7, 0x64, 0x1e11,
+ 0x65, 0x229, 0x67, 0x123, 0x68, 0x1e29, 0x6b, 0x137,
+ 0x6c, 0x13c, 0x6e, 0x146, 0x72, 0x157, 0x73, 0x15f,
+ 0x74, 0x163, 0xa, 0x41, 0x104, 0x45, 0x118, 0x49,
+ 0x12e, 0x4f, 0x1ea, 0x55, 0x172, 0x61, 0x105, 0x65,
+ 0x119, 0x69, 0x12f, 0x6f, 0x1eb, 0x75, 0x173, 0xc,
+ 0x44, 0x1e12, 0x45, 0x1e18, 0x4c, 0x1e3c, 0x4e, 0x1e4a,
+ 0x54, 0x1e70, 0x55, 0x1e76, 0x64, 0x1e13, 0x65, 0x1e19,
+ 0x6c, 0x1e3d, 0x6e, 0x1e4b, 0x74, 0x1e71, 0x75, 0x1e77,
+ 0x2, 0x48, 0x1e2a, 0x68, 0x1e2b, 0x6, 0x45, 0x1e1a,
+ 0x49, 0x1e2c, 0x55, 0x1e74, 0x65, 0x1e1b, 0x69, 0x1e2d,
+ 0x75, 0x1e75, 0x11, 0x42, 0x1e06, 0x44, 0x1e0e, 0x4b,
+ 0x1e34, 0x4c, 0x1e3a, 0x4e, 0x1e48, 0x52, 0x1e5e, 0x54,
+ 0x1e6e, 0x5a, 0x1e94, 0x62, 0x1e07, 0x64, 0x1e0f, 0x68,
+ 0x1e96, 0x6b, 0x1e35, 0x6c, 0x1e3b, 0x6e, 0x1e49, 0x72,
+ 0x1e5f, 0x74, 0x1e6f, 0x7a, 0x1e95, 0x2c, 0x3c, 0x226e,
+ 0x3d, 0x2260, 0x3e, 0x226f, 0x2190, 0x219a, 0x2192, 0x219b,
+ 0x2194, 0x21ae, 0x21d0, 0x21cd, 0x21d2, 0x21cf, 0x21d4, 0x21ce,
+ 0x2203, 0x2204, 0x2208, 0x2209, 0x220b, 0x220c, 0x2223, 0x2224,
+ 0x2225, 0x2226, 0x223c, 0x2241, 0x2243, 0x2244, 0x2245, 0x2247,
+ 0x2248, 0x2249, 0x224d, 0x226d, 0x2261, 0x2262, 0x2264, 0x2270,
+ 0x2265, 0x2271, 0x2272, 0x2274, 0x2273, 0x2275, 0x2276, 0x2278,
+ 0x2277, 0x2279, 0x227a, 0x2280, 0x227b, 0x2281, 0x227c, 0x22e0,
+ 0x227d, 0x22e1, 0x2282, 0x2284, 0x2283, 0x2285, 0x2286, 0x2288,
+ 0x2287, 0x2289, 0x2291, 0x22e2, 0x2292, 0x22e3, 0x22a2, 0x22ac,
+ 0x22a8, 0x22ad, 0x22a9, 0x22ae, 0x22ab, 0x22af, 0x22b2, 0x22ea,
+ 0x22b3, 0x22eb, 0x22b4, 0x22ec, 0x22b5, 0x22ed, 0x1d, 0xa8,
+ 0x1fc1, 0x3b1, 0x1fb6, 0x3b7, 0x1fc6, 0x3b9, 0x1fd6, 0x3c5,
+ 0x1fe6, 0x3c9, 0x1ff6, 0x3ca, 0x1fd7, 0x3cb, 0x1fe7, 0x1f00,
+ 0x1f06, 0x1f01, 0x1f07, 0x1f08, 0x1f0e, 0x1f09, 0x1f0f, 0x1f20,
+ 0x1f26, 0x1f21, 0x1f27, 0x1f28, 0x1f2e, 0x1f29, 0x1f2f, 0x1f30,
+ 0x1f36, 0x1f31, 0x1f37, 0x1f38, 0x1f3e, 0x1f39, 0x1f3f, 0x1f50,
+ 0x1f56, 0x1f51, 0x1f57, 0x1f59, 0x1f5f, 0x1f60, 0x1f66, 0x1f61,
+ 0x1f67, 0x1f68, 0x1f6e, 0x1f69, 0x1f6f, 0x1fbf, 0x1fcf, 0x1ffe,
+ 0x1fdf, 0x3f, 0x391, 0x1fbc, 0x397, 0x1fcc, 0x3a9, 0x1ffc,
+ 0x3ac, 0x1fb4, 0x3ae, 0x1fc4, 0x3b1, 0x1fb3, 0x3b7, 0x1fc3,
+ 0x3c9, 0x1ff3, 0x3ce, 0x1ff4, 0x1f00, 0x1f80, 0x1f01, 0x1f81,
+ 0x1f02, 0x1f82, 0x1f03, 0x1f83, 0x1f04, 0x1f84, 0x1f05, 0x1f85,
+ 0x1f06, 0x1f86, 0x1f07, 0x1f87, 0x1f08, 0x1f88, 0x1f09, 0x1f89,
+ 0x1f0a, 0x1f8a, 0x1f0b, 0x1f8b, 0x1f0c, 0x1f8c, 0x1f0d, 0x1f8d,
+ 0x1f0e, 0x1f8e, 0x1f0f, 0x1f8f, 0x1f20, 0x1f90, 0x1f21, 0x1f91,
+ 0x1f22, 0x1f92, 0x1f23, 0x1f93, 0x1f24, 0x1f94, 0x1f25, 0x1f95,
+ 0x1f26, 0x1f96, 0x1f27, 0x1f97, 0x1f28, 0x1f98, 0x1f29, 0x1f99,
+ 0x1f2a, 0x1f9a, 0x1f2b, 0x1f9b, 0x1f2c, 0x1f9c, 0x1f2d, 0x1f9d,
+ 0x1f2e, 0x1f9e, 0x1f2f, 0x1f9f, 0x1f60, 0x1fa0, 0x1f61, 0x1fa1,
+ 0x1f62, 0x1fa2, 0x1f63, 0x1fa3, 0x1f64, 0x1fa4, 0x1f65, 0x1fa5,
+ 0x1f66, 0x1fa6, 0x1f67, 0x1fa7, 0x1f68, 0x1fa8, 0x1f69, 0x1fa9,
+ 0x1f6a, 0x1faa, 0x1f6b, 0x1fab, 0x1f6c, 0x1fac, 0x1f6d, 0x1fad,
+ 0x1f6e, 0x1fae, 0x1f6f, 0x1faf, 0x1f70, 0x1fb2, 0x1f74, 0x1fc2,
+ 0x1f7c, 0x1ff2, 0x1fb6, 0x1fb7, 0x1fc6, 0x1fc7, 0x1ff6, 0x1ff7,
+ 0x1, 0x627, 0x622, 0x6, 0x627, 0x623, 0x648, 0x624,
+ 0x64a, 0x626, 0x6c1, 0x6c2, 0x6d2, 0x6d3, 0x6d5, 0x6c0,
+ 0x1, 0x627, 0x625, 0x3, 0x928, 0x929, 0x930, 0x931,
+ 0x933, 0x934, 0x1, 0x9c7, 0x9cb, 0x1, 0x9c7, 0x9cc,
+ 0x1, 0xb47, 0xb4b, 0x1, 0xb47, 0xb48, 0x1, 0xb47,
+ 0xb4c, 0x2, 0xbc6, 0xbca, 0xbc7, 0xbcb, 0x2, 0xb92,
+ 0xb94, 0xbc6, 0xbcc, 0x1, 0xc46, 0xc48, 0x1, 0xcc6,
+ 0xcca, 0x3, 0xcbf, 0xcc0, 0xcc6, 0xcc7, 0xcca, 0xccb,
+ 0x1, 0xcc6, 0xcc8, 0x2, 0xd46, 0xd4a, 0xd47, 0xd4b,
+ 0x1, 0xd46, 0xd4c, 0x2, 0xdd9, 0xdda, 0xddc, 0xddd,
+ 0x1, 0xdd9, 0xddc, 0x1, 0xdd9, 0xdde, 0x1, 0x1025,
+ 0x1026, 0xb, 0x1b05, 0x1b06, 0x1b07, 0x1b08, 0x1b09, 0x1b0a,
+ 0x1b0b, 0x1b0c, 0x1b0d, 0x1b0e, 0x1b11, 0x1b12, 0x1b3a, 0x1b3b,
+ 0x1b3c, 0x1b3d, 0x1b3e, 0x1b40, 0x1b3f, 0x1b41, 0x1b42, 0x1b43,
+ 0x30, 0x3046, 0x3094, 0x304b, 0x304c, 0x304d, 0x304e, 0x304f,
+ 0x3050, 0x3051, 0x3052, 0x3053, 0x3054, 0x3055, 0x3056, 0x3057,
+ 0x3058, 0x3059, 0x305a, 0x305b, 0x305c, 0x305d, 0x305e, 0x305f,
+ 0x3060, 0x3061, 0x3062, 0x3064, 0x3065, 0x3066, 0x3067, 0x3068,
+ 0x3069, 0x306f, 0x3070, 0x3072, 0x3073, 0x3075, 0x3076, 0x3078,
+ 0x3079, 0x307b, 0x307c, 0x309d, 0x309e, 0x30a6, 0x30f4, 0x30ab,
+ 0x30ac, 0x30ad, 0x30ae, 0x30af, 0x30b0, 0x30b1, 0x30b2, 0x30b3,
+ 0x30b4, 0x30b5, 0x30b6, 0x30b7, 0x30b8, 0x30b9, 0x30ba, 0x30bb,
+ 0x30bc, 0x30bd, 0x30be, 0x30bf, 0x30c0, 0x30c1, 0x30c2, 0x30c4,
+ 0x30c5, 0x30c6, 0x30c7, 0x30c8, 0x30c9, 0x30cf, 0x30d0, 0x30d2,
+ 0x30d3, 0x30d5, 0x30d6, 0x30d8, 0x30d9, 0x30db, 0x30dc, 0x30ef,
+ 0x30f7, 0x30f0, 0x30f8, 0x30f1, 0x30f9, 0x30f2, 0x30fa, 0x30fd,
+ 0x30fe, 0xa, 0x306f, 0x3071, 0x3072, 0x3074, 0x3075, 0x3077,
+ 0x3078, 0x307a, 0x307b, 0x307d, 0x30cf, 0x30d1, 0x30d2, 0x30d4,
+ 0x30d5, 0x30d7, 0x30d8, 0x30da, 0x30db, 0x30dd,
+};
+
+struct NormalizationCorrection {
+ uint ucs4;
+ uint old_mapping;
+ int version;
+};
+
+static const NormalizationCorrection uc_normalization_corrections[] = {
+ { 0xf951, 0x96fb, 6 },
+ { 0x2f868, 0x2136a, 7 },
+ { 0x2f874, 0x5f33, 7 },
+ { 0x2f91f, 0x43ab, 7 },
+ { 0x2f95f, 0x7aae, 7 },
+ { 0x2f9bf, 0x4d57, 7 },
+};
+
+enum { NumNormalizationCorrections = 6 };
+
+enum { UnicodeBlockCount = 512 }; // number of unicode blocks
+enum { UnicodeBlockSize = 128 }; // size of each block
+
+namespace QUnicodeTables {
+
+static const unsigned char uc_scripts[] = {
+ Common, /* U+0000-007f */
+ Common, /* U+0080-00ff */
+ Latin, /* U+0100-017f */
+ Latin, /* U+0180-01ff */
+ Latin, /* U+0200-027f */
+ Latin, /* U+0280-02ff */
+ 32, /* U+0300-037f at offset 512 */
+ 33, /* U+0380-03ff at offset 640 */
+ Cyrillic, /* U+0400-047f */
+ 34, /* U+0480-04ff at offset 768 */
+ 35, /* U+0500-057f at offset 896 */
+ 36, /* U+0580-05ff at offset 1024 */
+ 37, /* U+0600-067f at offset 1152 */
+ 38, /* U+0680-06ff at offset 1280 */
+ 39, /* U+0700-077f at offset 1408 */
+ 40, /* U+0780-07ff at offset 1536 */
+ Common, /* U+0800-087f */
+ Common, /* U+0880-08ff */
+ 41, /* U+0900-097f at offset 1664 */
+ 42, /* U+0980-09ff at offset 1792 */
+ 43, /* U+0a00-0a7f at offset 1920 */
+ 44, /* U+0a80-0aff at offset 2048 */
+ 45, /* U+0b00-0b7f at offset 2176 */
+ 46, /* U+0b80-0bff at offset 2304 */
+ 47, /* U+0c00-0c7f at offset 2432 */
+ 48, /* U+0c80-0cff at offset 2560 */
+ 49, /* U+0d00-0d7f at offset 2688 */
+ 50, /* U+0d80-0dff at offset 2816 */
+ 51, /* U+0e00-0e7f at offset 2944 */
+ 52, /* U+0e80-0eff at offset 3072 */
+ 53, /* U+0f00-0f7f at offset 3200 */
+ 54, /* U+0f80-0fff at offset 3328 */
+ 55, /* U+1000-107f at offset 3456 */
+ 56, /* U+1080-10ff at offset 3584 */
+ 57, /* U+1100-117f at offset 3712 */
+ 58, /* U+1180-11ff at offset 3840 */
+ Ethiopic, /* U+1200-127f */
+ Ethiopic, /* U+1280-12ff */
+ Ethiopic, /* U+1300-137f */
+ Ethiopic, /* U+1380-13ff */
+ Common, /* U+1400-147f */
+ CanadianAboriginal, /* U+1480-14ff */
+ CanadianAboriginal, /* U+1500-157f */
+ CanadianAboriginal, /* U+1580-15ff */
+ CanadianAboriginal, /* U+1600-167f */
+ 59, /* U+1680-16ff at offset 3968 */
+ Tagalog, /* U+1700-177f */
+ 60, /* U+1780-17ff at offset 4096 */
+ Mongolian, /* U+1800-187f */
+ Mongolian, /* U+1880-18ff */
+ Limbu, /* U+1900-197f */
+ 61, /* U+1980-19ff at offset 4224 */
+ Buginese, /* U+1a00-1a7f */
+ Common, /* U+1a80-1aff */
+ Balinese, /* U+1b00-1b7f */
+ Common, /* U+1b80-1bff */
+ Common, /* U+1c00-1c7f */
+ Common, /* U+1c80-1cff */
+ 62, /* U+1d00-1d7f at offset 4352 */
+ 63, /* U+1d80-1dff at offset 4480 */
+ Latin, /* U+1e00-1e7f */
+ Latin, /* U+1e80-1eff */
+ 64, /* U+1f00-1f7f at offset 4608 */
+ 65, /* U+1f80-1fff at offset 4736 */
+ 66, /* U+2000-207f at offset 4864 */
+ 67, /* U+2080-20ff at offset 4992 */
+ 68, /* U+2100-217f at offset 5120 */
+ Common, /* U+2180-21ff */
+ Common, /* U+2200-227f */
+ Common, /* U+2280-22ff */
+ Common, /* U+2300-237f */
+ Common, /* U+2380-23ff */
+ Common, /* U+2400-247f */
+ Common, /* U+2480-24ff */
+ Common, /* U+2500-257f */
+ Common, /* U+2580-25ff */
+ Common, /* U+2600-267f */
+ Common, /* U+2680-26ff */
+ Common, /* U+2700-277f */
+ Common, /* U+2780-27ff */
+ Braille, /* U+2800-287f */
+ Braille, /* U+2880-28ff */
+ Common, /* U+2900-297f */
+ Common, /* U+2980-29ff */
+ Common, /* U+2a00-2a7f */
+ Common, /* U+2a80-2aff */
+ Common, /* U+2b00-2b7f */
+ Common, /* U+2b80-2bff */
+ Glagolitic, /* U+2c00-2c7f */
+ Coptic, /* U+2c80-2cff */
+ 69, /* U+2d00-2d7f at offset 5248 */
+ Ethiopic, /* U+2d80-2dff */
+ Common, /* U+2e00-2e7f */
+ Han, /* U+2e80-2eff */
+ Han, /* U+2f00-2f7f */
+ Han, /* U+2f80-2fff */
+ 70, /* U+3000-307f at offset 5376 */
+ 71, /* U+3080-30ff at offset 5504 */
+ 72, /* U+3100-317f at offset 5632 */
+ 73, /* U+3180-31ff at offset 5760 */
+ 74, /* U+3200-327f at offset 5888 */
+ Common, /* U+3280-32ff */
+ Common, /* U+3300-337f */
+ Common, /* U+3380-33ff */
+ Han, /* U+3400-347f */
+ Han, /* U+3480-34ff */
+ Han, /* U+3500-357f */
+ Han, /* U+3580-35ff */
+ Han, /* U+3600-367f */
+ Han, /* U+3680-36ff */
+ Han, /* U+3700-377f */
+ Han, /* U+3780-37ff */
+ Han, /* U+3800-387f */
+ Han, /* U+3880-38ff */
+ Han, /* U+3900-397f */
+ Han, /* U+3980-39ff */
+ Han, /* U+3a00-3a7f */
+ Han, /* U+3a80-3aff */
+ Han, /* U+3b00-3b7f */
+ Han, /* U+3b80-3bff */
+ Han, /* U+3c00-3c7f */
+ Han, /* U+3c80-3cff */
+ Han, /* U+3d00-3d7f */
+ Han, /* U+3d80-3dff */
+ Han, /* U+3e00-3e7f */
+ Han, /* U+3e80-3eff */
+ Han, /* U+3f00-3f7f */
+ Han, /* U+3f80-3fff */
+ Han, /* U+4000-407f */
+ Han, /* U+4080-40ff */
+ Han, /* U+4100-417f */
+ Han, /* U+4180-41ff */
+ Han, /* U+4200-427f */
+ Han, /* U+4280-42ff */
+ Han, /* U+4300-437f */
+ Han, /* U+4380-43ff */
+ Han, /* U+4400-447f */
+ Han, /* U+4480-44ff */
+ Han, /* U+4500-457f */
+ Han, /* U+4580-45ff */
+ Han, /* U+4600-467f */
+ Han, /* U+4680-46ff */
+ Han, /* U+4700-477f */
+ Han, /* U+4780-47ff */
+ Han, /* U+4800-487f */
+ Han, /* U+4880-48ff */
+ Han, /* U+4900-497f */
+ Han, /* U+4980-49ff */
+ Han, /* U+4a00-4a7f */
+ Han, /* U+4a80-4aff */
+ Han, /* U+4b00-4b7f */
+ Han, /* U+4b80-4bff */
+ Han, /* U+4c00-4c7f */
+ Han, /* U+4c80-4cff */
+ Han, /* U+4d00-4d7f */
+ Han, /* U+4d80-4dff */
+ Han, /* U+4e00-4e7f */
+ Han, /* U+4e80-4eff */
+ Han, /* U+4f00-4f7f */
+ Han, /* U+4f80-4fff */
+ Han, /* U+5000-507f */
+ Han, /* U+5080-50ff */
+ Han, /* U+5100-517f */
+ Han, /* U+5180-51ff */
+ Han, /* U+5200-527f */
+ Han, /* U+5280-52ff */
+ Han, /* U+5300-537f */
+ Han, /* U+5380-53ff */
+ Han, /* U+5400-547f */
+ Han, /* U+5480-54ff */
+ Han, /* U+5500-557f */
+ Han, /* U+5580-55ff */
+ Han, /* U+5600-567f */
+ Han, /* U+5680-56ff */
+ Han, /* U+5700-577f */
+ Han, /* U+5780-57ff */
+ Han, /* U+5800-587f */
+ Han, /* U+5880-58ff */
+ Han, /* U+5900-597f */
+ Han, /* U+5980-59ff */
+ Han, /* U+5a00-5a7f */
+ Han, /* U+5a80-5aff */
+ Han, /* U+5b00-5b7f */
+ Han, /* U+5b80-5bff */
+ Han, /* U+5c00-5c7f */
+ Han, /* U+5c80-5cff */
+ Han, /* U+5d00-5d7f */
+ Han, /* U+5d80-5dff */
+ Han, /* U+5e00-5e7f */
+ Han, /* U+5e80-5eff */
+ Han, /* U+5f00-5f7f */
+ Han, /* U+5f80-5fff */
+ Han, /* U+6000-607f */
+ Han, /* U+6080-60ff */
+ Han, /* U+6100-617f */
+ Han, /* U+6180-61ff */
+ Han, /* U+6200-627f */
+ Han, /* U+6280-62ff */
+ Han, /* U+6300-637f */
+ Han, /* U+6380-63ff */
+ Han, /* U+6400-647f */
+ Han, /* U+6480-64ff */
+ Han, /* U+6500-657f */
+ Han, /* U+6580-65ff */
+ Han, /* U+6600-667f */
+ Han, /* U+6680-66ff */
+ Han, /* U+6700-677f */
+ Han, /* U+6780-67ff */
+ Han, /* U+6800-687f */
+ Han, /* U+6880-68ff */
+ Han, /* U+6900-697f */
+ Han, /* U+6980-69ff */
+ Han, /* U+6a00-6a7f */
+ Han, /* U+6a80-6aff */
+ Han, /* U+6b00-6b7f */
+ Han, /* U+6b80-6bff */
+ Han, /* U+6c00-6c7f */
+ Han, /* U+6c80-6cff */
+ Han, /* U+6d00-6d7f */
+ Han, /* U+6d80-6dff */
+ Han, /* U+6e00-6e7f */
+ Han, /* U+6e80-6eff */
+ Han, /* U+6f00-6f7f */
+ Han, /* U+6f80-6fff */
+ Han, /* U+7000-707f */
+ Han, /* U+7080-70ff */
+ Han, /* U+7100-717f */
+ Han, /* U+7180-71ff */
+ Han, /* U+7200-727f */
+ Han, /* U+7280-72ff */
+ Han, /* U+7300-737f */
+ Han, /* U+7380-73ff */
+ Han, /* U+7400-747f */
+ Han, /* U+7480-74ff */
+ Han, /* U+7500-757f */
+ Han, /* U+7580-75ff */
+ Han, /* U+7600-767f */
+ Han, /* U+7680-76ff */
+ Han, /* U+7700-777f */
+ Han, /* U+7780-77ff */
+ Han, /* U+7800-787f */
+ Han, /* U+7880-78ff */
+ Han, /* U+7900-797f */
+ Han, /* U+7980-79ff */
+ Han, /* U+7a00-7a7f */
+ Han, /* U+7a80-7aff */
+ Han, /* U+7b00-7b7f */
+ Han, /* U+7b80-7bff */
+ Han, /* U+7c00-7c7f */
+ Han, /* U+7c80-7cff */
+ Han, /* U+7d00-7d7f */
+ Han, /* U+7d80-7dff */
+ Han, /* U+7e00-7e7f */
+ Han, /* U+7e80-7eff */
+ Han, /* U+7f00-7f7f */
+ Han, /* U+7f80-7fff */
+ Han, /* U+8000-807f */
+ Han, /* U+8080-80ff */
+ Han, /* U+8100-817f */
+ Han, /* U+8180-81ff */
+ Han, /* U+8200-827f */
+ Han, /* U+8280-82ff */
+ Han, /* U+8300-837f */
+ Han, /* U+8380-83ff */
+ Han, /* U+8400-847f */
+ Han, /* U+8480-84ff */
+ Han, /* U+8500-857f */
+ Han, /* U+8580-85ff */
+ Han, /* U+8600-867f */
+ Han, /* U+8680-86ff */
+ Han, /* U+8700-877f */
+ Han, /* U+8780-87ff */
+ Han, /* U+8800-887f */
+ Han, /* U+8880-88ff */
+ Han, /* U+8900-897f */
+ Han, /* U+8980-89ff */
+ Han, /* U+8a00-8a7f */
+ Han, /* U+8a80-8aff */
+ Han, /* U+8b00-8b7f */
+ Han, /* U+8b80-8bff */
+ Han, /* U+8c00-8c7f */
+ Han, /* U+8c80-8cff */
+ Han, /* U+8d00-8d7f */
+ Han, /* U+8d80-8dff */
+ Han, /* U+8e00-8e7f */
+ Han, /* U+8e80-8eff */
+ Han, /* U+8f00-8f7f */
+ Han, /* U+8f80-8fff */
+ Han, /* U+9000-907f */
+ Han, /* U+9080-90ff */
+ Han, /* U+9100-917f */
+ Han, /* U+9180-91ff */
+ Han, /* U+9200-927f */
+ Han, /* U+9280-92ff */
+ Han, /* U+9300-937f */
+ Han, /* U+9380-93ff */
+ Han, /* U+9400-947f */
+ Han, /* U+9480-94ff */
+ Han, /* U+9500-957f */
+ Han, /* U+9580-95ff */
+ Han, /* U+9600-967f */
+ Han, /* U+9680-96ff */
+ Han, /* U+9700-977f */
+ Han, /* U+9780-97ff */
+ Han, /* U+9800-987f */
+ Han, /* U+9880-98ff */
+ Han, /* U+9900-997f */
+ Han, /* U+9980-99ff */
+ Han, /* U+9a00-9a7f */
+ Han, /* U+9a80-9aff */
+ Han, /* U+9b00-9b7f */
+ Han, /* U+9b80-9bff */
+ Han, /* U+9c00-9c7f */
+ Han, /* U+9c80-9cff */
+ Han, /* U+9d00-9d7f */
+ Han, /* U+9d80-9dff */
+ Han, /* U+9e00-9e7f */
+ Han, /* U+9e80-9eff */
+ Han, /* U+9f00-9f7f */
+ Han, /* U+9f80-9fff */
+ Yi, /* U+a000-a07f */
+ Yi, /* U+a080-a0ff */
+ Yi, /* U+a100-a17f */
+ Yi, /* U+a180-a1ff */
+ Yi, /* U+a200-a27f */
+ Yi, /* U+a280-a2ff */
+ Yi, /* U+a300-a37f */
+ Yi, /* U+a380-a3ff */
+ Yi, /* U+a400-a47f */
+ Yi, /* U+a480-a4ff */
+ Common, /* U+a500-a57f */
+ Common, /* U+a580-a5ff */
+ Common, /* U+a600-a67f */
+ Common, /* U+a680-a6ff */
+ Common, /* U+a700-a77f */
+ Common, /* U+a780-a7ff */
+ SylotiNagri, /* U+a800-a87f */
+ Common, /* U+a880-a8ff */
+ Common, /* U+a900-a97f */
+ Common, /* U+a980-a9ff */
+ Common, /* U+aa00-aa7f */
+ Common, /* U+aa80-aaff */
+ Common, /* U+ab00-ab7f */
+ Common, /* U+ab80-abff */
+ Hangul, /* U+ac00-ac7f */
+ Hangul, /* U+ac80-acff */
+ Hangul, /* U+ad00-ad7f */
+ Hangul, /* U+ad80-adff */
+ Hangul, /* U+ae00-ae7f */
+ Hangul, /* U+ae80-aeff */
+ Hangul, /* U+af00-af7f */
+ Hangul, /* U+af80-afff */
+ Hangul, /* U+b000-b07f */
+ Hangul, /* U+b080-b0ff */
+ Hangul, /* U+b100-b17f */
+ Hangul, /* U+b180-b1ff */
+ Hangul, /* U+b200-b27f */
+ Hangul, /* U+b280-b2ff */
+ Hangul, /* U+b300-b37f */
+ Hangul, /* U+b380-b3ff */
+ Hangul, /* U+b400-b47f */
+ Hangul, /* U+b480-b4ff */
+ Hangul, /* U+b500-b57f */
+ Hangul, /* U+b580-b5ff */
+ Hangul, /* U+b600-b67f */
+ Hangul, /* U+b680-b6ff */
+ Hangul, /* U+b700-b77f */
+ Hangul, /* U+b780-b7ff */
+ Hangul, /* U+b800-b87f */
+ Hangul, /* U+b880-b8ff */
+ Hangul, /* U+b900-b97f */
+ Hangul, /* U+b980-b9ff */
+ Hangul, /* U+ba00-ba7f */
+ Hangul, /* U+ba80-baff */
+ Hangul, /* U+bb00-bb7f */
+ Hangul, /* U+bb80-bbff */
+ Hangul, /* U+bc00-bc7f */
+ Hangul, /* U+bc80-bcff */
+ Hangul, /* U+bd00-bd7f */
+ Hangul, /* U+bd80-bdff */
+ Hangul, /* U+be00-be7f */
+ Hangul, /* U+be80-beff */
+ Hangul, /* U+bf00-bf7f */
+ Hangul, /* U+bf80-bfff */
+ Hangul, /* U+c000-c07f */
+ Hangul, /* U+c080-c0ff */
+ Hangul, /* U+c100-c17f */
+ Hangul, /* U+c180-c1ff */
+ Hangul, /* U+c200-c27f */
+ Hangul, /* U+c280-c2ff */
+ Hangul, /* U+c300-c37f */
+ Hangul, /* U+c380-c3ff */
+ Hangul, /* U+c400-c47f */
+ Hangul, /* U+c480-c4ff */
+ Hangul, /* U+c500-c57f */
+ Hangul, /* U+c580-c5ff */
+ Hangul, /* U+c600-c67f */
+ Hangul, /* U+c680-c6ff */
+ Hangul, /* U+c700-c77f */
+ Hangul, /* U+c780-c7ff */
+ Hangul, /* U+c800-c87f */
+ Hangul, /* U+c880-c8ff */
+ Hangul, /* U+c900-c97f */
+ Hangul, /* U+c980-c9ff */
+ Hangul, /* U+ca00-ca7f */
+ Hangul, /* U+ca80-caff */
+ Hangul, /* U+cb00-cb7f */
+ Hangul, /* U+cb80-cbff */
+ Hangul, /* U+cc00-cc7f */
+ Hangul, /* U+cc80-ccff */
+ Hangul, /* U+cd00-cd7f */
+ Hangul, /* U+cd80-cdff */
+ Hangul, /* U+ce00-ce7f */
+ Hangul, /* U+ce80-ceff */
+ Hangul, /* U+cf00-cf7f */
+ Hangul, /* U+cf80-cfff */
+ Hangul, /* U+d000-d07f */
+ Hangul, /* U+d080-d0ff */
+ Hangul, /* U+d100-d17f */
+ Hangul, /* U+d180-d1ff */
+ Hangul, /* U+d200-d27f */
+ Hangul, /* U+d280-d2ff */
+ Hangul, /* U+d300-d37f */
+ Hangul, /* U+d380-d3ff */
+ Hangul, /* U+d400-d47f */
+ Hangul, /* U+d480-d4ff */
+ Hangul, /* U+d500-d57f */
+ Hangul, /* U+d580-d5ff */
+ Hangul, /* U+d600-d67f */
+ Hangul, /* U+d680-d6ff */
+ Hangul, /* U+d700-d77f */
+ 75, /* U+d780-d7ff at offset 6016 */
+ Common, /* U+d800-d87f */
+ Common, /* U+d880-d8ff */
+ Common, /* U+d900-d97f */
+ Common, /* U+d980-d9ff */
+ Common, /* U+da00-da7f */
+ Common, /* U+da80-daff */
+ Common, /* U+db00-db7f */
+ Common, /* U+db80-dbff */
+ Common, /* U+dc00-dc7f */
+ Common, /* U+dc80-dcff */
+ Common, /* U+dd00-dd7f */
+ Common, /* U+dd80-ddff */
+ Common, /* U+de00-de7f */
+ Common, /* U+de80-deff */
+ Common, /* U+df00-df7f */
+ Common, /* U+df80-dfff */
+ Common, /* U+e000-e07f */
+ Common, /* U+e080-e0ff */
+ Common, /* U+e100-e17f */
+ Common, /* U+e180-e1ff */
+ Common, /* U+e200-e27f */
+ Common, /* U+e280-e2ff */
+ Common, /* U+e300-e37f */
+ Common, /* U+e380-e3ff */
+ Common, /* U+e400-e47f */
+ Common, /* U+e480-e4ff */
+ Common, /* U+e500-e57f */
+ Common, /* U+e580-e5ff */
+ Common, /* U+e600-e67f */
+ Common, /* U+e680-e6ff */
+ Common, /* U+e700-e77f */
+ Common, /* U+e780-e7ff */
+ Common, /* U+e800-e87f */
+ Common, /* U+e880-e8ff */
+ Common, /* U+e900-e97f */
+ Common, /* U+e980-e9ff */
+ Common, /* U+ea00-ea7f */
+ Common, /* U+ea80-eaff */
+ Common, /* U+eb00-eb7f */
+ Common, /* U+eb80-ebff */
+ Common, /* U+ec00-ec7f */
+ Common, /* U+ec80-ecff */
+ Common, /* U+ed00-ed7f */
+ Common, /* U+ed80-edff */
+ Common, /* U+ee00-ee7f */
+ Common, /* U+ee80-eeff */
+ Common, /* U+ef00-ef7f */
+ Common, /* U+ef80-efff */
+ Common, /* U+f000-f07f */
+ Common, /* U+f080-f0ff */
+ Common, /* U+f100-f17f */
+ Common, /* U+f180-f1ff */
+ Common, /* U+f200-f27f */
+ Common, /* U+f280-f2ff */
+ Common, /* U+f300-f37f */
+ Common, /* U+f380-f3ff */
+ Common, /* U+f400-f47f */
+ Common, /* U+f480-f4ff */
+ Common, /* U+f500-f57f */
+ Common, /* U+f580-f5ff */
+ Common, /* U+f600-f67f */
+ Common, /* U+f680-f6ff */
+ Common, /* U+f700-f77f */
+ Common, /* U+f780-f7ff */
+ Common, /* U+f800-f87f */
+ Common, /* U+f880-f8ff */
+ Han, /* U+f900-f97f */
+ Han, /* U+f980-f9ff */
+ Han, /* U+fa00-fa7f */
+ Han, /* U+fa80-faff */
+ 76, /* U+fb00-fb7f at offset 6144 */
+ 77, /* U+fb80-fbff at offset 6272 */
+ Arabic, /* U+fc00-fc7f */
+ Arabic, /* U+fc80-fcff */
+ 78, /* U+fd00-fd7f at offset 6400 */
+ 79, /* U+fd80-fdff at offset 6528 */
+ 80, /* U+fe00-fe7f at offset 6656 */
+ 81, /* U+fe80-feff at offset 6784 */
+ Common, /* U+ff00-ff7f */
+ 82, /* U+ff80-ffff at offset 6912 */
+
+
+ /* U+0300-037f at offset 512 */
+ Inherited, Inherited, Inherited, Inherited, Inherited, Inherited, Inherited, Inherited,
+ Inherited, Inherited, Inherited, Inherited, Inherited, Inherited, Inherited, Inherited,
+ Inherited, Inherited, Inherited, Inherited, Inherited, Inherited, Inherited, Inherited,
+ Inherited, Inherited, Inherited, Inherited, Inherited, Inherited, Inherited, Inherited,
+ Inherited, Inherited, Inherited, Inherited, Inherited, Inherited, Inherited, Inherited,
+ Inherited, Inherited, Inherited, Inherited, Inherited, Inherited, Inherited, Inherited,
+ Inherited, Inherited, Inherited, Inherited, Inherited, Inherited, Inherited, Inherited,
+ Inherited, Inherited, Inherited, Inherited, Inherited, Inherited, Inherited, Inherited,
+ Inherited, Inherited, Inherited, Inherited, Inherited, Inherited, Inherited, Inherited,
+ Inherited, Inherited, Inherited, Inherited, Inherited, Inherited, Inherited, Inherited,
+ Inherited, Inherited, Inherited, Inherited, Inherited, Inherited, Inherited, Inherited,
+ Inherited, Inherited, Inherited, Inherited, Inherited, Inherited, Inherited, Inherited,
+ Inherited, Inherited, Inherited, Inherited, Inherited, Inherited, Inherited, Inherited,
+ Inherited, Inherited, Inherited, Inherited, Inherited, Inherited, Inherited, Inherited,
+ Common, Common, Common, Common, Greek, Greek, Common, Common,
+ Common, Common, Greek, Greek, Greek, Greek, Common, Common,
+
+ /* U+0380-03ff at offset 640 */
+ Common, Common, Common, Common, Greek, Greek, Greek, Common,
+ Greek, Greek, Greek, Common, Greek, Common, Greek, Greek,
+ Greek, Greek, Greek, Greek, Greek, Greek, Greek, Greek,
+ Greek, Greek, Greek, Greek, Greek, Greek, Greek, Greek,
+ Greek, Greek, Common, Greek, Greek, Greek, Greek, Greek,
+ Greek, Greek, Greek, Greek, Greek, Greek, Greek, Greek,
+ Greek, Greek, Greek, Greek, Greek, Greek, Greek, Greek,
+ Greek, Greek, Greek, Greek, Greek, Greek, Greek, Greek,
+ Greek, Greek, Greek, Greek, Greek, Greek, Greek, Greek,
+ Greek, Greek, Greek, Greek, Greek, Greek, Greek, Common,
+ Greek, Greek, Greek, Greek, Greek, Greek, Greek, Greek,
+ Greek, Greek, Greek, Greek, Greek, Greek, Greek, Greek,
+ Greek, Greek, Coptic, Coptic, Coptic, Coptic, Coptic, Coptic,
+ Coptic, Coptic, Coptic, Coptic, Coptic, Coptic, Coptic, Coptic,
+ Greek, Greek, Greek, Greek, Greek, Greek, Greek, Greek,
+ Greek, Greek, Greek, Greek, Greek, Greek, Greek, Greek,
+
+ /* U+0480-04ff at offset 768 */
+ Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic, Common,
+ Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic,
+ Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic,
+ Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic,
+ Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic,
+ Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic,
+ Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic,
+ Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic,
+ Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic,
+ Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic,
+ Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic,
+ Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic,
+ Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic,
+ Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic,
+ Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic,
+ Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic,
+
+ /* U+0500-057f at offset 896 */
+ Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic,
+ Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic, Cyrillic,
+ Cyrillic, Cyrillic, Cyrillic, Cyrillic, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Armenian, Armenian, Armenian, Armenian, Armenian, Armenian, Armenian,
+ Armenian, Armenian, Armenian, Armenian, Armenian, Armenian, Armenian, Armenian,
+ Armenian, Armenian, Armenian, Armenian, Armenian, Armenian, Armenian, Armenian,
+ Armenian, Armenian, Armenian, Armenian, Armenian, Armenian, Armenian, Armenian,
+ Armenian, Armenian, Armenian, Armenian, Armenian, Armenian, Armenian, Common,
+ Common, Armenian, Armenian, Armenian, Armenian, Armenian, Armenian, Armenian,
+ Common, Armenian, Armenian, Armenian, Armenian, Armenian, Armenian, Armenian,
+ Armenian, Armenian, Armenian, Armenian, Armenian, Armenian, Armenian, Armenian,
+ Armenian, Armenian, Armenian, Armenian, Armenian, Armenian, Armenian, Armenian,
+ Armenian, Armenian, Armenian, Armenian, Armenian, Armenian, Armenian, Armenian,
+
+ /* U+0580-05ff at offset 1024 */
+ Armenian, Armenian, Armenian, Armenian, Armenian, Armenian, Armenian, Armenian,
+ Common, Common, Armenian, Common, Common, Common, Common, Common,
+ Common, Hebrew, Hebrew, Hebrew, Hebrew, Hebrew, Hebrew, Hebrew,
+ Hebrew, Hebrew, Hebrew, Hebrew, Hebrew, Hebrew, Hebrew, Hebrew,
+ Hebrew, Hebrew, Hebrew, Hebrew, Hebrew, Hebrew, Hebrew, Hebrew,
+ Hebrew, Hebrew, Hebrew, Hebrew, Hebrew, Hebrew, Hebrew, Hebrew,
+ Hebrew, Hebrew, Hebrew, Hebrew, Hebrew, Hebrew, Hebrew, Hebrew,
+ Hebrew, Hebrew, Hebrew, Hebrew, Hebrew, Hebrew, Hebrew, Hebrew,
+ Hebrew, Hebrew, Hebrew, Hebrew, Hebrew, Hebrew, Hebrew, Hebrew,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Hebrew, Hebrew, Hebrew, Hebrew, Hebrew, Hebrew, Hebrew, Hebrew,
+ Hebrew, Hebrew, Hebrew, Hebrew, Hebrew, Hebrew, Hebrew, Hebrew,
+ Hebrew, Hebrew, Hebrew, Hebrew, Hebrew, Hebrew, Hebrew, Hebrew,
+ Hebrew, Hebrew, Hebrew, Common, Common, Common, Common, Common,
+ Hebrew, Hebrew, Hebrew, Hebrew, Hebrew, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+
+ /* U+0600-067f at offset 1152 */
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Arabic, Common, Arabic, Arabic, Arabic,
+ Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Common, Common,
+ Common, Common, Common, Common, Common, Common, Arabic, Common,
+ Common, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
+ Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
+ Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
+ Arabic, Arabic, Arabic, Common, Common, Common, Common, Common,
+ Common, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
+ Arabic, Arabic, Arabic, Inherited, Inherited, Inherited, Inherited, Inherited,
+ Inherited, Inherited, Inherited, Inherited, Inherited, Inherited, Arabic, Arabic,
+ Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
+ Inherited, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
+ Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
+
+ /* U+0680-06ff at offset 1280 */
+ Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
+ Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
+ Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
+ Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
+ Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
+ Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
+ Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
+ Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
+ Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
+ Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
+ Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
+ Arabic, Arabic, Arabic, Arabic, Arabic, Common, Arabic, Arabic,
+ Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
+ Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
+ Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
+ Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
+
+ /* U+0700-077f at offset 1408 */
+ Syriac, Syriac, Syriac, Syriac, Syriac, Syriac, Syriac, Syriac,
+ Syriac, Syriac, Syriac, Syriac, Syriac, Syriac, Common, Syriac,
+ Syriac, Syriac, Syriac, Syriac, Syriac, Syriac, Syriac, Syriac,
+ Syriac, Syriac, Syriac, Syriac, Syriac, Syriac, Syriac, Syriac,
+ Syriac, Syriac, Syriac, Syriac, Syriac, Syriac, Syriac, Syriac,
+ Syriac, Syriac, Syriac, Syriac, Syriac, Syriac, Syriac, Syriac,
+ Syriac, Syriac, Syriac, Syriac, Syriac, Syriac, Syriac, Syriac,
+ Syriac, Syriac, Syriac, Syriac, Syriac, Syriac, Syriac, Syriac,
+ Syriac, Syriac, Syriac, Syriac, Syriac, Syriac, Syriac, Syriac,
+ Syriac, Syriac, Syriac, Common, Common, Syriac, Syriac, Syriac,
+ Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
+ Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
+ Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
+ Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+
+ /* U+0780-07ff at offset 1536 */
+ Thaana, Thaana, Thaana, Thaana, Thaana, Thaana, Thaana, Thaana,
+ Thaana, Thaana, Thaana, Thaana, Thaana, Thaana, Thaana, Thaana,
+ Thaana, Thaana, Thaana, Thaana, Thaana, Thaana, Thaana, Thaana,
+ Thaana, Thaana, Thaana, Thaana, Thaana, Thaana, Thaana, Thaana,
+ Thaana, Thaana, Thaana, Thaana, Thaana, Thaana, Thaana, Thaana,
+ Thaana, Thaana, Thaana, Thaana, Thaana, Thaana, Thaana, Thaana,
+ Thaana, Thaana, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Nko, Nko, Nko, Nko, Nko, Nko, Nko, Nko,
+ Nko, Nko, Nko, Nko, Nko, Nko, Nko, Nko,
+ Nko, Nko, Nko, Nko, Nko, Nko, Nko, Nko,
+ Nko, Nko, Nko, Nko, Nko, Nko, Nko, Nko,
+ Nko, Nko, Nko, Nko, Nko, Nko, Nko, Nko,
+ Nko, Nko, Nko, Nko, Nko, Nko, Nko, Nko,
+ Nko, Nko, Nko, Nko, Nko, Nko, Nko, Nko,
+ Nko, Nko, Nko, Common, Common, Common, Common, Common,
+
+ /* U+0900-097f at offset 1664 */
+ Common, Devanagari, Devanagari, Devanagari, Devanagari, Devanagari, Devanagari, Devanagari,
+ Devanagari, Devanagari, Devanagari, Devanagari, Devanagari, Devanagari, Devanagari, Devanagari,
+ Devanagari, Devanagari, Devanagari, Devanagari, Devanagari, Devanagari, Devanagari, Devanagari,
+ Devanagari, Devanagari, Devanagari, Devanagari, Devanagari, Devanagari, Devanagari, Devanagari,
+ Devanagari, Devanagari, Devanagari, Devanagari, Devanagari, Devanagari, Devanagari, Devanagari,
+ Devanagari, Devanagari, Devanagari, Devanagari, Devanagari, Devanagari, Devanagari, Devanagari,
+ Devanagari, Devanagari, Devanagari, Devanagari, Devanagari, Devanagari, Devanagari, Devanagari,
+ Devanagari, Devanagari, Common, Common, Devanagari, Devanagari, Devanagari, Devanagari,
+ Devanagari, Devanagari, Devanagari, Devanagari, Devanagari, Devanagari, Devanagari, Devanagari,
+ Devanagari, Devanagari, Devanagari, Devanagari, Devanagari, Devanagari, Common, Common,
+ Devanagari, Devanagari, Devanagari, Devanagari, Devanagari, Common, Common, Common,
+ Devanagari, Devanagari, Devanagari, Devanagari, Devanagari, Devanagari, Devanagari, Devanagari,
+ Devanagari, Devanagari, Devanagari, Devanagari, Common, Common, Devanagari, Devanagari,
+ Devanagari, Devanagari, Devanagari, Devanagari, Devanagari, Devanagari, Devanagari, Devanagari,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Devanagari, Devanagari, Devanagari, Devanagari, Devanagari,
+
+ /* U+0980-09ff at offset 1792 */
+ Common, Bengali, Bengali, Bengali, Common, Bengali, Bengali, Bengali,
+ Bengali, Bengali, Bengali, Bengali, Bengali, Common, Common, Bengali,
+ Bengali, Common, Common, Bengali, Bengali, Bengali, Bengali, Bengali,
+ Bengali, Bengali, Bengali, Bengali, Bengali, Bengali, Bengali, Bengali,
+ Bengali, Bengali, Bengali, Bengali, Bengali, Bengali, Bengali, Bengali,
+ Bengali, Common, Bengali, Bengali, Bengali, Bengali, Bengali, Bengali,
+ Bengali, Common, Bengali, Common, Common, Common, Bengali, Bengali,
+ Bengali, Bengali, Common, Common, Bengali, Bengali, Bengali, Bengali,
+ Bengali, Bengali, Bengali, Bengali, Bengali, Common, Common, Bengali,
+ Bengali, Common, Common, Bengali, Bengali, Bengali, Bengali, Common,
+ Common, Common, Common, Common, Common, Common, Common, Bengali,
+ Common, Common, Common, Common, Bengali, Bengali, Common, Bengali,
+ Bengali, Bengali, Bengali, Bengali, Common, Common, Bengali, Bengali,
+ Bengali, Bengali, Bengali, Bengali, Bengali, Bengali, Bengali, Bengali,
+ Bengali, Bengali, Bengali, Bengali, Bengali, Bengali, Bengali, Bengali,
+ Bengali, Bengali, Bengali, Common, Common, Common, Common, Common,
+
+ /* U+0a00-0a7f at offset 1920 */
+ Common, Gurmukhi, Gurmukhi, Gurmukhi, Common, Gurmukhi, Gurmukhi, Gurmukhi,
+ Gurmukhi, Gurmukhi, Gurmukhi, Common, Common, Common, Common, Gurmukhi,
+ Gurmukhi, Common, Common, Gurmukhi, Gurmukhi, Gurmukhi, Gurmukhi, Gurmukhi,
+ Gurmukhi, Gurmukhi, Gurmukhi, Gurmukhi, Gurmukhi, Gurmukhi, Gurmukhi, Gurmukhi,
+ Gurmukhi, Gurmukhi, Gurmukhi, Gurmukhi, Gurmukhi, Gurmukhi, Gurmukhi, Gurmukhi,
+ Gurmukhi, Common, Gurmukhi, Gurmukhi, Gurmukhi, Gurmukhi, Gurmukhi, Gurmukhi,
+ Gurmukhi, Common, Gurmukhi, Gurmukhi, Common, Gurmukhi, Gurmukhi, Common,
+ Gurmukhi, Gurmukhi, Common, Common, Gurmukhi, Common, Gurmukhi, Gurmukhi,
+ Gurmukhi, Gurmukhi, Gurmukhi, Common, Common, Common, Common, Gurmukhi,
+ Gurmukhi, Common, Common, Gurmukhi, Gurmukhi, Gurmukhi, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Gurmukhi, Gurmukhi, Gurmukhi, Gurmukhi, Common, Gurmukhi, Common,
+ Common, Common, Common, Common, Common, Common, Gurmukhi, Gurmukhi,
+ Gurmukhi, Gurmukhi, Gurmukhi, Gurmukhi, Gurmukhi, Gurmukhi, Gurmukhi, Gurmukhi,
+ Gurmukhi, Gurmukhi, Gurmukhi, Gurmukhi, Gurmukhi, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+
+ /* U+0a80-0aff at offset 2048 */
+ Common, Gujarati, Gujarati, Gujarati, Common, Gujarati, Gujarati, Gujarati,
+ Gujarati, Gujarati, Gujarati, Gujarati, Gujarati, Gujarati, Common, Gujarati,
+ Gujarati, Gujarati, Common, Gujarati, Gujarati, Gujarati, Gujarati, Gujarati,
+ Gujarati, Gujarati, Gujarati, Gujarati, Gujarati, Gujarati, Gujarati, Gujarati,
+ Gujarati, Gujarati, Gujarati, Gujarati, Gujarati, Gujarati, Gujarati, Gujarati,
+ Gujarati, Common, Gujarati, Gujarati, Gujarati, Gujarati, Gujarati, Gujarati,
+ Gujarati, Common, Gujarati, Gujarati, Common, Gujarati, Gujarati, Gujarati,
+ Gujarati, Gujarati, Common, Common, Gujarati, Gujarati, Gujarati, Gujarati,
+ Gujarati, Gujarati, Gujarati, Gujarati, Gujarati, Gujarati, Common, Gujarati,
+ Gujarati, Gujarati, Common, Gujarati, Gujarati, Gujarati, Common, Common,
+ Gujarati, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Gujarati, Gujarati, Gujarati, Gujarati, Common, Common, Gujarati, Gujarati,
+ Gujarati, Gujarati, Gujarati, Gujarati, Gujarati, Gujarati, Gujarati, Gujarati,
+ Common, Gujarati, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+
+ /* U+0b00-0b7f at offset 2176 */
+ Common, Oriya, Oriya, Oriya, Common, Oriya, Oriya, Oriya,
+ Oriya, Oriya, Oriya, Oriya, Oriya, Common, Common, Oriya,
+ Oriya, Common, Common, Oriya, Oriya, Oriya, Oriya, Oriya,
+ Oriya, Oriya, Oriya, Oriya, Oriya, Oriya, Oriya, Oriya,
+ Oriya, Oriya, Oriya, Oriya, Oriya, Oriya, Oriya, Oriya,
+ Oriya, Common, Oriya, Oriya, Oriya, Oriya, Oriya, Oriya,
+ Oriya, Common, Oriya, Oriya, Common, Oriya, Oriya, Oriya,
+ Oriya, Oriya, Common, Common, Oriya, Oriya, Oriya, Oriya,
+ Oriya, Oriya, Oriya, Oriya, Common, Common, Common, Oriya,
+ Oriya, Common, Common, Oriya, Oriya, Oriya, Common, Common,
+ Common, Common, Common, Common, Common, Common, Oriya, Oriya,
+ Common, Common, Common, Common, Oriya, Oriya, Common, Oriya,
+ Oriya, Oriya, Common, Common, Common, Common, Oriya, Oriya,
+ Oriya, Oriya, Oriya, Oriya, Oriya, Oriya, Oriya, Oriya,
+ Oriya, Oriya, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+
+ /* U+0b80-0bff at offset 2304 */
+ Common, Common, Tamil, Tamil, Common, Tamil, Tamil, Tamil,
+ Tamil, Tamil, Tamil, Common, Common, Common, Tamil, Tamil,
+ Tamil, Common, Tamil, Tamil, Tamil, Tamil, Common, Common,
+ Common, Tamil, Tamil, Common, Tamil, Common, Tamil, Tamil,
+ Common, Common, Common, Tamil, Tamil, Common, Common, Common,
+ Tamil, Tamil, Tamil, Common, Common, Common, Tamil, Tamil,
+ Tamil, Tamil, Tamil, Tamil, Tamil, Tamil, Tamil, Tamil,
+ Tamil, Tamil, Common, Common, Common, Common, Tamil, Tamil,
+ Tamil, Tamil, Tamil, Common, Common, Common, Tamil, Tamil,
+ Tamil, Common, Tamil, Tamil, Tamil, Tamil, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Tamil,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Tamil, Tamil,
+ Tamil, Tamil, Tamil, Tamil, Tamil, Tamil, Tamil, Tamil,
+ Tamil, Tamil, Tamil, Tamil, Tamil, Tamil, Tamil, Tamil,
+ Tamil, Tamil, Tamil, Common, Common, Common, Common, Common,
+
+ /* U+0c00-0c7f at offset 2432 */
+ Common, Telugu, Telugu, Telugu, Common, Telugu, Telugu, Telugu,
+ Telugu, Telugu, Telugu, Telugu, Telugu, Common, Telugu, Telugu,
+ Telugu, Common, Telugu, Telugu, Telugu, Telugu, Telugu, Telugu,
+ Telugu, Telugu, Telugu, Telugu, Telugu, Telugu, Telugu, Telugu,
+ Telugu, Telugu, Telugu, Telugu, Telugu, Telugu, Telugu, Telugu,
+ Telugu, Common, Telugu, Telugu, Telugu, Telugu, Telugu, Telugu,
+ Telugu, Telugu, Telugu, Telugu, Common, Telugu, Telugu, Telugu,
+ Telugu, Telugu, Common, Common, Common, Common, Telugu, Telugu,
+ Telugu, Telugu, Telugu, Telugu, Telugu, Common, Telugu, Telugu,
+ Telugu, Common, Telugu, Telugu, Telugu, Telugu, Common, Common,
+ Common, Common, Common, Common, Common, Telugu, Telugu, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Telugu, Telugu, Common, Common, Common, Common, Telugu, Telugu,
+ Telugu, Telugu, Telugu, Telugu, Telugu, Telugu, Telugu, Telugu,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+
+ /* U+0c80-0cff at offset 2560 */
+ Common, Common, Kannada, Kannada, Common, Kannada, Kannada, Kannada,
+ Kannada, Kannada, Kannada, Kannada, Kannada, Common, Kannada, Kannada,
+ Kannada, Common, Kannada, Kannada, Kannada, Kannada, Kannada, Kannada,
+ Kannada, Kannada, Kannada, Kannada, Kannada, Kannada, Kannada, Kannada,
+ Kannada, Kannada, Kannada, Kannada, Kannada, Kannada, Kannada, Kannada,
+ Kannada, Common, Kannada, Kannada, Kannada, Kannada, Kannada, Kannada,
+ Kannada, Kannada, Kannada, Kannada, Common, Kannada, Kannada, Kannada,
+ Kannada, Kannada, Common, Common, Kannada, Kannada, Kannada, Kannada,
+ Kannada, Kannada, Kannada, Kannada, Kannada, Common, Kannada, Kannada,
+ Kannada, Common, Kannada, Kannada, Kannada, Kannada, Common, Common,
+ Common, Common, Common, Common, Common, Kannada, Kannada, Common,
+ Common, Common, Common, Common, Common, Common, Kannada, Common,
+ Kannada, Kannada, Kannada, Kannada, Common, Common, Kannada, Kannada,
+ Kannada, Kannada, Kannada, Kannada, Kannada, Kannada, Kannada, Kannada,
+ Common, Kannada, Kannada, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+
+ /* U+0d00-0d7f at offset 2688 */
+ Common, Common, Malayalam, Malayalam, Common, Malayalam, Malayalam, Malayalam,
+ Malayalam, Malayalam, Malayalam, Malayalam, Malayalam, Common, Malayalam, Malayalam,
+ Malayalam, Common, Malayalam, Malayalam, Malayalam, Malayalam, Malayalam, Malayalam,
+ Malayalam, Malayalam, Malayalam, Malayalam, Malayalam, Malayalam, Malayalam, Malayalam,
+ Malayalam, Malayalam, Malayalam, Malayalam, Malayalam, Malayalam, Malayalam, Malayalam,
+ Malayalam, Common, Malayalam, Malayalam, Malayalam, Malayalam, Malayalam, Malayalam,
+ Malayalam, Malayalam, Malayalam, Malayalam, Malayalam, Malayalam, Malayalam, Malayalam,
+ Malayalam, Malayalam, Common, Common, Common, Common, Malayalam, Malayalam,
+ Malayalam, Malayalam, Malayalam, Malayalam, Common, Common, Malayalam, Malayalam,
+ Malayalam, Common, Malayalam, Malayalam, Malayalam, Malayalam, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Malayalam,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Malayalam, Malayalam, Common, Common, Common, Common, Malayalam, Malayalam,
+ Malayalam, Malayalam, Malayalam, Malayalam, Malayalam, Malayalam, Malayalam, Malayalam,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+
+ /* U+0d80-0dff at offset 2816 */
+ Common, Common, Sinhala, Sinhala, Common, Sinhala, Sinhala, Sinhala,
+ Sinhala, Sinhala, Sinhala, Sinhala, Sinhala, Sinhala, Sinhala, Sinhala,
+ Sinhala, Sinhala, Sinhala, Sinhala, Sinhala, Sinhala, Sinhala, Common,
+ Common, Common, Sinhala, Sinhala, Sinhala, Sinhala, Sinhala, Sinhala,
+ Sinhala, Sinhala, Sinhala, Sinhala, Sinhala, Sinhala, Sinhala, Sinhala,
+ Sinhala, Sinhala, Sinhala, Sinhala, Sinhala, Sinhala, Sinhala, Sinhala,
+ Sinhala, Sinhala, Common, Sinhala, Sinhala, Sinhala, Sinhala, Sinhala,
+ Sinhala, Sinhala, Sinhala, Sinhala, Common, Sinhala, Common, Common,
+ Sinhala, Sinhala, Sinhala, Sinhala, Sinhala, Sinhala, Sinhala, Common,
+ Common, Common, Sinhala, Common, Common, Common, Common, Sinhala,
+ Sinhala, Sinhala, Sinhala, Sinhala, Sinhala, Common, Sinhala, Common,
+ Sinhala, Sinhala, Sinhala, Sinhala, Sinhala, Sinhala, Sinhala, Sinhala,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Sinhala, Sinhala, Sinhala, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+
+ /* U+0e00-0e7f at offset 2944 */
+ Common, Thai, Thai, Thai, Thai, Thai, Thai, Thai,
+ Thai, Thai, Thai, Thai, Thai, Thai, Thai, Thai,
+ Thai, Thai, Thai, Thai, Thai, Thai, Thai, Thai,
+ Thai, Thai, Thai, Thai, Thai, Thai, Thai, Thai,
+ Thai, Thai, Thai, Thai, Thai, Thai, Thai, Thai,
+ Thai, Thai, Thai, Thai, Thai, Thai, Thai, Thai,
+ Thai, Thai, Thai, Thai, Thai, Thai, Thai, Thai,
+ Thai, Thai, Thai, Common, Common, Common, Common, Common,
+ Thai, Thai, Thai, Thai, Thai, Thai, Thai, Thai,
+ Thai, Thai, Thai, Thai, Thai, Thai, Thai, Thai,
+ Thai, Thai, Thai, Thai, Thai, Thai, Thai, Thai,
+ Thai, Thai, Thai, Thai, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+
+ /* U+0e80-0eff at offset 3072 */
+ Common, Lao, Lao, Common, Lao, Common, Common, Lao,
+ Lao, Common, Lao, Common, Common, Lao, Common, Common,
+ Common, Common, Common, Common, Lao, Lao, Lao, Lao,
+ Common, Lao, Lao, Lao, Lao, Lao, Lao, Lao,
+ Common, Lao, Lao, Lao, Common, Lao, Common, Lao,
+ Common, Common, Lao, Lao, Common, Lao, Lao, Lao,
+ Lao, Lao, Lao, Lao, Lao, Lao, Lao, Lao,
+ Lao, Lao, Common, Lao, Lao, Lao, Common, Common,
+ Lao, Lao, Lao, Lao, Lao, Common, Lao, Common,
+ Lao, Lao, Lao, Lao, Lao, Lao, Common, Common,
+ Lao, Lao, Lao, Lao, Lao, Lao, Lao, Lao,
+ Lao, Lao, Common, Common, Lao, Lao, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+
+ /* U+0f00-0f7f at offset 3200 */
+ Tibetan, Tibetan, Tibetan, Tibetan, Tibetan, Tibetan, Tibetan, Tibetan,
+ Tibetan, Tibetan, Tibetan, Tibetan, Tibetan, Tibetan, Tibetan, Tibetan,
+ Tibetan, Tibetan, Tibetan, Tibetan, Tibetan, Tibetan, Tibetan, Tibetan,
+ Tibetan, Tibetan, Tibetan, Tibetan, Tibetan, Tibetan, Tibetan, Tibetan,
+ Tibetan, Tibetan, Tibetan, Tibetan, Tibetan, Tibetan, Tibetan, Tibetan,
+ Tibetan, Tibetan, Tibetan, Tibetan, Tibetan, Tibetan, Tibetan, Tibetan,
+ Tibetan, Tibetan, Tibetan, Tibetan, Tibetan, Tibetan, Tibetan, Tibetan,
+ Tibetan, Tibetan, Tibetan, Tibetan, Tibetan, Tibetan, Tibetan, Tibetan,
+ Tibetan, Tibetan, Tibetan, Tibetan, Tibetan, Tibetan, Tibetan, Tibetan,
+ Common, Tibetan, Tibetan, Tibetan, Tibetan, Tibetan, Tibetan, Tibetan,
+ Tibetan, Tibetan, Tibetan, Tibetan, Tibetan, Tibetan, Tibetan, Tibetan,
+ Tibetan, Tibetan, Tibetan, Tibetan, Tibetan, Tibetan, Tibetan, Tibetan,
+ Tibetan, Tibetan, Tibetan, Tibetan, Tibetan, Tibetan, Tibetan, Tibetan,
+ Tibetan, Tibetan, Tibetan, Common, Common, Common, Common, Common,
+ Common, Tibetan, Tibetan, Tibetan, Tibetan, Tibetan, Tibetan, Tibetan,
+ Tibetan, Tibetan, Tibetan, Tibetan, Tibetan, Tibetan, Tibetan, Tibetan,
+
+ /* U+0f80-0fff at offset 3328 */
+ Tibetan, Tibetan, Tibetan, Tibetan, Tibetan, Tibetan, Tibetan, Tibetan,
+ Tibetan, Tibetan, Tibetan, Tibetan, Common, Common, Common, Common,
+ Tibetan, Tibetan, Tibetan, Tibetan, Tibetan, Tibetan, Tibetan, Tibetan,
+ Common, Tibetan, Tibetan, Tibetan, Tibetan, Tibetan, Tibetan, Tibetan,
+ Tibetan, Tibetan, Tibetan, Tibetan, Tibetan, Tibetan, Tibetan, Tibetan,
+ Tibetan, Tibetan, Tibetan, Tibetan, Tibetan, Tibetan, Tibetan, Tibetan,
+ Tibetan, Tibetan, Tibetan, Tibetan, Tibetan, Tibetan, Tibetan, Tibetan,
+ Tibetan, Tibetan, Tibetan, Tibetan, Tibetan, Common, Tibetan, Tibetan,
+ Tibetan, Tibetan, Tibetan, Tibetan, Tibetan, Tibetan, Tibetan, Tibetan,
+ Tibetan, Tibetan, Tibetan, Tibetan, Tibetan, Common, Common, Tibetan,
+ Tibetan, Tibetan, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+
+ /* U+1000-107f at offset 3456 */
+ Myanmar, Myanmar, Myanmar, Myanmar, Myanmar, Myanmar, Myanmar, Myanmar,
+ Myanmar, Myanmar, Myanmar, Myanmar, Myanmar, Myanmar, Myanmar, Myanmar,
+ Myanmar, Myanmar, Myanmar, Myanmar, Myanmar, Myanmar, Myanmar, Myanmar,
+ Myanmar, Myanmar, Myanmar, Myanmar, Myanmar, Myanmar, Myanmar, Myanmar,
+ Myanmar, Myanmar, Common, Myanmar, Myanmar, Myanmar, Myanmar, Myanmar,
+ Common, Myanmar, Myanmar, Common, Myanmar, Myanmar, Myanmar, Myanmar,
+ Myanmar, Myanmar, Myanmar, Common, Common, Common, Myanmar, Myanmar,
+ Myanmar, Myanmar, Common, Common, Common, Common, Common, Common,
+ Myanmar, Myanmar, Myanmar, Myanmar, Myanmar, Myanmar, Myanmar, Myanmar,
+ Myanmar, Myanmar, Myanmar, Myanmar, Myanmar, Myanmar, Myanmar, Myanmar,
+ Myanmar, Myanmar, Myanmar, Myanmar, Myanmar, Myanmar, Myanmar, Myanmar,
+ Myanmar, Myanmar, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+
+ /* U+1080-10ff at offset 3584 */
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Georgian, Georgian, Georgian, Georgian, Georgian, Georgian, Georgian, Georgian,
+ Georgian, Georgian, Georgian, Georgian, Georgian, Georgian, Georgian, Georgian,
+ Georgian, Georgian, Georgian, Georgian, Georgian, Georgian, Georgian, Georgian,
+ Georgian, Georgian, Georgian, Georgian, Georgian, Georgian, Georgian, Georgian,
+ Georgian, Georgian, Georgian, Georgian, Georgian, Georgian, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Georgian, Georgian, Georgian, Georgian, Georgian, Georgian, Georgian, Georgian,
+ Georgian, Georgian, Georgian, Georgian, Georgian, Georgian, Georgian, Georgian,
+ Georgian, Georgian, Georgian, Georgian, Georgian, Georgian, Georgian, Georgian,
+ Georgian, Georgian, Georgian, Georgian, Georgian, Georgian, Georgian, Georgian,
+ Georgian, Georgian, Georgian, Georgian, Georgian, Georgian, Georgian, Georgian,
+ Georgian, Georgian, Georgian, Common, Georgian, Common, Common, Common,
+
+ /* U+1100-117f at offset 3712 */
+ Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul,
+ Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul,
+ Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul,
+ Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul,
+ Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul,
+ Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul,
+ Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul,
+ Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul,
+ Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul,
+ Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul,
+ Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul,
+ Hangul, Hangul, Common, Common, Common, Common, Common, Hangul,
+ Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul,
+ Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul,
+ Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul,
+ Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul,
+
+ /* U+1180-11ff at offset 3840 */
+ Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul,
+ Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul,
+ Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul,
+ Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul,
+ Hangul, Hangul, Hangul, Common, Common, Common, Common, Common,
+ Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul,
+ Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul,
+ Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul,
+ Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul,
+ Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul,
+ Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul,
+ Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul,
+ Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul,
+ Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul,
+ Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul,
+ Hangul, Hangul, Common, Common, Common, Common, Common, Common,
+
+ /* U+1680-16ff at offset 3968 */
+ Ogham, Ogham, Ogham, Ogham, Ogham, Ogham, Ogham, Ogham,
+ Ogham, Ogham, Ogham, Ogham, Ogham, Ogham, Ogham, Ogham,
+ Ogham, Ogham, Ogham, Ogham, Ogham, Ogham, Ogham, Ogham,
+ Ogham, Ogham, Ogham, Ogham, Ogham, Common, Common, Common,
+ Runic, Runic, Runic, Runic, Runic, Runic, Runic, Runic,
+ Runic, Runic, Runic, Runic, Runic, Runic, Runic, Runic,
+ Runic, Runic, Runic, Runic, Runic, Runic, Runic, Runic,
+ Runic, Runic, Runic, Runic, Runic, Runic, Runic, Runic,
+ Runic, Runic, Runic, Runic, Runic, Runic, Runic, Runic,
+ Runic, Runic, Runic, Runic, Runic, Runic, Runic, Runic,
+ Runic, Runic, Runic, Runic, Runic, Runic, Runic, Runic,
+ Runic, Runic, Runic, Runic, Runic, Runic, Runic, Runic,
+ Runic, Runic, Runic, Runic, Runic, Runic, Runic, Runic,
+ Runic, Runic, Runic, Common, Common, Common, Runic, Runic,
+ Runic, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+
+ /* U+1780-17ff at offset 4096 */
+ Khmer, Khmer, Khmer, Khmer, Khmer, Khmer, Khmer, Khmer,
+ Khmer, Khmer, Khmer, Khmer, Khmer, Khmer, Khmer, Khmer,
+ Khmer, Khmer, Khmer, Khmer, Khmer, Khmer, Khmer, Khmer,
+ Khmer, Khmer, Khmer, Khmer, Khmer, Khmer, Khmer, Khmer,
+ Khmer, Khmer, Khmer, Khmer, Khmer, Khmer, Khmer, Khmer,
+ Khmer, Khmer, Khmer, Khmer, Khmer, Khmer, Khmer, Khmer,
+ Khmer, Khmer, Khmer, Khmer, Khmer, Khmer, Khmer, Khmer,
+ Khmer, Khmer, Khmer, Khmer, Khmer, Khmer, Khmer, Khmer,
+ Khmer, Khmer, Khmer, Khmer, Khmer, Khmer, Khmer, Khmer,
+ Khmer, Khmer, Khmer, Khmer, Khmer, Khmer, Khmer, Khmer,
+ Khmer, Khmer, Khmer, Khmer, Khmer, Khmer, Khmer, Khmer,
+ Khmer, Khmer, Khmer, Khmer, Khmer, Khmer, Common, Common,
+ Khmer, Khmer, Khmer, Khmer, Khmer, Khmer, Khmer, Khmer,
+ Khmer, Khmer, Common, Common, Common, Common, Common, Common,
+ Khmer, Khmer, Khmer, Khmer, Khmer, Khmer, Khmer, Khmer,
+ Khmer, Khmer, Common, Common, Common, Common, Common, Common,
+
+ /* U+1980-19ff at offset 4224 */
+ NewTaiLue, NewTaiLue, NewTaiLue, NewTaiLue, NewTaiLue, NewTaiLue, NewTaiLue, NewTaiLue,
+ NewTaiLue, NewTaiLue, NewTaiLue, NewTaiLue, NewTaiLue, NewTaiLue, NewTaiLue, NewTaiLue,
+ NewTaiLue, NewTaiLue, NewTaiLue, NewTaiLue, NewTaiLue, NewTaiLue, NewTaiLue, NewTaiLue,
+ NewTaiLue, NewTaiLue, NewTaiLue, NewTaiLue, NewTaiLue, NewTaiLue, NewTaiLue, NewTaiLue,
+ NewTaiLue, NewTaiLue, NewTaiLue, NewTaiLue, NewTaiLue, NewTaiLue, NewTaiLue, NewTaiLue,
+ NewTaiLue, NewTaiLue, Common, Common, Common, Common, Common, Common,
+ NewTaiLue, NewTaiLue, NewTaiLue, NewTaiLue, NewTaiLue, NewTaiLue, NewTaiLue, NewTaiLue,
+ NewTaiLue, NewTaiLue, NewTaiLue, NewTaiLue, NewTaiLue, NewTaiLue, NewTaiLue, NewTaiLue,
+ NewTaiLue, NewTaiLue, NewTaiLue, NewTaiLue, NewTaiLue, NewTaiLue, NewTaiLue, NewTaiLue,
+ NewTaiLue, NewTaiLue, Common, Common, Common, Common, Common, Common,
+ NewTaiLue, NewTaiLue, NewTaiLue, NewTaiLue, NewTaiLue, NewTaiLue, NewTaiLue, NewTaiLue,
+ NewTaiLue, NewTaiLue, Common, Common, Common, Common, NewTaiLue, NewTaiLue,
+ Khmer, Khmer, Khmer, Khmer, Khmer, Khmer, Khmer, Khmer,
+ Khmer, Khmer, Khmer, Khmer, Khmer, Khmer, Khmer, Khmer,
+ Khmer, Khmer, Khmer, Khmer, Khmer, Khmer, Khmer, Khmer,
+ Khmer, Khmer, Khmer, Khmer, Khmer, Khmer, Khmer, Khmer,
+
+ /* U+1d00-1d7f at offset 4352 */
+ Latin, Latin, Latin, Latin, Latin, Latin, Latin, Latin,
+ Latin, Latin, Latin, Latin, Latin, Latin, Latin, Latin,
+ Latin, Latin, Latin, Latin, Latin, Latin, Latin, Latin,
+ Latin, Latin, Latin, Latin, Latin, Latin, Latin, Latin,
+ Latin, Latin, Latin, Latin, Latin, Latin, Greek, Greek,
+ Greek, Greek, Greek, Cyrillic, Latin, Latin, Latin, Latin,
+ Latin, Latin, Latin, Latin, Latin, Latin, Latin, Latin,
+ Latin, Latin, Latin, Latin, Latin, Latin, Latin, Latin,
+ Latin, Latin, Latin, Latin, Latin, Latin, Latin, Latin,
+ Latin, Latin, Latin, Latin, Latin, Latin, Latin, Latin,
+ Latin, Latin, Latin, Latin, Latin, Latin, Latin, Latin,
+ Latin, Latin, Latin, Latin, Latin, Greek, Greek, Greek,
+ Greek, Greek, Latin, Latin, Latin, Latin, Greek, Greek,
+ Greek, Greek, Greek, Latin, Latin, Latin, Latin, Latin,
+ Latin, Latin, Latin, Latin, Latin, Latin, Latin, Latin,
+ Cyrillic, Latin, Latin, Latin, Latin, Latin, Latin, Latin,
+
+ /* U+1d80-1dff at offset 4480 */
+ Latin, Latin, Latin, Latin, Latin, Latin, Latin, Latin,
+ Latin, Latin, Latin, Latin, Latin, Latin, Latin, Latin,
+ Latin, Latin, Latin, Latin, Latin, Latin, Latin, Latin,
+ Latin, Latin, Latin, Latin, Latin, Latin, Latin, Latin,
+ Latin, Latin, Latin, Latin, Latin, Latin, Latin, Latin,
+ Latin, Latin, Latin, Latin, Latin, Latin, Latin, Latin,
+ Latin, Latin, Latin, Latin, Latin, Latin, Latin, Latin,
+ Latin, Latin, Latin, Latin, Latin, Latin, Latin, Greek,
+ Inherited, Inherited, Inherited, Inherited, Inherited, Inherited, Inherited, Inherited,
+ Inherited, Inherited, Inherited, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Inherited, Inherited,
+
+ /* U+1f00-1f7f at offset 4608 */
+ Greek, Greek, Greek, Greek, Greek, Greek, Greek, Greek,
+ Greek, Greek, Greek, Greek, Greek, Greek, Greek, Greek,
+ Greek, Greek, Greek, Greek, Greek, Greek, Common, Common,
+ Greek, Greek, Greek, Greek, Greek, Greek, Common, Common,
+ Greek, Greek, Greek, Greek, Greek, Greek, Greek, Greek,
+ Greek, Greek, Greek, Greek, Greek, Greek, Greek, Greek,
+ Greek, Greek, Greek, Greek, Greek, Greek, Greek, Greek,
+ Greek, Greek, Greek, Greek, Greek, Greek, Greek, Greek,
+ Greek, Greek, Greek, Greek, Greek, Greek, Common, Common,
+ Greek, Greek, Greek, Greek, Greek, Greek, Common, Common,
+ Greek, Greek, Greek, Greek, Greek, Greek, Greek, Greek,
+ Common, Greek, Common, Greek, Common, Greek, Common, Greek,
+ Greek, Greek, Greek, Greek, Greek, Greek, Greek, Greek,
+ Greek, Greek, Greek, Greek, Greek, Greek, Greek, Greek,
+ Greek, Greek, Greek, Greek, Greek, Greek, Greek, Greek,
+ Greek, Greek, Greek, Greek, Greek, Greek, Common, Common,
+
+ /* U+1f80-1fff at offset 4736 */
+ Greek, Greek, Greek, Greek, Greek, Greek, Greek, Greek,
+ Greek, Greek, Greek, Greek, Greek, Greek, Greek, Greek,
+ Greek, Greek, Greek, Greek, Greek, Greek, Greek, Greek,
+ Greek, Greek, Greek, Greek, Greek, Greek, Greek, Greek,
+ Greek, Greek, Greek, Greek, Greek, Greek, Greek, Greek,
+ Greek, Greek, Greek, Greek, Greek, Greek, Greek, Greek,
+ Greek, Greek, Greek, Greek, Greek, Common, Greek, Greek,
+ Greek, Greek, Greek, Greek, Greek, Greek, Greek, Greek,
+ Greek, Greek, Greek, Greek, Greek, Common, Greek, Greek,
+ Greek, Greek, Greek, Greek, Greek, Greek, Greek, Greek,
+ Greek, Greek, Greek, Greek, Common, Common, Greek, Greek,
+ Greek, Greek, Greek, Greek, Common, Greek, Greek, Greek,
+ Greek, Greek, Greek, Greek, Greek, Greek, Greek, Greek,
+ Greek, Greek, Greek, Greek, Greek, Greek, Greek, Greek,
+ Common, Common, Greek, Greek, Greek, Common, Greek, Greek,
+ Greek, Greek, Greek, Greek, Greek, Greek, Greek, Common,
+
+ /* U+2000-207f at offset 4864 */
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Inherited, Inherited, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Latin, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Latin,
+
+ /* U+2080-20ff at offset 4992 */
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Latin, Latin, Latin, Latin, Latin, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Inherited, Inherited, Inherited, Inherited, Inherited, Inherited, Inherited, Inherited,
+ Inherited, Inherited, Inherited, Inherited, Inherited, Inherited, Inherited, Inherited,
+ Inherited, Inherited, Inherited, Inherited, Inherited, Inherited, Inherited, Inherited,
+ Inherited, Inherited, Inherited, Inherited, Inherited, Inherited, Inherited, Inherited,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+
+ /* U+2100-217f at offset 5120 */
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Greek, Common,
+ Common, Common, Latin, Latin, Common, Common, Common, Common,
+ Common, Common, Latin, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Latin, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+
+ /* U+2d00-2d7f at offset 5248 */
+ Georgian, Georgian, Georgian, Georgian, Georgian, Georgian, Georgian, Georgian,
+ Georgian, Georgian, Georgian, Georgian, Georgian, Georgian, Georgian, Georgian,
+ Georgian, Georgian, Georgian, Georgian, Georgian, Georgian, Georgian, Georgian,
+ Georgian, Georgian, Georgian, Georgian, Georgian, Georgian, Georgian, Georgian,
+ Georgian, Georgian, Georgian, Georgian, Georgian, Georgian, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Tifinagh, Tifinagh, Tifinagh, Tifinagh, Tifinagh, Tifinagh, Tifinagh, Tifinagh,
+ Tifinagh, Tifinagh, Tifinagh, Tifinagh, Tifinagh, Tifinagh, Tifinagh, Tifinagh,
+ Tifinagh, Tifinagh, Tifinagh, Tifinagh, Tifinagh, Tifinagh, Tifinagh, Tifinagh,
+ Tifinagh, Tifinagh, Tifinagh, Tifinagh, Tifinagh, Tifinagh, Tifinagh, Tifinagh,
+ Tifinagh, Tifinagh, Tifinagh, Tifinagh, Tifinagh, Tifinagh, Tifinagh, Tifinagh,
+ Tifinagh, Tifinagh, Tifinagh, Tifinagh, Tifinagh, Tifinagh, Tifinagh, Tifinagh,
+ Tifinagh, Tifinagh, Tifinagh, Tifinagh, Tifinagh, Tifinagh, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Tifinagh,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+
+ /* U+3000-307f at offset 5376 */
+ Common, Common, Common, Common, Common, Han, Common, Han,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Han, Han, Han, Han, Han, Han, Han,
+ Han, Han, Inherited, Inherited, Inherited, Inherited, Inherited, Inherited,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Han, Han, Han, Han, Common, Common, Common, Common,
+ Common, Hiragana, Hiragana, Hiragana, Hiragana, Hiragana, Hiragana, Hiragana,
+ Hiragana, Hiragana, Hiragana, Hiragana, Hiragana, Hiragana, Hiragana, Hiragana,
+ Hiragana, Hiragana, Hiragana, Hiragana, Hiragana, Hiragana, Hiragana, Hiragana,
+ Hiragana, Hiragana, Hiragana, Hiragana, Hiragana, Hiragana, Hiragana, Hiragana,
+ Hiragana, Hiragana, Hiragana, Hiragana, Hiragana, Hiragana, Hiragana, Hiragana,
+ Hiragana, Hiragana, Hiragana, Hiragana, Hiragana, Hiragana, Hiragana, Hiragana,
+ Hiragana, Hiragana, Hiragana, Hiragana, Hiragana, Hiragana, Hiragana, Hiragana,
+ Hiragana, Hiragana, Hiragana, Hiragana, Hiragana, Hiragana, Hiragana, Hiragana,
+
+ /* U+3080-30ff at offset 5504 */
+ Hiragana, Hiragana, Hiragana, Hiragana, Hiragana, Hiragana, Hiragana, Hiragana,
+ Hiragana, Hiragana, Hiragana, Hiragana, Hiragana, Hiragana, Hiragana, Hiragana,
+ Hiragana, Hiragana, Hiragana, Hiragana, Hiragana, Hiragana, Hiragana, Common,
+ Common, Inherited, Inherited, Common, Common, Hiragana, Hiragana, Hiragana,
+ Common, Katakana, Katakana, Katakana, Katakana, Katakana, Katakana, Katakana,
+ Katakana, Katakana, Katakana, Katakana, Katakana, Katakana, Katakana, Katakana,
+ Katakana, Katakana, Katakana, Katakana, Katakana, Katakana, Katakana, Katakana,
+ Katakana, Katakana, Katakana, Katakana, Katakana, Katakana, Katakana, Katakana,
+ Katakana, Katakana, Katakana, Katakana, Katakana, Katakana, Katakana, Katakana,
+ Katakana, Katakana, Katakana, Katakana, Katakana, Katakana, Katakana, Katakana,
+ Katakana, Katakana, Katakana, Katakana, Katakana, Katakana, Katakana, Katakana,
+ Katakana, Katakana, Katakana, Katakana, Katakana, Katakana, Katakana, Katakana,
+ Katakana, Katakana, Katakana, Katakana, Katakana, Katakana, Katakana, Katakana,
+ Katakana, Katakana, Katakana, Katakana, Katakana, Katakana, Katakana, Katakana,
+ Katakana, Katakana, Katakana, Katakana, Katakana, Katakana, Katakana, Katakana,
+ Katakana, Katakana, Katakana, Common, Common, Katakana, Katakana, Katakana,
+
+ /* U+3100-317f at offset 5632 */
+ Common, Common, Common, Common, Common, Bopomofo, Bopomofo, Bopomofo,
+ Bopomofo, Bopomofo, Bopomofo, Bopomofo, Bopomofo, Bopomofo, Bopomofo, Bopomofo,
+ Bopomofo, Bopomofo, Bopomofo, Bopomofo, Bopomofo, Bopomofo, Bopomofo, Bopomofo,
+ Bopomofo, Bopomofo, Bopomofo, Bopomofo, Bopomofo, Bopomofo, Bopomofo, Bopomofo,
+ Bopomofo, Bopomofo, Bopomofo, Bopomofo, Bopomofo, Bopomofo, Bopomofo, Bopomofo,
+ Bopomofo, Bopomofo, Bopomofo, Bopomofo, Bopomofo, Common, Common, Common,
+ Common, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul,
+ Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul,
+ Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul,
+ Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul,
+ Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul,
+ Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul,
+ Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul,
+ Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul,
+ Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul,
+ Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul,
+
+ /* U+3180-31ff at offset 5760 */
+ Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul,
+ Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Bopomofo, Bopomofo, Bopomofo, Bopomofo, Bopomofo, Bopomofo, Bopomofo, Bopomofo,
+ Bopomofo, Bopomofo, Bopomofo, Bopomofo, Bopomofo, Bopomofo, Bopomofo, Bopomofo,
+ Bopomofo, Bopomofo, Bopomofo, Bopomofo, Bopomofo, Bopomofo, Bopomofo, Bopomofo,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Katakana, Katakana, Katakana, Katakana, Katakana, Katakana, Katakana, Katakana,
+ Katakana, Katakana, Katakana, Katakana, Katakana, Katakana, Katakana, Katakana,
+
+ /* U+3200-327f at offset 5888 */
+ Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul,
+ Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul,
+ Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul,
+ Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul,
+ Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul,
+ Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul,
+ Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Common, Common,
+
+ /* U+d780-d7ff at offset 6016 */
+ Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul,
+ Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul,
+ Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul,
+ Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul,
+ Hangul, Hangul, Hangul, Hangul, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+
+ /* U+fb00-fb7f at offset 6144 */
+ Latin, Latin, Latin, Latin, Latin, Latin, Latin, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Armenian, Armenian, Armenian, Armenian, Armenian,
+ Common, Common, Common, Common, Common, Hebrew, Hebrew, Hebrew,
+ Hebrew, Hebrew, Hebrew, Hebrew, Hebrew, Hebrew, Hebrew, Hebrew,
+ Hebrew, Hebrew, Hebrew, Hebrew, Hebrew, Hebrew, Hebrew, Hebrew,
+ Hebrew, Hebrew, Hebrew, Hebrew, Hebrew, Hebrew, Hebrew, Common,
+ Hebrew, Hebrew, Hebrew, Hebrew, Hebrew, Common, Hebrew, Common,
+ Hebrew, Hebrew, Common, Hebrew, Hebrew, Common, Hebrew, Hebrew,
+ Hebrew, Hebrew, Hebrew, Hebrew, Hebrew, Hebrew, Hebrew, Hebrew,
+ Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
+ Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
+ Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
+ Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
+ Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
+ Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
+
+ /* U+fb80-fbff at offset 6272 */
+ Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
+ Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
+ Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
+ Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
+ Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
+ Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
+ Arabic, Arabic, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Arabic, Arabic, Arabic, Arabic, Arabic,
+ Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
+ Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
+ Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
+ Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
+ Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
+
+ /* U+fd00-fd7f at offset 6400 */
+ Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
+ Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
+ Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
+ Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
+ Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
+ Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
+ Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
+ Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
+ Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
+ Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
+ Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
+ Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
+ Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
+
+ /* U+fd80-fdff at offset 6528 */
+ Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
+ Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
+ Common, Common, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
+ Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
+ Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
+ Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
+ Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
+ Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
+ Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
+ Arabic, Arabic, Arabic, Arabic, Arabic, Common, Common, Common,
+
+ /* U+fe00-fe7f at offset 6656 */
+ Inherited, Inherited, Inherited, Inherited, Inherited, Inherited, Inherited, Inherited,
+ Inherited, Inherited, Inherited, Inherited, Inherited, Inherited, Inherited, Inherited,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Inherited, Inherited, Inherited, Inherited, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Arabic, Arabic, Arabic, Arabic, Arabic, Common, Arabic, Arabic,
+ Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
+
+ /* U+fe80-feff at offset 6784 */
+ Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
+ Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
+ Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
+ Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
+ Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
+ Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
+ Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
+ Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
+ Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
+ Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
+ Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
+ Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
+ Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
+ Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
+ Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic, Arabic,
+ Arabic, Arabic, Arabic, Arabic, Arabic, Common, Common, Common,
+
+ /* U+ff80-ffff at offset 6912 */
+ Katakana, Katakana, Katakana, Katakana, Katakana, Katakana, Katakana, Katakana,
+ Katakana, Katakana, Katakana, Katakana, Katakana, Katakana, Katakana, Katakana,
+ Katakana, Katakana, Katakana, Katakana, Katakana, Katakana, Katakana, Katakana,
+ Katakana, Katakana, Katakana, Katakana, Katakana, Katakana, Common, Common,
+ Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul,
+ Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul,
+ Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul,
+ Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Common,
+ Common, Common, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul,
+ Common, Common, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul,
+ Common, Common, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul,
+ Common, Common, Hangul, Hangul, Hangul, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common,
+ Common, Common, Common, Common, Common, Common, Common, Common
+};
+
+} // namespace QUnicodeTables
+
+
+QT_END_NAMESPACE
diff --git a/src/corelib/tools/qunicodetables_p.h b/src/corelib/tools/qunicodetables_p.h
new file mode 100644
index 0000000000..e588313b6d
--- /dev/null
+++ b/src/corelib/tools/qunicodetables_p.h
@@ -0,0 +1,231 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/* This file is autogenerated from the Unicode 5.0 database. Do not edit */
+
+//
+// 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.
+//
+
+#ifndef QUNICODETABLES_P_H
+#define QUNICODETABLES_P_H
+
+#include <QtCore/qchar.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace QUnicodeTables {
+ struct Properties {
+ ushort category : 8;
+ ushort line_break_class : 8;
+ ushort direction : 8;
+ ushort combiningClass :8;
+ ushort joining : 2;
+ signed short digitValue : 6; /* 5 needed */
+ ushort unicodeVersion : 4;
+ ushort lowerCaseSpecial : 1;
+ ushort upperCaseSpecial : 1;
+ ushort titleCaseSpecial : 1;
+ ushort caseFoldSpecial : 1; /* currently unused */
+ signed short mirrorDiff : 16;
+ signed short lowerCaseDiff : 16;
+ signed short upperCaseDiff : 16;
+ signed short titleCaseDiff : 16;
+ signed short caseFoldDiff : 16;
+ ushort graphemeBreak : 8;
+ ushort wordBreak : 8;
+ ushort sentenceBreak : 8;
+ };
+ Q_CORE_EXPORT const Properties* QT_FASTCALL properties(uint ucs4);
+ Q_CORE_EXPORT const Properties* QT_FASTCALL properties(ushort ucs2);
+
+ // See http://www.unicode.org/reports/tr24/tr24-5.html
+
+ enum Script {
+ Common,
+ Greek,
+ Cyrillic,
+ Armenian,
+ Hebrew,
+ Arabic,
+ Syriac,
+ Thaana,
+ Devanagari,
+ Bengali,
+ Gurmukhi,
+ Gujarati,
+ Oriya,
+ Tamil,
+ Telugu,
+ Kannada,
+ Malayalam,
+ Sinhala,
+ Thai,
+ Lao,
+ Tibetan,
+ Myanmar,
+ Georgian,
+ Hangul,
+ Ogham,
+ Runic,
+ Khmer,
+ Inherited,
+ ScriptCount = Inherited,
+ Latin = Common,
+ Ethiopic = Common,
+ Cherokee = Common,
+ CanadianAboriginal = Common,
+ Mongolian = Common,
+ Hiragana = Common,
+ Katakana = Common,
+ Bopomofo = Common,
+ Han = Common,
+ Yi = Common,
+ OldItalic = Common,
+ Gothic = Common,
+ Deseret = Common,
+ Tagalog = Common,
+ Hanunoo = Common,
+ Buhid = Common,
+ Tagbanwa = Common,
+ Limbu = Common,
+ TaiLe = Common,
+ LinearB = Common,
+ Ugaritic = Common,
+ Shavian = Common,
+ Osmanya = Common,
+ Cypriot = Common,
+ Braille = Common,
+ Buginese = Common,
+ Coptic = Common,
+ NewTaiLue = Common,
+ Glagolitic = Common,
+ Tifinagh = Common,
+ SylotiNagri = Common,
+ OldPersian = Common,
+ Kharoshthi = Common,
+ Balinese = Common,
+ Cuneiform = Common,
+ Phoenician = Common,
+ PhagsPa = Common,
+ Nko = Common
+ };
+ enum { ScriptSentinel = 32 };
+
+
+ // see http://www.unicode.org/reports/tr14/tr14-19.html
+ // we don't use the XX, AI and CB properties and map them to AL instead.
+ // as we don't support any EBDIC based OS'es, NL is ignored and mapped to AL as well.
+ enum LineBreakClass {
+ LineBreak_OP, LineBreak_CL, LineBreak_QU, LineBreak_GL, LineBreak_NS,
+ LineBreak_EX, LineBreak_SY, LineBreak_IS, LineBreak_PR, LineBreak_PO,
+ LineBreak_NU, LineBreak_AL, LineBreak_ID, LineBreak_IN, LineBreak_HY,
+ LineBreak_BA, LineBreak_BB, LineBreak_B2, LineBreak_ZW, LineBreak_CM,
+ LineBreak_WJ, LineBreak_H2, LineBreak_H3, LineBreak_JL, LineBreak_JV,
+ LineBreak_JT, LineBreak_SA, LineBreak_SG,
+ LineBreak_SP, LineBreak_CR, LineBreak_LF, LineBreak_BK
+ };
+
+
+ Q_CORE_EXPORT QUnicodeTables::LineBreakClass QT_FASTCALL lineBreakClass(uint ucs4);
+ inline int lineBreakClass(const QChar &ch) {
+ return QUnicodeTables::lineBreakClass(ch.unicode());
+ }
+
+ Q_CORE_EXPORT int QT_FASTCALL script(uint ucs4);
+ Q_CORE_EXPORT_INLINE int QT_FASTCALL script(const QChar &ch) {
+ return script(ch.unicode());
+ }
+
+
+ enum GraphemeBreak {
+ GraphemeBreakOther,
+ GraphemeBreakCR,
+ GraphemeBreakLF,
+ GraphemeBreakControl,
+ GraphemeBreakExtend,
+ GraphemeBreakL,
+ GraphemeBreakV,
+ GraphemeBreakT,
+ GraphemeBreakLV,
+ GraphemeBreakLVT
+ };
+
+
+ enum WordBreak {
+ WordBreakOther,
+ WordBreakFormat,
+ WordBreakKatakana,
+ WordBreakALetter,
+ WordBreakMidLetter,
+ WordBreakMidNum,
+ WordBreakNumeric,
+ WordBreakExtendNumLet
+ };
+
+
+ enum SentenceBreak {
+ SentenceBreakOther,
+ SentenceBreakSep,
+ SentenceBreakFormat,
+ SentenceBreakSp,
+ SentenceBreakLower,
+ SentenceBreakUpper,
+ SentenceBreakOLetter,
+ SentenceBreakNumeric,
+ SentenceBreakATerm,
+ SentenceBreakSTerm,
+ SentenceBreakClose
+ };
+
+
+}
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/corelib/tools/qvarlengtharray.h b/src/corelib/tools/qvarlengtharray.h
new file mode 100644
index 0000000000..e2f60edd19
--- /dev/null
+++ b/src/corelib/tools/qvarlengtharray.h
@@ -0,0 +1,238 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QVARLENGTHARRAY_H
+#define QVARLENGTHARRAY_H
+
+#include <QtCore/qcontainerfwd.h>
+#include <QtCore/qglobal.h>
+#include <new>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Core)
+
+// Prealloc = 256 by default, specified in qcontainerfwd.h
+template<class T, int Prealloc>
+class QVarLengthArray
+{
+public:
+ inline explicit QVarLengthArray(int size = 0);
+
+ inline QVarLengthArray(const QVarLengthArray<T, Prealloc> &other)
+ : a(Prealloc), s(0), ptr(reinterpret_cast<T *>(array))
+ {
+ append(other.constData(), other.size());
+ }
+
+ inline ~QVarLengthArray() {
+ if (QTypeInfo<T>::isComplex) {
+ T *i = ptr + s;
+ while (i-- != ptr)
+ i->~T();
+ }
+ if (ptr != reinterpret_cast<T *>(array))
+ qFree(ptr);
+ }
+ inline QVarLengthArray<T, Prealloc> &operator=(const QVarLengthArray<T, Prealloc> &other)
+ {
+ if (this != &other) {
+ clear();
+ append(other.constData(), other.size());
+ }
+ return *this;
+ }
+
+ inline void removeLast() {
+ Q_ASSERT(s > 0);
+ realloc(s - 1, a);
+ }
+ inline int size() const { return s; }
+ inline int count() const { return s; }
+ inline bool isEmpty() const { return (s == 0); }
+ inline void resize(int size);
+ inline void clear() { resize(0); }
+
+ inline int capacity() const { return a; }
+ inline void reserve(int size);
+
+ inline T &operator[](int idx) {
+ Q_ASSERT(idx >= 0 && idx < s);
+ return ptr[idx];
+ }
+ inline const T &operator[](int idx) const {
+ Q_ASSERT(idx >= 0 && idx < s);
+ return ptr[idx];
+ }
+
+ inline void append(const T &t) {
+ if (s == a) // i.e. s != 0
+ realloc(s, s<<1);
+ const int idx = s++;
+ if (QTypeInfo<T>::isComplex) {
+ new (ptr + idx) T(t);
+ } else {
+ ptr[idx] = t;
+ }
+ }
+ void append(const T *buf, int size);
+
+ inline T *data() { return ptr; }
+ inline const T *data() const { return ptr; }
+ inline const T * constData() const { return ptr; }
+
+private:
+ void realloc(int size, int alloc);
+
+ int a;
+ int s;
+ T *ptr;
+ union {
+ // ### Qt 5: Use 'Prealloc * sizeof(T)' as array size
+ char array[sizeof(qint64) * (((Prealloc * sizeof(T)) / sizeof(qint64)) + 1)];
+ qint64 q_for_alignment_1;
+ double q_for_alignment_2;
+ };
+};
+
+template <class T, int Prealloc>
+Q_INLINE_TEMPLATE QVarLengthArray<T, Prealloc>::QVarLengthArray(int asize)
+ : s(asize) {
+ if (s > Prealloc) {
+ ptr = reinterpret_cast<T *>(qMalloc(s * sizeof(T)));
+ a = s;
+ } else {
+ ptr = reinterpret_cast<T *>(array);
+ a = Prealloc;
+ }
+ if (QTypeInfo<T>::isComplex) {
+ T *i = ptr + s;
+ while (i != ptr)
+ new (--i) T;
+ }
+}
+
+template <class T, int Prealloc>
+Q_INLINE_TEMPLATE void QVarLengthArray<T, Prealloc>::resize(int asize)
+{ realloc(asize, qMax(asize, a)); }
+
+template <class T, int Prealloc>
+Q_INLINE_TEMPLATE void QVarLengthArray<T, Prealloc>::reserve(int asize)
+{ if (asize > a) realloc(s, asize); }
+
+template <class T, int Prealloc>
+Q_OUTOFLINE_TEMPLATE void QVarLengthArray<T, Prealloc>::append(const T *abuf, int asize)
+{
+ Q_ASSERT(abuf);
+ if (asize <= 0)
+ return;
+
+ const int idx = s;
+ const int news = s + asize;
+ if (news >= a)
+ realloc(s, qMax(s<<1, news));
+ s = news;
+
+ if (QTypeInfo<T>::isComplex) {
+ T *i = ptr + idx;
+ T *j = i + asize;
+ while (i < j)
+ new (i++) T(*abuf++);
+ } else {
+ qMemCopy(&ptr[idx], abuf, asize * sizeof(T));
+ }
+}
+
+template <class T, int Prealloc>
+Q_OUTOFLINE_TEMPLATE void QVarLengthArray<T, Prealloc>::realloc(int asize, int aalloc)
+{
+ Q_ASSERT(aalloc >= asize);
+ T *oldPtr = ptr;
+ int osize = s;
+ s = asize;
+
+ if (aalloc != a) {
+ ptr = reinterpret_cast<T *>(qMalloc(aalloc * sizeof(T)));
+ if (ptr) {
+ a = aalloc;
+
+ if (QTypeInfo<T>::isStatic) {
+ T *i = ptr + osize;
+ T *j = oldPtr + osize;
+ while (i != ptr) {
+ new (--i) T(*--j);
+ j->~T();
+ }
+ } else {
+ qMemCopy(ptr, oldPtr, osize * sizeof(T));
+ }
+ } else {
+ ptr = oldPtr;
+ s = 0;
+ asize = 0;
+ }
+ }
+
+ if (QTypeInfo<T>::isComplex) {
+ if (asize < osize) {
+ T *i = oldPtr + osize;
+ T *j = oldPtr + asize;
+ while (i-- != j)
+ i->~T();
+ } else {
+ T *i = ptr + asize;
+ T *j = ptr + osize;
+ while (i != j)
+ new (--i) T;
+ }
+ }
+
+ if (oldPtr != reinterpret_cast<T *>(array) && oldPtr != ptr)
+ qFree(oldPtr);
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QVARLENGTHARRAY_H
diff --git a/src/corelib/tools/qvector.cpp b/src/corelib/tools/qvector.cpp
new file mode 100644
index 0000000000..6b26b2e08d
--- /dev/null
+++ b/src/corelib/tools/qvector.cpp
@@ -0,0 +1,968 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qvector.h"
+#include "qtools_p.h"
+#include <string.h>
+
+QT_BEGIN_NAMESPACE
+
+QVectorData QVectorData::shared_null = { Q_BASIC_ATOMIC_INITIALIZER(1), 0, 0, true, false };
+
+QVectorData *QVectorData::malloc(int sizeofTypedData, int size, int sizeofT, QVectorData *init)
+{
+ QVectorData* p = (QVectorData *)qMalloc(sizeofTypedData + (size - 1) * sizeofT);
+ ::memcpy(p, init, sizeofTypedData + (qMin(size, init->alloc) - 1) * sizeofT);
+ return p;
+}
+
+int QVectorData::grow(int sizeofTypedData, int size, int sizeofT, bool excessive)
+{
+ if (excessive)
+ return size + size / 2;
+ return qAllocMore(size * sizeofT, sizeofTypedData - sizeofT) / sizeofT;
+}
+
+/*!
+ \class QVector
+ \brief The QVector class is a template class that provides a dynamic array.
+
+ \ingroup tools
+ \ingroup shared
+ \mainclass
+ \reentrant
+
+ QVector\<T\> is one of Qt's generic \l{container classes}. It
+ stores its items in adjacent memory locations and provides fast
+ index-based access.
+
+ QList\<T\>, QLinkedList\<T\>, and QVarLengthArray\<T\> provide
+ similar functionality. Here's an overview:
+
+ \list
+ \i For most purposes, QList is the right class to use. Operations
+ like prepend() and insert() are usually faster than with
+ QVector because of the way QList stores its items in memory
+ (see \l{Algorithmic Complexity} for details),
+ and its index-based API is more convenient than QLinkedList's
+ iterator-based API. It also expands to less code in your
+ executable.
+ \i If you need a real linked list, with guarantees of \l{constant
+ time} insertions in the middle of the list and iterators to
+ items rather than indexes, use QLinkedList.
+ \i If you want the items to occupy adjacent memory positions, or
+ if your items are larger than a pointer and you want to avoid
+ the overhead of allocating them on the heap individually at
+ insertion time, then use QVector.
+ \i If you want a low-level variable-size array, QVarLengthArray
+ may be sufficient.
+ \endlist
+
+ Here's an example of a QVector that stores integers and a QVector
+ that stores QString values:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qvector.cpp 0
+
+ QVector stores a vector (or array) of items. Typically, vectors
+ are created with an initial size. For example, the following code
+ constructs a QVector with 200 elements:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qvector.cpp 1
+
+ The elements are automatically initialized with a
+ \l{default-constructed value}. If you want to initialize the
+ vector with a different value, pass that value as the second
+ argument to the constructor:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qvector.cpp 2
+
+ You can also call fill() at any time to fill the vector with a
+ value.
+
+ QVector uses 0-based indexes, just like C++ arrays. To access the
+ item at a particular index position, you can use operator[](). On
+ non-const vectors, operator[]() returns a reference to the item
+ that can be used on the left side of an assignment:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qvector.cpp 3
+
+ For read-only access, an alternative syntax is to use at():
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qvector.cpp 4
+
+ at() can be faster than operator[](), because it never causes a
+ \l{deep copy} to occur.
+
+ Another way to access the data stored in a QVector is to call
+ data(). The function returns a pointer to the first item in the
+ vector. You can use the pointer to directly access and modify the
+ elements stored in the vector. The pointer is also useful if you
+ need to pass a QVector to a function that accepts a plain C++
+ array.
+
+ If you want to find all occurrences of a particular value in a
+ vector, use indexOf() or lastIndexOf(). The former searches
+ forward starting from a given index position, the latter searches
+ backward. Both return the index of the matching item if they found
+ one; otherwise, they return -1. For example:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qvector.cpp 5
+
+ If you simply want to check whether a vector contains a
+ particular value, use contains(). If you want to find out how
+ many times a particular value occurs in the vector, use count().
+
+ QVector provides these basic functions to add, move, and remove
+ items: insert(), replace(), remove(), prepend(), append(). With
+ the exception of append() and replace(), these functions can be slow
+ (\l{linear time}) for large vectors, because they require moving many
+ items in the vector by one position in memory. If you want a container
+ class that provides fast insertion/removal in the middle, use
+ QList or QLinkedList instead.
+
+ Unlike plain C++ arrays, QVectors can be resized at any time by
+ calling resize(). If the new size is larger than the old size,
+ QVector might need to reallocate the whole vector. QVector tries
+ to reduce the number of reallocations by preallocating up to twice
+ as much memory as the actual data needs.
+
+ If you know in advance approximately how many items the QVector
+ will contain, you can call reserve(), asking QVector to
+ preallocate a certain amount of memory. You can also call
+ capacity() to find out how much memory QVector actually
+ allocated.
+
+ Note that using non-const operators and functions can cause
+ QVector to do a deep copy of the data. This is due to \l{implicit sharing}.
+
+ QVector's value type must be an \l{assignable data type}. This
+ covers most data types that are commonly used, but the compiler
+ won't let you, for example, store a QWidget as a value; instead,
+ store a QWidget *. A few functions have additional requirements;
+ for example, indexOf() and lastIndexOf() expect the value type to
+ support \c operator==(). These requirements are documented on a
+ per-function basis.
+
+ Like the other container classes, QVector provides \l{Java-style
+ iterators} (QVectorIterator and QMutableVectorIterator) and
+ \l{STL-style iterators} (QVector::const_iterator and
+ QVector::iterator). In practice, these are rarely used, because
+ you can use indexes into the QVector.
+
+ In addition to QVector, Qt also provides QVarLengthArray, a very
+ low-level class with little functionality that is optimized for
+ speed.
+
+ QVector does \e not support inserting, prepending, appending or replacing
+ with references to its own values. Doing so will cause your application to
+ abort with an error message.
+
+ \sa QVectorIterator, QMutableVectorIterator, QList, QLinkedList
+*/
+
+/*!
+ \fn QVector<T> QVector::mid(int pos, int length = -1) const
+
+ Returns a vector whose elements are copied from this vector,
+ starting at position \a pos. If \a length is -1 (the default), all
+ elements after \a pos are copied; otherwise \a length elements (or
+ all remaining elements if there are less than \a length elements)
+ are copied.
+*/
+
+
+/*! \fn QVector::QVector()
+
+ Constructs an empty vector.
+
+ \sa resize()
+*/
+
+/*! \fn QVector::QVector(int size)
+
+ Constructs a vector with an initial size of \a size elements.
+
+ The elements are initialized with a \l{default-constructed
+ value}.
+
+ \sa resize()
+*/
+
+/*! \fn QVector::QVector(int size, const T &value)
+
+ Constructs a vector with an initial size of \a size elements.
+ Each element is initialized with \a value.
+
+ \sa resize(), fill()
+*/
+
+/*! \fn QVector::QVector(const QVector<T> &other)
+
+ Constructs a copy of \a other.
+
+ This operation takes \l{constant time}, because QVector is
+ \l{implicitly shared}. This makes returning a QVector from a
+ function very fast. If a shared instance is modified, it will be
+ copied (copy-on-write), and that takes \l{linear time}.
+
+ \sa operator=()
+*/
+
+/*! \fn QVector::~QVector()
+
+ Destroys the vector.
+*/
+
+/*! \fn QVector<T> &QVector::operator=(const QVector<T> &other)
+
+ Assigns \a other to this vector and returns a reference to this
+ vector.
+*/
+
+/*! \fn bool QVector::operator==(const QVector<T> &other) const
+
+ Returns true if \a other is equal to this vector; otherwise
+ returns false.
+
+ Two vectors are considered equal if they contain the same values
+ in the same order.
+
+ This function requires the value type to have an implementation
+ of \c operator==().
+
+ \sa operator!=()
+*/
+
+/*! \fn bool QVector::operator!=(const QVector<T> &other) const
+
+ Returns true if \a other is not equal to this vector; otherwise
+ returns false.
+
+ Two vectors are considered equal if they contain the same values
+ in the same order.
+
+ This function requires the value type to have an implementation
+ of \c operator==().
+
+ \sa operator==()
+*/
+
+/*! \fn int QVector::size() const
+
+ Returns the number of items in the vector.
+
+ \sa isEmpty(), resize()
+*/
+
+/*! \fn bool QVector::isEmpty() const
+
+ Returns true if the vector has size 0; otherwise returns false.
+
+ \sa size(), resize()
+*/
+
+/*! \fn void QVector::resize(int size)
+
+ Sets the size of the vector to \a size. If \a size is greater than the
+ current size, elements are added to the end; the new elements are
+ initialized with a \l{default-constructed value}. If \a size is less
+ than the current size, elements are removed from the end.
+
+ \sa size()
+*/
+
+/*! \fn int QVector::capacity() const
+
+ Returns the maximum number of items that can be stored in the
+ vector without forcing a reallocation.
+
+ The sole purpose of this function is to provide a means of fine
+ tuning QVector's memory usage. In general, you will rarely ever
+ need to call this function. If you want to know how many items are
+ in the vector, call size().
+
+ \sa reserve(), squeeze()
+*/
+
+/*! \fn void QVector::reserve(int size)
+
+ Attempts to allocate memory for at least \a size elements. If you
+ know in advance how large the vector 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 QVector will be a bit slower.
+
+ The sole purpose of this function is to provide a means of fine
+ tuning QVector's memory usage. In general, you will rarely ever
+ need to call this function. If you want to change the size of the
+ vector, call resize().
+
+ \sa squeeze(), capacity()
+*/
+
+/*! \fn void QVector::squeeze()
+
+ Releases any memory not required to store the items.
+
+ The sole purpose of this function is to provide a means of fine
+ tuning QVector's memory usage. In general, you will rarely ever
+ need to call this function.
+
+ \sa reserve(), capacity()
+*/
+
+/*! \fn void QVector::detach()
+
+ \internal
+*/
+
+/*! \fn bool QVector::isDetached() const
+
+ \internal
+*/
+
+/*! \fn void QVector::setSharable(bool sharable)
+
+ \internal
+*/
+
+/*! \fn T *QVector::data()
+
+ Returns a pointer to the data stored in the vector. The pointer
+ can be used to access and modify the items in the vector.
+
+ Example:
+ \snippet doc/src/snippets/code/src_corelib_tools_qvector.cpp 6
+
+ The pointer remains valid as long as the vector isn't
+ reallocated.
+
+ This function is mostly useful to pass a vector to a function
+ that accepts a plain C++ array.
+
+ \sa constData(), operator[]()
+*/
+
+/*! \fn const T *QVector::data() const
+
+ \overload
+*/
+
+/*! \fn const T *QVector::constData() const
+
+ Returns a const pointer to the data stored in the vector. The
+ pointer can be used to access the items in the vector.
+ The pointer remains valid as long as the vector isn't
+ reallocated.
+
+ This function is mostly useful to pass a vector to a function
+ that accepts a plain C++ array.
+
+ \sa data(), operator[]()
+*/
+
+/*! \fn void QVector::clear()
+
+ Removes all the elements from the vector and releases the memory used by
+ the vector.
+*/
+
+/*! \fn const T &QVector::at(int i) const
+
+ Returns the item at index position \a i in the vector.
+
+ \a i must be a valid index position in the vector (i.e., 0 <= \a
+ i < size()).
+
+ \sa value(), operator[]()
+*/
+
+/*! \fn T &QVector::operator[](int i)
+
+ Returns the item at index position \a i as a modifiable reference.
+
+ \a i must be a valid index position in the vector (i.e., 0 <= \a i
+ < size()).
+
+ Note that using non-const operators can cause QVector to do a deep
+ copy.
+
+ \sa at(), value()
+*/
+
+/*! \fn const T &QVector::operator[](int i) const
+
+ \overload
+
+ Same as at(\a i).
+*/
+
+/*!
+ \fn void QVector::append(const T &value)
+
+ Inserts \a value at the end of the vector.
+
+ Example:
+ \snippet doc/src/snippets/code/src_corelib_tools_qvector.cpp 7
+
+ This is the same as calling resize(size() + 1) and assigning \a
+ value to the new last element in the vector.
+
+ This operation is relatively fast, because QVector typically
+ allocates more memory than necessary, so it can grow without
+ reallocating the entire vector each time.
+
+ \sa operator<<(), prepend(), insert()
+*/
+
+/*! \fn void QVector::prepend(const T &value)
+
+ Inserts \a value at the beginning of the vector.
+
+ Example:
+ \snippet doc/src/snippets/code/src_corelib_tools_qvector.cpp 8
+
+ This is the same as vector.insert(0, \a value).
+
+ For large vectors, this operation can be slow (\l{linear time}),
+ because it requires moving all the items in the vector by one
+ position further in memory. If you want a container class that
+ provides a fast prepend() function, use QList or QLinkedList
+ instead.
+
+ \sa append(), insert()
+*/
+
+/*! \fn void QVector::insert(int i, const T &value)
+
+ Inserts \a value at index position \a i in the vector. If \a i is
+ 0, the value is prepended to the vector. If \a i is size(), the
+ value is appended to the vector.
+
+ Example:
+ \snippet doc/src/snippets/code/src_corelib_tools_qvector.cpp 9
+
+ For large vectors, this operation can be slow (\l{linear time}),
+ because it requires moving all the items at indexes \a i and
+ above by one position further in memory. If you want a container
+ class that provides a fast insert() function, use QLinkedList
+ instead.
+
+ \sa append(), prepend(), remove()
+*/
+
+/*! \fn void QVector::insert(int i, int count, const T &value)
+
+ \overload
+
+ Inserts \a count copies of \a value at index position \a i in the
+ vector.
+
+ Example:
+ \snippet doc/src/snippets/code/src_corelib_tools_qvector.cpp 10
+*/
+
+/*! \fn QVector::iterator QVector::insert(iterator before, const T &value)
+
+ \overload
+
+ Inserts \a value in front of the item pointed to by the iterator
+ \a before. Returns an iterator pointing at the inserted item.
+*/
+
+/*! \fn QVector::iterator QVector::insert(iterator before, int count, const T &value)
+
+ Inserts \a count copies of \a value in front of the item pointed to
+ by the iterator \a before. Returns an iterator pointing at the
+ first of the inserted items.
+*/
+
+/*! \fn void QVector::replace(int i, const T &value)
+
+ Replaces the item at index position \a i with \a value.
+
+ \a i must be a valid index position in the vector (i.e., 0 <= \a
+ i < size()).
+
+ \sa operator[](), remove()
+*/
+
+/*! \fn void QVector::remove(int i)
+
+ \overload
+
+ Removes the element at index position \a i.
+
+ \sa insert(), replace(), fill()
+*/
+
+/*! \fn void QVector::remove(int i, int count)
+
+ \overload
+
+ Removes \a count elements from the middle of the vector, starting at
+ index position \a i.
+
+ \sa insert(), replace(), fill()
+*/
+
+/*! \fn QVector &QVector::fill(const T &value, int size = -1)
+
+ Assigns \a value to all items in the vector. If \a size is
+ different from -1 (the default), the vector is resized to size \a
+ size beforehand.
+
+ Example:
+ \snippet doc/src/snippets/code/src_corelib_tools_qvector.cpp 11
+
+ \sa resize()
+*/
+
+/*! \fn int QVector::indexOf(const T &value, int from = 0) const
+
+ Returns the index position of the first occurrence of \a value in
+ the vector, searching forward from index position \a from.
+ Returns -1 if no item matched.
+
+ Example:
+ \snippet doc/src/snippets/code/src_corelib_tools_qvector.cpp 12
+
+ This function requires the value type to have an implementation of
+ \c operator==().
+
+ \sa lastIndexOf(), contains()
+*/
+
+/*! \fn int QVector::lastIndexOf(const T &value, int from = -1) const
+
+ Returns the index position of the last occurrence of the value \a
+ value in the vector, searching backward from index position \a
+ from. If \a from is -1 (the default), the search starts at the
+ last item. Returns -1 if no item matched.
+
+ Example:
+ \snippet doc/src/snippets/code/src_corelib_tools_qvector.cpp 13
+
+ This function requires the value type to have an implementation of
+ \c operator==().
+
+ \sa indexOf()
+*/
+
+/*! \fn bool QVector::contains(const T &value) const
+
+ Returns true if the vector contains an occurrence of \a value;
+ otherwise returns false.
+
+ This function requires the value type to have an implementation of
+ \c operator==().
+
+ \sa indexOf(), count()
+*/
+
+/*! \fn bool QVector::startsWith(const T &value) const
+ \since 4.5
+
+ Returns true if this vector is not empty and its first
+ item is equal to \a value; otherwise returns false.
+
+ \sa isEmpty(), first()
+*/
+
+/*! \fn bool QVector::endsWith(const T &value) const
+ \since 4.5
+
+ Returns true if this vector is not empty and its last
+ item is equal to \a value; otherwise returns false.
+
+ \sa isEmpty(), last()
+*/
+
+
+/*! \fn int QVector::count(const T &value) const
+
+ Returns the number of occurrences of \a value in the vector.
+
+ This function requires the value type to have an implementation of
+ \c operator==().
+
+ \sa contains(), indexOf()
+*/
+
+/*! \fn int QVector::count() const
+
+ \overload
+
+ Same as size().
+*/
+
+/*! \fn QVector::iterator QVector::begin()
+
+ Returns an \l{STL-style iterator} pointing to the first item in
+ the vector.
+
+ \sa constBegin(), end()
+*/
+
+/*! \fn QVector::const_iterator QVector::begin() const
+
+ \overload
+*/
+
+/*! \fn QVector::const_iterator QVector::constBegin() const
+
+ Returns a const \l{STL-style iterator} pointing to the first item
+ in the vector.
+
+ \sa begin(), constEnd()
+*/
+
+/*! \fn QVector::iterator QVector::end()
+
+ Returns an \l{STL-style iterator} pointing to the imaginary item
+ after the last item in the vector.
+
+ \sa begin(), constEnd()
+*/
+
+/*! \fn QVector::const_iterator QVector::end() const
+
+ \overload
+*/
+
+/*! \fn QVector::const_iterator QVector::constEnd() const
+
+ Returns a const \l{STL-style iterator} pointing to the imaginary
+ item after the last item in the vector.
+
+ \sa constBegin(), end()
+*/
+
+/*! \fn QVector::iterator QVector::erase(iterator pos)
+
+ Removes the item pointed to by the iterator \a pos from the
+ vector, and returns an iterator to the next item in the vector
+ (which may be end()).
+
+ \sa insert(), remove()
+*/
+
+/*! \fn QVector::iterator QVector::erase(iterator begin, iterator end)
+
+ \overload
+
+ Removes all the items from \a begin up to (but not including) \a
+ end. Returns an iterator to the same item that \a end referred to
+ before the call.
+*/
+
+/*! \fn T& QVector::first()
+
+ Returns a reference to the first item in the vector. This
+ function assumes that the vector isn't empty.
+
+ \sa last(), isEmpty()
+*/
+
+/*! \fn const T& QVector::first() const
+
+ \overload
+*/
+
+/*! \fn T& QVector::last()
+
+ Returns a reference to the last item in the vector. This function
+ assumes that the vector isn't empty.
+
+ \sa first(), isEmpty()
+*/
+
+/*! \fn const T& QVector::last() const
+
+ \overload
+*/
+
+/*! \fn T QVector::value(int i) const
+
+ Returns the value at index position \a i in the vector.
+
+ If the index \a i is out of bounds, the function returns
+ a \l{default-constructed value}. If you are certain that
+ \a i is within bounds, you can use at() instead, which is slightly
+ faster.
+
+ \sa at(), operator[]()
+*/
+
+/*! \fn T QVector::value(int i, const T &defaultValue) const
+
+ \overload
+
+ If the index \a i is out of bounds, the function returns
+ \a defaultValue.
+*/
+
+/*! \fn void QVector::push_back(const T &value)
+
+ This function is provided for STL compatibility. It is equivalent
+ to append(\a value).
+*/
+
+/*! \fn void QVector::push_front(const T &value)
+
+ This function is provided for STL compatibility. It is equivalent
+ to prepend(\a value).
+*/
+
+/*! \fn void QVector::pop_front()
+
+ This function is provided for STL compatibility. It is equivalent
+ to erase(begin()).
+*/
+
+/*! \fn void QVector::pop_back()
+
+ This function is provided for STL compatibility. It is equivalent
+ to erase(end() - 1).
+*/
+
+/*! \fn T& QVector::front()
+
+ This function is provided for STL compatibility. It is equivalent
+ to first().
+*/
+
+/*! \fn QVector::const_reference QVector::front() const
+
+ \overload
+*/
+
+/*! \fn QVector::reference QVector::back()
+
+ This function is provided for STL compatibility. It is equivalent
+ to last().
+*/
+
+/*! \fn QVector::const_reference QVector::back() const
+
+ \overload
+*/
+
+/*! \fn bool QVector::empty() const
+
+ This function is provided for STL compatibility. It is equivalent
+ to isEmpty(), returning true if the vector is empty; otherwise
+ returns false.
+*/
+
+/*! \fn QVector<T> &QVector::operator+=(const QVector<T> &other)
+
+ Appends the items of the \a other vector to this vector and
+ returns a reference to this vector.
+
+ \sa operator+(), append()
+*/
+
+/*! \fn void QVector::operator+=(const T &value)
+
+ \overload
+
+ Appends \a value to the vector.
+
+ \sa append(), operator<<()
+*/
+
+/*! \fn QVector<T> QVector::operator+(const QVector<T> &other) const
+
+ Returns a vector that contains all the items in this vector
+ followed by all the items in the \a other vector.
+
+ \sa operator+=()
+*/
+
+/*! \fn QVector<T> &QVector::operator<<(const T &value)
+
+ Appends \a value to the vector and returns a reference to this
+ vector.
+
+ \sa append(), operator+=()
+*/
+
+/*! \fn QVector<T> &QVector::operator<<(const QVector<T> &other)
+
+ Appends \a other to the vector and returns a reference to the
+ vector.
+*/
+
+/*! \typedef QVector::iterator
+
+ The QVector::iterator typedef provides an STL-style non-const
+ iterator for QVector and QStack.
+
+ QVector provides both \l{STL-style iterators} and \l{Java-style
+ iterators}. The STL-style non-const iterator is simply a typedef
+ for "T *" (pointer to T).
+
+ \sa QVector::begin(), QVector::end(), QVector::const_iterator, QMutableVectorIterator
+*/
+
+/*! \typedef QVector::const_iterator
+
+ The QVector::const_iterator typedef provides an STL-style const
+ iterator for QVector and QStack.
+
+ QVector provides both \l{STL-style iterators} and \l{Java-style
+ iterators}. The STL-style const iterator is simply a typedef for
+ "const T *" (pointer to const T).
+
+ \sa QVector::constBegin(), QVector::constEnd(), QVector::iterator, QVectorIterator
+*/
+
+/*! \typedef QVector::Iterator
+
+ Qt-style synonym for QVector::iterator.
+*/
+
+/*! \typedef QVector::ConstIterator
+
+ Qt-style synonym for QVector::const_iterator.
+*/
+
+/*! \typedef QVector::const_pointer
+
+ Typedef for const T *. Provided for STL compatibility.
+*/
+
+/*! \typedef QVector::const_reference
+
+ Typedef for T &. Provided for STL compatibility.
+*/
+
+/*! \typedef QVector::difference_type
+
+ Typedef for ptrdiff_t. Provided for STL compatibility.
+*/
+
+/*! \typedef QVector::pointer
+
+ Typedef for T *. Provided for STL compatibility.
+*/
+
+/*! \typedef QVector::reference
+
+ Typedef for T &. Provided for STL compatibility.
+*/
+
+/*! \typedef QVector::size_type
+
+ Typedef for int. Provided for STL compatibility.
+*/
+
+/*! \typedef QVector::value_type
+
+ Typedef for T. Provided for STL compatibility.
+*/
+
+/*! \fn QList<T> QVector<T>::toList() const
+
+ Returns a QList object with the data contained in this QVector.
+
+ Example:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qvector.cpp 14
+
+ \sa fromList(), QList::fromVector()
+*/
+
+/*! \fn QVector<T> QVector<T>::fromList(const QList<T> &list)
+
+ Returns a QVector object with the data contained in \a list.
+
+ Example:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qvector.cpp 15
+
+ \sa toList(), QList::toVector()
+*/
+
+/*! \fn QVector<T> QVector<T>::fromStdVector(const std::vector<T> &vector)
+
+ Returns a QVector object with the data contained in \a vector. The
+ order of the elements in the QVector is the same as in \a vector.
+
+ Example:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qvector.cpp 16
+
+ \sa toStdVector(), QList::fromStdList()
+*/
+
+/*! \fn std::vector<T> QVector<T>::toStdVector() const
+
+ Returns a std::vector object with the data contained in this QVector.
+ Example:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qvector.cpp 17
+
+ \sa fromStdVector(), QList::toStdList()
+*/
+
+/*! \fn QDataStream &operator<<(QDataStream &out, const QVector<T> &vector)
+ \relates QVector
+
+ Writes the vector \a vector to stream \a out.
+
+ This function requires the value type to implement \c operator<<().
+
+ \sa \link datastreamformat.html Format of the QDataStream operators \endlink
+*/
+
+/*! \fn QDataStream &operator>>(QDataStream &in, QVector<T> &vector)
+ \relates QVector
+
+ Reads a vector from stream \a in into \a vector.
+
+ This function requires the value type to implement \c operator>>().
+
+ \sa \link datastreamformat.html Format of the QDataStream operators \endlink
+*/
+
+QT_END_NAMESPACE
diff --git a/src/corelib/tools/qvector.h b/src/corelib/tools/qvector.h
new file mode 100644
index 0000000000..6bea03b936
--- /dev/null
+++ b/src/corelib/tools/qvector.h
@@ -0,0 +1,776 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QVECTOR_H
+#define QVECTOR_H
+
+#include <QtCore/qiterator.h>
+#include <QtCore/qatomic.h>
+#include <QtCore/qalgorithms.h>
+#include <QtCore/qlist.h>
+
+#ifndef QT_NO_STL
+#include <iterator>
+#include <vector>
+#endif
+#include <stdlib.h>
+#include <string.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Core)
+
+struct Q_CORE_EXPORT QVectorData
+{
+ QBasicAtomicInt ref;
+ int alloc;
+ int size;
+#if defined(QT_ARCH_SPARC) && defined(Q_CC_GNU) && defined(__LP64__) && defined(QT_BOOTSTRAPPED)
+ // workaround for bug in gcc 3.4.2
+ uint sharable;
+ uint capacity;
+#else
+ uint sharable : 1;
+ uint capacity : 1;
+#endif
+
+ static QVectorData shared_null;
+ // ### Qt 5: rename to 'allocate()'. The current name causes problems for
+ // some debugges when the QVector is member of a class within an unnamed namespace.
+ static QVectorData *malloc(int sizeofTypedData, int size, int sizeofT, QVectorData *init);
+ static int grow(int sizeofTypedData, int size, int sizeofT, bool excessive);
+};
+
+template <typename T>
+struct QVectorTypedData
+{
+ QBasicAtomicInt ref;
+ int alloc;
+ int size;
+#if defined(QT_ARCH_SPARC) && defined(Q_CC_GNU) && defined(__LP64__) && defined(QT_BOOTSTRAPPED)
+ // workaround for bug in gcc 3.4.2
+ uint sharable;
+ uint capacity;
+#else
+ uint sharable : 1;
+ uint capacity : 1;
+#endif
+ T array[1];
+};
+
+template <typename T>
+class QVector
+{
+ typedef QVectorTypedData<T> Data;
+ union { QVectorData *p; QVectorTypedData<T> *d; };
+
+public:
+ inline QVector() : p(&QVectorData::shared_null) { d->ref.ref(); }
+ explicit QVector(int size);
+ QVector(int size, const T &t);
+ inline QVector(const QVector<T> &v) : d(v.d) { d->ref.ref(); if (!d->sharable) detach_helper(); }
+ inline ~QVector() { if (!d) return; if (!d->ref.deref()) free(d); }
+ QVector<T> &operator=(const QVector<T> &v);
+ bool operator==(const QVector<T> &v) const;
+ inline bool operator!=(const QVector<T> &v) const { return !(*this == v); }
+
+ inline int size() const { return d->size; }
+
+ inline bool isEmpty() const { return d->size == 0; }
+
+ void resize(int size);
+
+ inline int capacity() const { return d->alloc; }
+ void reserve(int size);
+ inline void squeeze() { realloc(d->size, d->size); d->capacity = 0; }
+
+ inline void detach() { if (d->ref != 1) detach_helper(); }
+ inline bool isDetached() const { return d->ref == 1; }
+ inline void setSharable(bool sharable) { if (!sharable) detach(); d->sharable = sharable; }
+
+ inline T *data() { detach(); return d->array; }
+ inline const T *data() const { return d->array; }
+ inline const T *constData() const { return d->array; }
+ void clear();
+
+ const T &at(int i) const;
+ T &operator[](int i);
+ const T &operator[](int i) const;
+ void append(const T &t);
+ void prepend(const T &t);
+ void insert(int i, const T &t);
+ void insert(int i, int n, const T &t);
+ void replace(int i, const T &t);
+ void remove(int i);
+ void remove(int i, int n);
+
+ QVector<T> &fill(const T &t, int size = -1);
+
+ int indexOf(const T &t, int from = 0) const;
+ int lastIndexOf(const T &t, int from = -1) const;
+ bool contains(const T &t) const;
+ int count(const T &t) const;
+
+#ifdef QT_STRICT_ITERATORS
+ class iterator {
+ public:
+ T *i;
+ typedef std::random_access_iterator_tag iterator_category;
+ typedef ptrdiff_t difference_type;
+ typedef T value_type;
+ typedef T *pointer;
+ typedef T &reference;
+
+ inline iterator() : i(0) {}
+ inline iterator(T *n) : i(n) {}
+ inline iterator(const iterator &o): i(o.i){}
+ inline T &operator*() const { return *i; }
+ inline T *operator->() const { return i; }
+ inline T &operator[](int j) const { return *(i + j); }
+ inline bool operator==(const iterator &o) const { return i == o.i; }
+ inline bool operator!=(const iterator &o) const { return i != o.i; }
+ inline bool operator<(const iterator& other) const { return i < other.i; }
+ inline bool operator<=(const iterator& other) const { return i <= other.i; }
+ inline bool operator>(const iterator& other) const { return i > other.i; }
+ inline bool operator>=(const iterator& other) const { return i >= other.i; }
+ inline iterator &operator++() { ++i; return *this; }
+ inline iterator operator++(int) { T *n = i; ++i; return n; }
+ inline iterator &operator--() { i--; return *this; }
+ inline iterator operator--(int) { T *n = i; i--; return n; }
+ inline iterator &operator+=(int j) { i+=j; return *this; }
+ inline iterator &operator-=(int j) { i-=j; return *this; }
+ inline iterator operator+(int j) const { return iterator(i+j); }
+ inline iterator operator-(int j) const { return iterator(i-j); }
+ inline int operator-(iterator j) const { return i - j.i; }
+ };
+ friend class iterator;
+
+ class const_iterator {
+ public:
+ T *i;
+ typedef std::random_access_iterator_tag iterator_category;
+ typedef ptrdiff_t difference_type;
+ typedef T value_type;
+ typedef const T *pointer;
+ typedef const T &reference;
+
+ inline const_iterator() : i(0) {}
+ inline const_iterator(T *n) : i(n) {}
+ inline const_iterator(const const_iterator &o): i(o.i) {}
+ inline explicit const_iterator(const iterator &o): i(o.i) {}
+ inline const T &operator*() const { return *i; }
+ inline const T *operator->() const { return i; }
+ inline const T &operator[](int j) const { return *(i + j); }
+ inline bool operator==(const const_iterator &o) const { return i == o.i; }
+ inline bool operator!=(const const_iterator &o) const { return i != o.i; }
+ inline bool operator<(const const_iterator& other) const { return i < other.i; }
+ inline bool operator<=(const const_iterator& other) const { return i <= other.i; }
+ inline bool operator>(const const_iterator& other) const { return i > other.i; }
+ inline bool operator>=(const const_iterator& other) const { return i >= other.i; }
+ inline const_iterator &operator++() { ++i; return *this; }
+ inline const_iterator operator++(int) { T *n = i; ++i; return n; }
+ inline const_iterator &operator--() { i--; return *this; }
+ inline const_iterator operator--(int) { T *n = i; i--; return n; }
+ inline const_iterator &operator+=(int j) { i+=j; return *this; }
+ inline const_iterator &operator-=(int j) { i+=j; return *this; }
+ inline const_iterator operator+(int j) const { return const_iterator(i+j); }
+ inline const_iterator operator-(int j) const { return const_iterator(i-j); }
+ inline int operator-(const_iterator j) const { return i - j.i; }
+ };
+ friend class const_iterator;
+#else
+ // STL-style
+ typedef T* iterator;
+ typedef const T* const_iterator;
+#endif
+ inline iterator begin() { detach(); return d->array; }
+ inline const_iterator begin() const { return d->array; }
+ inline const_iterator constBegin() const { return d->array; }
+ inline iterator end() { detach(); return d->array + d->size; }
+ inline const_iterator end() const { return d->array + d->size; }
+ inline const_iterator constEnd() const { return d->array + d->size; }
+ iterator insert(iterator before, int n, const T &x);
+ inline iterator insert(iterator before, const T &x) { return insert(before, 1, x); }
+ iterator erase(iterator begin, iterator end);
+ inline iterator erase(iterator pos) { return erase(pos, pos+1); }
+
+ // more Qt
+ inline int count() const { return d->size; }
+ inline T& first() { Q_ASSERT(!isEmpty()); return *begin(); }
+ inline const T &first() const { Q_ASSERT(!isEmpty()); return *begin(); }
+ inline T& last() { Q_ASSERT(!isEmpty()); return *(end()-1); }
+ inline const T &last() const { Q_ASSERT(!isEmpty()); return *(end()-1); }
+ inline bool startsWith(const T &t) const { return !isEmpty() && first() == t; }
+ inline bool endsWith(const T &t) const { return !isEmpty() && last() == t; }
+ QVector<T> mid(int pos, int length = -1) const;
+
+ T value(int i) const;
+ T value(int i, const T &defaultValue) const;
+
+ // STL compatibility
+ typedef T value_type;
+ typedef value_type* pointer;
+ typedef const value_type* const_pointer;
+ typedef value_type& reference;
+ typedef const value_type& const_reference;
+#ifndef QT_NO_STL
+ typedef ptrdiff_t difference_type;
+#else
+ typedef int difference_type;
+#endif
+ typedef iterator Iterator;
+ typedef const_iterator ConstIterator;
+ typedef int size_type;
+ inline void push_back(const T &t) { append(t); }
+ inline void push_front(const T &t) { prepend(t); }
+ void pop_back() { Q_ASSERT(!isEmpty()); erase(end()-1); }
+ void pop_front() { Q_ASSERT(!isEmpty()); erase(begin()); }
+ inline bool empty() const
+ { return d->size == 0; }
+ inline T& front() { return first(); }
+ inline const_reference front() const { return first(); }
+ inline reference back() { return last(); }
+ inline const_reference back() const { return last(); }
+
+ // comfort
+ QVector<T> &operator+=(const QVector<T> &l);
+ inline QVector<T> operator+(const QVector<T> &l) const
+ { QVector n = *this; n += l; return n; }
+ inline QVector<T> &operator+=(const T &t)
+ { append(t); return *this; }
+ inline QVector<T> &operator<< (const T &t)
+ { append(t); return *this; }
+ inline QVector<T> &operator<<(const QVector<T> &l)
+ { *this += l; return *this; }
+
+ QList<T> toList() const;
+
+ static QVector<T> fromList(const QList<T> &list);
+
+#ifndef QT_NO_STL
+ static inline QVector<T> fromStdVector(const std::vector<T> &vector)
+ { QVector<T> tmp; qCopy(vector.begin(), vector.end(), std::back_inserter(tmp)); return tmp; }
+ inline std::vector<T> toStdVector() const
+ { std::vector<T> tmp; qCopy(constBegin(), constEnd(), std::back_inserter(tmp)); return tmp; }
+#endif
+
+private:
+ friend class QRegion; // Optimization for QRegion::rects()
+
+ void detach_helper();
+ QVectorData *malloc(int alloc);
+ void realloc(int size, int alloc);
+ void free(Data *d);
+ int sizeOfTypedData() {
+ // this is more or less the same as sizeof(Data), except that it doesn't
+ // count the padding at the end
+ return reinterpret_cast<const char *>(&(reinterpret_cast<const Data *>(this))->array[1]) - reinterpret_cast<const char *>(this);
+ }
+};
+
+template <typename T>
+void QVector<T>::detach_helper()
+{ realloc(d->size, d->alloc); }
+template <typename T>
+void QVector<T>::reserve(int asize)
+{ if (asize > d->alloc) realloc(d->size, asize); d->capacity = 1; }
+template <typename T>
+void QVector<T>::resize(int asize)
+{ realloc(asize, (asize > d->alloc || (!d->capacity && asize < d->size && asize < (d->alloc >> 1))) ?
+ QVectorData::grow(sizeOfTypedData(), asize, sizeof(T), QTypeInfo<T>::isStatic)
+ : d->alloc); }
+template <typename T>
+inline void QVector<T>::clear()
+{ *this = QVector<T>(); }
+template <typename T>
+inline const T &QVector<T>::at(int i) const
+{ Q_ASSERT_X(i >= 0 && i < d->size, "QVector<T>::at", "index out of range");
+ return d->array[i]; }
+template <typename T>
+inline const T &QVector<T>::operator[](int i) const
+{ Q_ASSERT_X(i >= 0 && i < d->size, "QVector<T>::operator[]", "index out of range");
+ return d->array[i]; }
+template <typename T>
+inline T &QVector<T>::operator[](int i)
+{ Q_ASSERT_X(i >= 0 && i < d->size, "QVector<T>::operator[]", "index out of range");
+ return data()[i]; }
+template <typename T>
+inline void QVector<T>::insert(int i, const T &t)
+{ Q_ASSERT_X(i >= 0 && i <= d->size, "QVector<T>::insert", "index out of range");
+ insert(begin() + i, 1, t); }
+template <typename T>
+inline void QVector<T>::insert(int i, int n, const T &t)
+{ Q_ASSERT_X(i >= 0 && i <= d->size, "QVector<T>::insert", "index out of range");
+ insert(begin() + i, n, t); }
+template <typename T>
+inline void QVector<T>::remove(int i, int n)
+{ Q_ASSERT_X(i >= 0 && n >= 0 && i + n <= d->size, "QVector<T>::remove", "index out of range");
+ erase(begin() + i, begin() + i + n); }
+template <typename T>
+inline void QVector<T>::remove(int i)
+{ Q_ASSERT_X(i >= 0 && i < d->size, "QVector<T>::remove", "index out of range");
+ erase(begin() + i, begin() + i + 1); }
+template <typename T>
+inline void QVector<T>::prepend(const T &t)
+{ insert(begin(), 1, t); }
+
+template <typename T>
+inline void QVector<T>::replace(int i, const T &t)
+{
+ Q_ASSERT_X(i >= 0 && i < d->size, "QVector<T>::replace", "index out of range");
+ const T copy(t);
+ data()[i] = copy;
+}
+
+template <typename T>
+QVector<T> &QVector<T>::operator=(const QVector<T> &v)
+{
+ v.d->ref.ref();
+ if (!d->ref.deref())
+ free(d);
+ d = v.d;
+ if (!d->sharable)
+ detach_helper();
+ return *this;
+}
+
+template <typename T>
+inline QVectorData *QVector<T>::malloc(int aalloc)
+{
+ return static_cast<QVectorData *>(qMalloc(sizeOfTypedData() + (aalloc - 1) * sizeof(T)));
+}
+
+template <typename T>
+QVector<T>::QVector(int asize)
+{
+ p = malloc(asize);
+ d->ref = 1;
+ d->alloc = d->size = asize;
+ d->sharable = true;
+ d->capacity = false;
+ if (QTypeInfo<T>::isComplex) {
+ T* b = d->array;
+ T* i = d->array + d->size;
+ while (i != b)
+ new (--i) T;
+ } else {
+ qMemSet(d->array, 0, asize * sizeof(T));
+ }
+}
+
+template <typename T>
+QVector<T>::QVector(int asize, const T &t)
+{
+ p = malloc(asize);
+ d->ref = 1;
+ d->alloc = d->size = asize;
+ d->sharable = true;
+ d->capacity = false;
+ T* i = d->array + d->size;
+ while (i != d->array)
+ new (--i) T(t);
+}
+
+template <typename T>
+void QVector<T>::free(Data *x)
+{
+ if (QTypeInfo<T>::isComplex) {
+ T* b = x->array;
+ T* i = b + x->size;
+ while (i-- != b)
+ i->~T();
+ }
+ qFree(x);
+}
+
+template <typename T>
+void QVector<T>::realloc(int asize, int aalloc)
+{
+ T *j, *i, *b;
+ union { QVectorData *p; Data *d; } x;
+ x.d = d;
+
+ if (QTypeInfo<T>::isComplex && aalloc == d->alloc && d->ref == 1) {
+ // pure resize
+ i = d->array + d->size;
+ j = d->array + asize;
+ if (i > j) {
+ while (i-- != j)
+ i->~T();
+ } else {
+ while (j-- != i)
+ new (j) T;
+ }
+ d->size = asize;
+ return;
+ }
+
+ if (aalloc != d->alloc || d->ref != 1) {
+ // (re)allocate memory
+ if (QTypeInfo<T>::isStatic) {
+ x.p = malloc(aalloc);
+ } else if (d->ref != 1) {
+ x.p = QVectorData::malloc(sizeOfTypedData(), aalloc, sizeof(T), p);
+ } else {
+ if (QTypeInfo<T>::isComplex) {
+ // call the destructor on all objects that need to be
+ // destroyed when shrinking
+ if (asize < d->size) {
+ j = d->array + asize;
+ i = d->array + d->size;
+ while (i-- != j)
+ i->~T();
+ i = d->array + asize;
+ }
+ }
+ x.p = p = static_cast<QVectorData *>(qRealloc(p, sizeOfTypedData() + (aalloc - 1) * sizeof(T)));
+ }
+ x.d->ref = 1;
+ x.d->sharable = true;
+ x.d->capacity = d->capacity;
+
+ }
+ if (QTypeInfo<T>::isComplex) {
+ if (asize < d->size) {
+ j = d->array + asize;
+ i = x.d->array + asize;
+ } else {
+ // construct all new objects when growing
+ i = x.d->array + asize;
+ j = x.d->array + d->size;
+ while (i != j)
+ new (--i) T;
+ j = d->array + d->size;
+ }
+ if (i != j) {
+ // copy objects from the old array into the new array
+ b = x.d->array;
+ while (i != b)
+ new (--i) T(*--j);
+ }
+ } else if (asize > d->size) {
+ // initialize newly allocated memory to 0
+ qMemSet(x.d->array + d->size, 0, (asize - d->size) * sizeof(T));
+ }
+ x.d->size = asize;
+ x.d->alloc = aalloc;
+ if (d != x.d) {
+ if (!d->ref.deref())
+ free(d);
+ d = x.d;
+ }
+}
+
+template<typename T>
+Q_OUTOFLINE_TEMPLATE T QVector<T>::value(int i) const
+{
+ if (i < 0 || i >= p->size) {
+ return T();
+ }
+ return d->array[i];
+}
+template<typename T>
+Q_OUTOFLINE_TEMPLATE T QVector<T>::value(int i, const T &defaultValue) const
+{
+ return ((i < 0 || i >= p->size) ? defaultValue : d->array[i]);
+}
+
+template <typename T>
+void QVector<T>::append(const T &t)
+{
+ if (d->ref != 1 || d->size + 1 > d->alloc) {
+ const T copy(t);
+ realloc(d->size, QVectorData::grow(sizeOfTypedData(), d->size + 1, sizeof(T),
+ QTypeInfo<T>::isStatic));
+ if (QTypeInfo<T>::isComplex)
+ new (d->array + d->size) T(copy);
+ else
+ d->array[d->size] = copy;
+ } else {
+ if (QTypeInfo<T>::isComplex)
+ new (d->array + d->size) T(t);
+ else
+ d->array[d->size] = t;
+ }
+ ++d->size;
+}
+
+template <typename T>
+Q_TYPENAME QVector<T>::iterator QVector<T>::insert(iterator before, size_type n, const T &t)
+{
+ int offset = before - d->array;
+ if (n != 0) {
+ const T copy(t);
+ if (d->ref != 1 || d->size + n > d->alloc)
+ realloc(d->size, QVectorData::grow(sizeOfTypedData(), d->size + n, sizeof(T),
+ QTypeInfo<T>::isStatic));
+ if (QTypeInfo<T>::isStatic) {
+ T *b = d->array + d->size;
+ T *i = d->array + d->size + n;
+ while (i != b)
+ new (--i) T;
+ i = d->array + d->size;
+ T *j = i + n;
+ b = d->array + offset;
+ while (i != b)
+ *--j = *--i;
+ i = b+n;
+ while (i != b)
+ *--i = copy;
+ } else {
+ T *b = d->array + offset;
+ T *i = b + n;
+ memmove(i, b, (d->size - offset) * sizeof(T));
+ while (i != b)
+ new (--i) T(copy);
+ }
+ d->size += n;
+ }
+ return d->array + offset;
+}
+
+template <typename T>
+Q_TYPENAME QVector<T>::iterator QVector<T>::erase(iterator abegin, iterator aend)
+{
+ int f = abegin - d->array;
+ int l = aend - d->array;
+ int n = l - f;
+ detach();
+ if (QTypeInfo<T>::isComplex) {
+ qCopy(d->array+l, d->array+d->size, d->array+f);
+ T *i = d->array+d->size;
+ T* b = d->array+d->size-n;
+ while (i != b) {
+ --i;
+ i->~T();
+ }
+ } else {
+ memmove(d->array + f, d->array + l, (d->size-l)*sizeof(T));
+ }
+ d->size -= n;
+ return d->array + f;
+}
+
+template <typename T>
+bool QVector<T>::operator==(const QVector<T> &v) const
+{
+ if (d->size != v.d->size)
+ return false;
+ if (d == v.d)
+ return true;
+ T* b = d->array;
+ T* i = b + d->size;
+ T* j = v.d->array + d->size;
+ while (i != b)
+ if (!(*--i == *--j))
+ return false;
+ return true;
+}
+
+template <typename T>
+QVector<T> &QVector<T>::fill(const T &from, int asize)
+{
+ const T copy(from);
+ resize(asize < 0 ? d->size : asize);
+ if (d->size) {
+ T *i = d->array + d->size;
+ T *b = d->array;
+ while (i != b)
+ *--i = copy;
+ }
+ return *this;
+}
+
+template <typename T>
+QVector<T> &QVector<T>::operator+=(const QVector &l)
+{
+ int newSize = d->size + l.d->size;
+ realloc(d->size, newSize);
+
+ T *w = d->array + newSize;
+ T *i = l.d->array + l.d->size;
+ T *b = l.d->array;
+ while (i != b) {
+ if (QTypeInfo<T>::isComplex)
+ new (--w) T(*--i);
+ else
+ *--w = *--i;
+ }
+ d->size = newSize;
+ return *this;
+}
+
+template <typename T>
+int QVector<T>::indexOf(const T &t, int from) const
+{
+ if (from < 0)
+ from = qMax(from + d->size, 0);
+ if (from < d->size) {
+ T* n = d->array + from - 1;
+ T* e = d->array + d->size;
+ while (++n != e)
+ if (*n == t)
+ return n - d->array;
+ }
+ return -1;
+}
+
+template <typename T>
+int QVector<T>::lastIndexOf(const T &t, int from) const
+{
+ if (from < 0)
+ from += d->size;
+ else if (from >= d->size)
+ from = d->size-1;
+ if (from >= 0) {
+ T* b = d->array;
+ T* n = d->array + from + 1;
+ while (n != b) {
+ if (*--n == t)
+ return n - b;
+ }
+ }
+ return -1;
+}
+
+template <typename T>
+bool QVector<T>::contains(const T &t) const
+{
+ T* b = d->array;
+ T* i = d->array + d->size;
+ while (i != b)
+ if (*--i == t)
+ return true;
+ return false;
+}
+
+template <typename T>
+int QVector<T>::count(const T &t) const
+{
+ int c = 0;
+ T* b = d->array;
+ T* i = d->array + d->size;
+ while (i != b)
+ if (*--i == t)
+ ++c;
+ return c;
+}
+
+template <typename T>
+Q_OUTOFLINE_TEMPLATE QVector<T> QVector<T>::mid(int pos, int length) const
+{
+ if (length < 0)
+ length = size() - pos;
+ if (pos == 0 && length == size())
+ return *this;
+ QVector<T> copy;
+ if (pos + length > size())
+ length = size() - pos;
+ for (int i = pos; i < pos + length; ++i)
+ copy += at(i);
+ return copy;
+}
+
+template <typename T>
+Q_OUTOFLINE_TEMPLATE QList<T> QVector<T>::toList() const
+{
+ QList<T> result;
+ for (int i = 0; i < size(); ++i)
+ result.append(at(i));
+ return result;
+}
+
+template <typename T>
+Q_OUTOFLINE_TEMPLATE QVector<T> QList<T>::toVector() const
+{
+ QVector<T> result(size());
+ for (int i = 0; i < size(); ++i)
+ result[i] = at(i);
+ return result;
+}
+
+template <typename T>
+QVector<T> QVector<T>::fromList(const QList<T> &list)
+{
+ return list.toVector();
+}
+
+template <typename T>
+QList<T> QList<T>::fromVector(const QVector<T> &vector)
+{
+ return vector.toList();
+}
+
+Q_DECLARE_SEQUENTIAL_ITERATOR(Vector)
+Q_DECLARE_MUTABLE_SEQUENTIAL_ITERATOR(Vector)
+
+/*
+ ### Qt 5:
+ ### This needs to be removed for next releases of Qt. It is a workaround for vc++ because
+ ### Qt exports QPolygon and QPolygonF that inherit QVector<QPoint> and
+ ### QVector<QPointF> respectively.
+*/
+
+#ifdef Q_CC_MSVC
+QT_BEGIN_INCLUDE_NAMESPACE
+#include <QtCore/QPointF>
+#include <QtCore/QPoint>
+QT_END_INCLUDE_NAMESPACE
+
+#if defined(QT_BUILD_CORE_LIB)
+#define Q_TEMPLATE_EXTERN
+#else
+#define Q_TEMPLATE_EXTERN extern
+#endif
+# pragma warning(push) /* MSVC 6.0 doesn't care about the disabling in qglobal.h (why?), so do it here */
+# pragma warning(disable: 4231) /* nonstandard extension used : 'extern' before template explicit instantiation */
+Q_TEMPLATE_EXTERN template class Q_CORE_EXPORT QVector<QPointF>;
+Q_TEMPLATE_EXTERN template class Q_CORE_EXPORT QVector<QPoint>;
+# pragma warning(pop)
+#endif
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QVECTOR_H
diff --git a/src/corelib/tools/qvsnprintf.cpp b/src/corelib/tools/qvsnprintf.cpp
new file mode 100644
index 0000000000..31b8632801
--- /dev/null
+++ b/src/corelib/tools/qvsnprintf.cpp
@@ -0,0 +1,133 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qplatformdefs.h"
+
+#include "qbytearray.h"
+#include "qstring.h"
+
+#include "string.h"
+
+QT_BEGIN_NAMESPACE
+
+#ifndef QT_VSNPRINTF
+
+/*!
+ \relates QByteArray
+
+ A portable \c vsnprintf() function. Will call \c ::vsnprintf(), \c
+ ::_vsnprintf(), or \c ::vsnprintf_s depending on the system, or
+ fall back to an internal version.
+
+ \a fmt is the \c printf() format string. The result is put into
+ \a str, which is a buffer of at least \a n bytes.
+
+ The caller is responsible to call \c va_end() on \a ap.
+
+ \warning Since vsnprintf() shows different behavior on certain
+ platforms, you should not rely on the return value or on the fact
+ that you will always get a 0 terminated string back.
+
+ Ideally, you should never call this function but use QString::sprintf()
+ instead.
+
+ \sa qsnprintf(), QString::sprintf()
+*/
+
+int qvsnprintf(char *str, size_t n, const char *fmt, va_list ap)
+{
+ if (!str || !fmt)
+ return -1;
+
+ QString buf;
+ buf.vsprintf(fmt, ap);
+
+ QByteArray ba = buf.toLocal8Bit();
+
+ if (n > 0) {
+ size_t blen = qMin(size_t(ba.length()), size_t(n - 1));
+ memcpy(str, ba.constData(), blen);
+ str[blen] = '\0'; // make sure str is always 0 terminated
+ }
+
+ return ba.length();
+}
+
+#else
+
+QT_BEGIN_INCLUDE_NAMESPACE
+#include <stdio.h>
+QT_END_INCLUDE_NAMESPACE
+
+int qvsnprintf(char *str, size_t n, const char *fmt, va_list ap)
+{
+ return QT_VSNPRINTF(str, n, fmt, ap);
+}
+
+#endif
+
+/*!
+ \relates QByteArray
+
+ A portable snprintf() function, calls qvsnprintf.
+
+ \a fmt is the \c printf() format string. The result is put into
+ \a str, which is a buffer of at least \a n bytes.
+
+ \warning Call this function only when you know what you are doing
+ since it shows different behavior on certain platforms.
+ Use QString::sprintf() to format a string instead.
+
+ \sa qvsnprintf(), QString::sprintf()
+*/
+
+int qsnprintf(char *str, size_t n, const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+
+ int ret = qvsnprintf(str, n, fmt, ap);
+ va_end(ap);
+
+ return ret;
+}
+
+QT_END_NAMESPACE
diff --git a/src/corelib/tools/tools.pri b/src/corelib/tools/tools.pri
new file mode 100644
index 0000000000..e5bf7e4a2f
--- /dev/null
+++ b/src/corelib/tools/tools.pri
@@ -0,0 +1,104 @@
+# Qt tools module
+
+HEADERS += \
+ tools/qalgorithms.h \
+ tools/qbitarray.h \
+ tools/qbytearray.h \
+ tools/qbytearraymatcher.h \
+ tools/qcache.h \
+ tools/qchar.h \
+ tools/qcontainerfwd.h \
+ tools/qcryptographichash.h \
+ tools/qdatetime.h \
+ tools/qdatetime_p.h \
+ tools/qhash.h \
+ tools/qline.h \
+ tools/qlinkedlist.h \
+ tools/qlist.h \
+ tools/qlocale.h \
+ tools/qlocale_p.h \
+ tools/qlocale_data_p.h \
+ tools/qmap.h \
+ tools/qpodlist_p.h \
+ tools/qpoint.h \
+ tools/qqueue.h \
+ tools/qrect.h \
+ tools/qregexp.h \
+ tools/qringbuffer_p.h \
+ tools/qshareddata.h \
+ tools/qset.h \
+ tools/qsize.h \
+ tools/qstack.h \
+ tools/qstring.h \
+ tools/qstringlist.h \
+ tools/qstringmatcher.h \
+ tools/qtextboundaryfinder.h \
+ tools/qtimeline.h \
+ tools/qunicodetables_p.h \
+ tools/qvarlengtharray.h \
+ tools/qvector.h
+
+
+SOURCES += \
+ tools/qbitarray.cpp \
+ tools/qbytearray.cpp \
+ tools/qbytearraymatcher.cpp \
+ tools/qcryptographichash.cpp \
+ tools/qdatetime.cpp \
+ tools/qdumper.cpp \
+ tools/qhash.cpp \
+ tools/qline.cpp \
+ tools/qlinkedlist.cpp \
+ tools/qlistdata.cpp \
+ tools/qlocale.cpp \
+ tools/qpoint.cpp \
+ tools/qmap.cpp \
+ tools/qrect.cpp \
+ tools/qregexp.cpp \
+ tools/qshareddata.cpp \
+ tools/qsharedpointer.cpp \
+ tools/qsize.cpp \
+ tools/qstring.cpp \
+ tools/qstringlist.cpp \
+ tools/qtextboundaryfinder.cpp \
+ tools/qtimeline.cpp \
+ tools/qvector.cpp \
+ tools/qvsnprintf.cpp
+
+
+#zlib support
+contains(QT_CONFIG, zlib) {
+ wince*: DEFINES += NO_ERRNO_H
+ INCLUDEPATH += ../3rdparty/zlib
+ SOURCES+= \
+ ../3rdparty/zlib/adler32.c \
+ ../3rdparty/zlib/compress.c \
+ ../3rdparty/zlib/crc32.c \
+ ../3rdparty/zlib/deflate.c \
+ ../3rdparty/zlib/gzio.c \
+ ../3rdparty/zlib/inffast.c \
+ ../3rdparty/zlib/inflate.c \
+ ../3rdparty/zlib/inftrees.c \
+ ../3rdparty/zlib/trees.c \
+ ../3rdparty/zlib/uncompr.c \
+ ../3rdparty/zlib/zutil.c
+} else:!contains(QT_CONFIG, no-zlib) {
+ unix:LIBS += -lz
+# win32:LIBS += libz.lib
+}
+
+DEFINES += HB_EXPORT=Q_CORE_EXPORT
+INCLUDEPATH += ../3rdparty/harfbuzz/src
+HEADERS += ../3rdparty/harfbuzz/src/harfbuzz.h
+SOURCES += ../3rdparty/harfbuzz/src/harfbuzz-buffer.c \
+ ../3rdparty/harfbuzz/src/harfbuzz-gdef.c \
+ ../3rdparty/harfbuzz/src/harfbuzz-gsub.c \
+ ../3rdparty/harfbuzz/src/harfbuzz-gpos.c \
+ ../3rdparty/harfbuzz/src/harfbuzz-impl.c \
+ ../3rdparty/harfbuzz/src/harfbuzz-open.c \
+ ../3rdparty/harfbuzz/src/harfbuzz-stream.c \
+ ../3rdparty/harfbuzz/src/harfbuzz-shaper-all.cpp \
+ tools/qharfbuzz.cpp
+HEADERS += tools/qharfbuzz_p.h
+
+!macx-icc:unix:LIBS += -lm