qt 6.5.1 original

This commit is contained in:
kleuter
2023-10-29 23:33:08 +01:00
parent 71d22ab6b0
commit 85d238dfda
21202 changed files with 5499099 additions and 0 deletions

View File

@ -0,0 +1,29 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
add_subdirectory(qanystringview)
add_subdirectory(qbytearray)
add_subdirectory(qbytearray_large)
add_subdirectory(qbytearrayapisymmetry)
add_subdirectory(qbytearraylist)
add_subdirectory(qbytearraymatcher)
add_subdirectory(qbytearrayview)
add_subdirectory(qbytedatabuffer)
add_subdirectory(qchar)
add_subdirectory(qcollator)
add_subdirectory(qlatin1stringmatcher)
add_subdirectory(qlatin1stringview)
add_subdirectory(qregularexpression)
add_subdirectory(qstring)
add_subdirectory(qstring_no_cast_from_bytearray)
add_subdirectory(qstringapisymmetry)
add_subdirectory(qstringbuilder)
add_subdirectory(qstringconverter)
add_subdirectory(qstringiterator)
add_subdirectory(qstringlist)
add_subdirectory(qstringmatcher)
add_subdirectory(qstringtokenizer)
add_subdirectory(qstringview)
add_subdirectory(qtextboundaryfinder)
add_subdirectory(qunicodetools)
add_subdirectory(qlocale)

View File

@ -0,0 +1,16 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qstringview Test:
#####################################################################
qt_internal_add_test(tst_qanystringview
SOURCES
tst_qanystringview.cpp
LIBRARIES
Qt::CorePrivate
)
## Scopes:
#####################################################################

View File

@ -0,0 +1,693 @@
// Copyright (C) 2021 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include <QAnyStringView>
#include <QChar>
#include <QList>
#include <QString>
#include <QStringBuilder>
#include <QVarLengthArray>
#if QT_CONFIG(cpp_winrt)
# include <private/qt_winrtbase_p.h>
#endif
#include <private/qxmlstream_p.h>
#include <QTest>
#include <string>
#include <string_view>
#include <array>
#include <vector>
#include <algorithm>
#include <memory>
#include <q20iterator.h>
// for negative testing (can't convert from)
#include <deque>
#include <list>
#ifdef __cpp_char8_t
# define ONLY_IF_CHAR_8_T(expr) expr
#else
# define ONLY_IF_CHAR_8_T(expr) \
QSKIP("This test requires C++20 char8_t support enabled in the compiler.")
#endif
#ifdef __cpp_lib_char8_t
# define ONLY_IF_LIB_CHAR_8_T(expr) expr
#else
# define ONLY_IF_LIB_CHAR_8_T(expr) \
QSKIP("This test requires C++20 char8_t support enabled in the standard library.")
#endif
#ifdef Q_OS_WIN
# define ONLY_WIN(expr) expr
#else
# define ONLY_WIN(expr) QSKIP("This is a Windows-only test")
#endif
#ifdef __cpp_impl_three_way_comparison
# define ONLY_3WAY(expr) expr
#else
# define ONLY_3WAY(expr) \
QSKIP("This test requires C++20 spaceship operator (<=>) " \
"support enabled in the standard library.")
#endif
using namespace Qt::StringLiterals;
template <typename T>
constexpr inline bool CanConvert = std::is_convertible_v<T, QAnyStringView>;
static_assert(CanConvert<QLatin1String>);
static_assert(CanConvert<const char*>);
static_assert(CanConvert<QByteArray>);
template <typename T>
struct ImplicitlyConvertibleTo
{
operator T() const;
};
static_assert(CanConvert<ImplicitlyConvertibleTo<QString>>);
static_assert(CanConvert<ImplicitlyConvertibleTo<QByteArray>>);
static_assert(!CanConvert<ImplicitlyConvertibleTo<QLatin1StringView>>);
// QAnyStringView qchar_does_not_compile() { return QAnyStringView(QChar('a')); }
// QAnyStringView qlatin1string_does_not_compile() { return QAnyStringView(QLatin1String("a")); }
// QAnyStringView const_char_star_does_not_compile() { return QAnyStringView("a"); }
// QAnyStringView qbytearray_does_not_compile() { return QAnyStringView(QByteArray("a")); }
//
// QChar
//
static_assert(CanConvert<QChar>);
static_assert(CanConvert<QChar[123]>);
static_assert(CanConvert< QString >);
static_assert(CanConvert<const QString >);
static_assert(CanConvert< QString&>);
static_assert(CanConvert<const QString&>);
//
// ushort
//
static_assert(CanConvert<ushort>);
static_assert(CanConvert<ushort[123]>);
static_assert(CanConvert< ushort*>);
static_assert(CanConvert<const ushort*>);
static_assert(CanConvert<QList<ushort>>);
static_assert(CanConvert<QVarLengthArray<ushort>>);
static_assert(CanConvert<std::vector<ushort>>);
static_assert(CanConvert<std::array<ushort, 123>>);
static_assert(!CanConvert<std::deque<ushort>>);
static_assert(!CanConvert<std::list<ushort>>);
#ifdef __cpp_char8_t
//
// char8_t
//
static_assert(CanConvert<char8_t>);
static_assert(CanConvert< char8_t*>);
static_assert(CanConvert<const char8_t*>);
#ifdef __cpp_lib_char8_t
static_assert(CanConvert< std::u8string >);
static_assert(CanConvert<const std::u8string >);
static_assert(CanConvert< std::u8string&>);
static_assert(CanConvert<const std::u8string&>);
static_assert(CanConvert< std::u8string_view >);
static_assert(CanConvert<const std::u8string_view >);
static_assert(CanConvert< std::u8string_view&>);
static_assert(CanConvert<const std::u8string_view&>);
#endif // __cpp_lib_char8_t
static_assert(CanConvert<QList<char8_t>>);
static_assert(CanConvert<QVarLengthArray<char8_t>>);
static_assert(CanConvert<std::vector<char8_t>>);
static_assert(CanConvert<std::array<char8_t, 123>>);
static_assert(!CanConvert<std::deque<char8_t>>);
static_assert(!CanConvert<std::list<char8_t>>);
#endif // __cpp_char8_t
//
// char16_t
//
static_assert(CanConvert<char16_t>);
static_assert(CanConvert< char16_t*>);
static_assert(CanConvert<const char16_t*>);
static_assert(CanConvert< std::u16string >);
static_assert(CanConvert<const std::u16string >);
static_assert(CanConvert< std::u16string&>);
static_assert(CanConvert<const std::u16string&>);
static_assert(CanConvert< std::u16string_view >);
static_assert(CanConvert<const std::u16string_view >);
static_assert(CanConvert< std::u16string_view&>);
static_assert(CanConvert<const std::u16string_view&>);
static_assert(CanConvert<QList<char16_t>>);
static_assert(CanConvert<QVarLengthArray<char16_t>>);
static_assert(CanConvert<std::vector<char16_t>>);
static_assert(CanConvert<std::array<char16_t, 123>>);
static_assert(!CanConvert<std::deque<char16_t>>);
static_assert(!CanConvert<std::list<char16_t>>);
static_assert(CanConvert<QtPrivate::XmlStringRef>);
//
// char32_t
//
// Qt Policy: char32_t isn't supported
static_assert(CanConvert<char32_t>); // ... except here
static_assert(!CanConvert< char32_t*>);
static_assert(!CanConvert<const char32_t*>);
static_assert(!CanConvert< std::u32string >);
static_assert(!CanConvert<const std::u32string >);
static_assert(!CanConvert< std::u32string&>);
static_assert(!CanConvert<const std::u32string&>);
static_assert(!CanConvert< std::u32string_view >);
static_assert(!CanConvert<const std::u32string_view >);
static_assert(!CanConvert< std::u32string_view&>);
static_assert(!CanConvert<const std::u32string_view&>);
static_assert(!CanConvert<QList<char32_t>>);
static_assert(!CanConvert<QVarLengthArray<char32_t>>);
static_assert(!CanConvert<std::vector<char32_t>>);
static_assert(!CanConvert<std::array<char32_t, 123>>);
static_assert(!CanConvert<std::deque<char32_t>>);
static_assert(!CanConvert<std::list<char32_t>>);
//
// wchar_t
//
constexpr bool CanConvertFromWCharT =
#ifdef Q_OS_WIN
true
#else
false
#endif
;
static_assert(CanConvert<wchar_t> == CanConvertFromWCharT); // ### FIXME: should work everywhere
static_assert(CanConvert< wchar_t*> == CanConvertFromWCharT);
static_assert(CanConvert<const wchar_t*> == CanConvertFromWCharT);
static_assert(CanConvert< std::wstring > == CanConvertFromWCharT);
static_assert(CanConvert<const std::wstring > == CanConvertFromWCharT);
static_assert(CanConvert< std::wstring&> == CanConvertFromWCharT);
static_assert(CanConvert<const std::wstring&> == CanConvertFromWCharT);
static_assert(CanConvert< std::wstring_view > == CanConvertFromWCharT);
static_assert(CanConvert<const std::wstring_view > == CanConvertFromWCharT);
static_assert(CanConvert< std::wstring_view&> == CanConvertFromWCharT);
static_assert(CanConvert<const std::wstring_view&> == CanConvertFromWCharT);
static_assert(CanConvert<QList<wchar_t>> == CanConvertFromWCharT);
static_assert(CanConvert<QVarLengthArray<wchar_t>> == CanConvertFromWCharT);
static_assert(CanConvert<std::vector<wchar_t>> == CanConvertFromWCharT);
static_assert(CanConvert<std::array<wchar_t, 123>> == CanConvertFromWCharT);
static_assert(!CanConvert<std::deque<wchar_t>>);
static_assert(!CanConvert<std::list<wchar_t>>);
//
// QStringBuilder
//
static_assert(CanConvert<QStringBuilder<QString, QString>>);
#if QT_CONFIG(cpp_winrt)
//
// winrt::hstring (QTBUG-111886)
//
static_assert(CanConvert< winrt::hstring >);
static_assert(CanConvert<const winrt::hstring >);
static_assert(CanConvert< winrt::hstring&>);
static_assert(CanConvert<const winrt::hstring&>);
#endif // QT_CONFIG(cpp_winrt)
class tst_QAnyStringView : public QObject
{
Q_OBJECT
private Q_SLOTS:
void constExpr() const;
void basics() const;
void asciiLiteralIsLatin1() const;
void fromQString() const { fromQStringOrByteArray<QString>(); }
void fromQByteArray() const { fromQStringOrByteArray<QByteArray>(); }
void fromCharArray() const { fromArray<char>(); }
void fromChar8Array() const { ONLY_IF_CHAR_8_T(fromArray<char8_t>()); }
void fromChar16Array() const { fromArray<char16_t>(); }
void fromQCharArray() const { fromArray<QChar>(); }
void fromWCharTArray() const { ONLY_WIN(fromArray<wchar_t>()); }
void fromQCharStar() const
{
const QChar str[] = { 'H', 'e', 'l', 'l', 'o', ',', ' ', 'W', 'o', 'r', 'l', 'd', '!', '\0' };
fromLiteral(str);
}
void fromUShortStar() const
{
const ushort str[] = { 'H', 'e', 'l', 'l', 'o', ',', ' ', 'W', 'o', 'r', 'l', 'd', '!', '\0' };
fromLiteral(str);
}
void fromChar8TStar() const
{
fromLiteral(u8"Hello, World!"); // char[] in <= C++17, char8_t[] in >= C++20
}
void fromChar16TStar() const { fromLiteral(u"Hello, World!"); }
void fromWCharTStar() const { ONLY_WIN(fromLiteral(L"Hello, World!")); }
void fromQCharRange() const
{
const QChar str[] = { 'H', 'e', 'l', 'l', 'o', ',', ' ', 'W', 'o', 'r', 'l', 'd', '!' };
fromRange(std::begin(str), std::end(str));
}
void fromUShortRange() const
{
const ushort str[] = { 'H', 'e', 'l', 'l', 'o', ',', ' ', 'W', 'o', 'r', 'l', 'd', '!' };
fromRange(std::begin(str), std::end(str));
}
void fromChar16TRange() const
{
const char16_t str[] = { 'H', 'e', 'l', 'l', 'o', ',', ' ', 'W', 'o', 'r', 'l', 'd', '!' };
fromRange(std::begin(str), std::end(str));
}
void fromWCharTRange() const
{
[[maybe_unused]] const wchar_t str[] = { 'H', 'e', 'l', 'l', 'o', ',', ' ', 'W', 'o', 'r', 'l', 'd', '!' };
ONLY_WIN(fromRange(std::begin(str), std::end(str)));
}
// std::basic_string
void fromStdStringChar() const { fromStdString<char>(); }
void fromStdStringChar8T() const { ONLY_IF_LIB_CHAR_8_T(fromStdString<char8_t>()); }
void fromStdStringWCharT() const { ONLY_WIN(fromStdString<wchar_t>()); }
void fromStdStringChar16T() const { fromStdString<char16_t>(); }
void fromUShortContainers() const { fromContainers<ushort>(); }
void fromQCharContainers() const { fromContainers<QChar>(); }
void fromChar16TContainers() const { fromContainers<char16_t>(); }
void fromWCharTContainers() const { ONLY_WIN(fromContainers<wchar_t>()); }
void fromQStringBuilder_QString_QString() const { fromQStringBuilder(u"1"_s % u"2"_s, u"12"); }
void comparison();
void compare3way();
private:
template <typename StringBuilder>
void fromQStringBuilder(StringBuilder &&sb, QStringView expected) const;
template <typename Char>
void fromArray() const;
template <typename String>
void conversion_tests(String arg) const;
template <typename Char>
void fromLiteral(const Char *arg) const;
template <typename Char>
void fromRange(const Char *first, const Char *last) const;
template <typename Char, typename Container>
void fromContainer() const;
template <typename Char>
void fromContainers() const;
template <typename Char>
void fromStdString() const { fromContainer<Char, std::basic_string<Char> >(); }
template <typename QStringOrByteArray>
void fromQStringOrByteArray() const;
};
void tst_QAnyStringView::constExpr() const
{
#define IS_NULL(sv) \
do { \
static_assert(sv.size() == 0); \
static_assert(sv.isNull()); \
static_assert(sv.empty()); \
static_assert(sv.isEmpty()); \
static_assert(sv.data() == nullptr); \
} while (false) \
/*end*/
#define IS_EMPTY(sv) \
do { \
static_assert(sv.size() == 0); \
static_assert(!sv.isNull()); \
static_assert(sv.empty()); \
static_assert(sv.isEmpty()); \
static_assert(sv.data() != nullptr); \
} while (false) \
/*end*/
#define IS_OF_SIZE(sv, sz) \
do { \
static_assert(sv.size() == sz); \
static_assert(!sv.isNull()); \
static_assert(!sv.empty()); \
static_assert(!sv.isEmpty()); \
static_assert(sv.data() != nullptr); \
} while (false) \
/*end*/
// compile-time checks
{
constexpr QAnyStringView sv;
IS_NULL(sv);
}
{
constexpr const char *nul = nullptr;
constexpr QAnyStringView sv(nul, 0);
IS_NULL(sv);
}
{
constexpr const char16_t *nul = nullptr;
constexpr QAnyStringView sv(nul, 0);
IS_NULL(sv);
}
#ifdef __cpp_char8_t
{
constexpr const char8_t *nul = nullptr;
constexpr QAnyStringView sv(nul, 0);
IS_NULL(sv);
}
#endif // __cpp_char8_t
{
constexpr QAnyStringView sv = nullptr;
IS_NULL(sv);
}
{
constexpr QAnyStringView sv = "";
IS_EMPTY(sv);
}
{
constexpr QAnyStringView sv = u8"";
IS_EMPTY(sv);
}
{
constexpr QAnyStringView sv = u"";
IS_EMPTY(sv);
}
{
constexpr QAnyStringView sv = u"Hello";
IS_OF_SIZE(sv, 5);
constexpr QAnyStringView sv2 = sv;
IS_OF_SIZE(sv2, 5);
}
#undef IS_OF_SIZE
#undef IS_EMPTY
#undef IS_NULL
}
void tst_QAnyStringView::basics() const
{
QAnyStringView sv1;
// a default-constructed QAnyStringView is null:
QVERIFY(sv1.isNull());
// which implies it's empty();
QVERIFY(sv1.isEmpty());
QAnyStringView sv2;
QVERIFY(sv2 == sv1);
QVERIFY(!(sv2 != sv1));
}
void tst_QAnyStringView::asciiLiteralIsLatin1() const
{
if constexpr (QAnyStringView::detects_US_ASCII_at_compile_time) {
constexpr bool asciiCstringIsLatin1 = QAnyStringView("Hello, World").isLatin1();
QVERIFY(asciiCstringIsLatin1);
constexpr bool asciiUtf8stringIsLatin1 = QAnyStringView(u8"Hello, World").isLatin1();
QVERIFY(asciiUtf8stringIsLatin1);
constexpr bool utf8StringIsNotLatin1 = !QAnyStringView(u8"Tørrfisk").isLatin1();
QVERIFY(utf8StringIsNotLatin1);
constexpr bool asciiCstringArrayIsLatin1 =
QAnyStringView::fromArray("Hello, World").isLatin1();
QVERIFY(asciiCstringArrayIsLatin1);
constexpr bool asciiUtfstringArrayIsLatin1 =
QAnyStringView::fromArray(u8"Hello, World").isLatin1();
QVERIFY(asciiUtfstringArrayIsLatin1);
constexpr bool utf8StringArrayIsNotLatin1 =
!QAnyStringView::fromArray(u8"Tørrfisk").isLatin1();
QVERIFY(utf8StringArrayIsNotLatin1);
}
}
template <typename StringBuilder>
void tst_QAnyStringView::fromQStringBuilder(StringBuilder &&sb, QStringView expected) const
{
auto toAnyStringView = [](QAnyStringView sv) { return sv; };
QCOMPARE(toAnyStringView(std::forward<StringBuilder>(sb)), expected);
}
template <typename Char>
void tst_QAnyStringView::fromArray() const
{
constexpr Char hello[] = {'H', 'e', 'l', 'l', 'o', '\0', 'a', 'b', 'c', '\0', '\0', '.', '\0'};
QAnyStringView sv = QAnyStringView::fromArray(hello);
QCOMPARE(sv.size(), 13);
QVERIFY(!sv.empty());
QVERIFY(!sv.isEmpty());
QVERIFY(!sv.isNull());
QCOMPARE(sv.front(), 'H');
QCOMPARE(sv.back(), '\0');
const Char bytes[] = {'a', 'b', 'c'};
QAnyStringView sv2 = QAnyStringView::fromArray(bytes);
QCOMPARE(sv2.data(), static_cast<const void *>(bytes + 0));
QCOMPARE(sv2.size(), 3);
QCOMPARE(sv2.back(), u'c');
}
template <typename QStringOrByteArray>
void tst_QAnyStringView::fromQStringOrByteArray() const
{
QStringOrByteArray null;
QStringOrByteArray empty = "";
QVERIFY( QAnyStringView(null).isNull());
QVERIFY( QAnyStringView(null).isEmpty());
QVERIFY( QAnyStringView(empty).isEmpty());
QVERIFY(!QAnyStringView(empty).isNull());
conversion_tests(QStringOrByteArray("Hello World!"));
}
template <typename Char>
void tst_QAnyStringView::fromLiteral(const Char *arg) const
{
const Char *null = nullptr;
const Char empty[] = { Char{} };
QCOMPARE(QAnyStringView(null).size(), qsizetype(0));
QCOMPARE(QAnyStringView(null).data(), nullptr);
QCOMPARE(QAnyStringView(empty).size(), qsizetype(0));
QCOMPARE(static_cast<const void*>(QAnyStringView(empty).data()),
static_cast<const void*>(empty));
QVERIFY( QAnyStringView(null).isNull());
QVERIFY( QAnyStringView(null).isEmpty());
QVERIFY( QAnyStringView(empty).isEmpty());
QVERIFY(!QAnyStringView(empty).isNull());
conversion_tests(arg);
}
template <typename Char>
void tst_QAnyStringView::fromRange(const Char *first, const Char *last) const
{
const Char *null = nullptr;
QCOMPARE(QAnyStringView(null, null).size(), 0);
QCOMPARE(QAnyStringView(null, null).data(), nullptr);
QCOMPARE(QAnyStringView(first, first).size(), 0);
QCOMPARE(static_cast<const void*>(QAnyStringView(first, first).data()),
static_cast<const void*>(first));
const auto sv = QAnyStringView(first, last);
QCOMPARE(sv.size(), last - first);
QCOMPARE(static_cast<const void*>(sv.data()),
static_cast<const void*>(first));
// can't call conversion_tests() here, as it requires a single object
}
template <typename Char, typename Container>
void tst_QAnyStringView::fromContainer() const
{
const std::string s = "Hello World!";
Container c;
// unspecified whether empty containers make null QAnyStringViews
QVERIFY(QAnyStringView(c).isEmpty());
std::copy(s.begin(), s.end(), std::back_inserter(c));
conversion_tests(std::move(c));
}
template <typename Char>
void tst_QAnyStringView::fromContainers() const
{
fromContainer<Char, QList<Char>>();
fromContainer<Char, QVarLengthArray<Char>>();
fromContainer<Char, std::vector<Char>>();
}
namespace help {
template <typename T>
auto ssize(T &t) { return q20::ssize(t); }
template <typename T>
qsizetype ssize(const T *t)
{
qsizetype result = 0;
if (t) {
while (*t++)
++result;
}
return result;
}
qsizetype ssize(const QChar *t)
{
qsizetype result = 0;
if (t) {
while (!t++->isNull())
++result;
}
return result;
}
}
template <typename String>
void tst_QAnyStringView::conversion_tests(String string) const
{
// copy-construct:
{
QAnyStringView sv = string;
QCOMPARE(help::ssize(sv), help::ssize(string));
QCOMPARE(sv, string);
}
QAnyStringView sv;
// copy-assign:
{
sv = string;
QCOMPARE(help::ssize(sv), help::ssize(string));
// check relational operators:
QCOMPARE(sv, string);
QCOMPARE(string, sv);
QVERIFY(!(sv != string));
QVERIFY(!(string != sv));
QVERIFY(!(sv < string));
QVERIFY(sv <= string);
QVERIFY(!(sv > string));
QVERIFY(sv >= string);
QVERIFY(!(string < sv));
QVERIFY(string <= sv);
QVERIFY(!(string > sv));
QVERIFY(string >= sv);
}
// copy-construct from rvalue (QAnyStringView never assumes ownership):
{
QAnyStringView sv2 = std::move(string);
QCOMPARE(sv2, sv);
QCOMPARE(sv2, string);
}
// copy-assign from rvalue (QAnyStringView never assumes ownership):
{
QAnyStringView sv2;
sv2 = std::move(string);
QCOMPARE(sv2, sv);
QCOMPARE(sv2, string);
}
}
void tst_QAnyStringView::comparison()
{
const QAnyStringView aa = u"aa";
const QAnyStringView upperAa = u"AA";
const QAnyStringView bb = u"bb";
QVERIFY(aa == aa);
QVERIFY(aa != bb);
QVERIFY(aa < bb);
QVERIFY(bb > aa);
QCOMPARE(QAnyStringView::compare(aa, aa), 0);
QVERIFY(QAnyStringView::compare(aa, upperAa) != 0);
QCOMPARE(QAnyStringView::compare(aa, upperAa, Qt::CaseInsensitive), 0);
QVERIFY(QAnyStringView::compare(aa, bb) < 0);
QVERIFY(QAnyStringView::compare(bb, aa) > 0);
}
void tst_QAnyStringView::compare3way()
{
#define COMPARE_3WAY(lhs, rhs, res) \
do { \
const auto qt_3way_cmp_res = (lhs) <=> (rhs); \
static_assert(std::is_same_v<decltype(qt_3way_cmp_res), decltype(res)>); \
QCOMPARE(std::is_eq(qt_3way_cmp_res), std::is_eq(res)); \
QCOMPARE(std::is_lt(qt_3way_cmp_res), std::is_lt(res)); \
QCOMPARE(std::is_gt(qt_3way_cmp_res), std::is_gt(res)); \
} while (false)
ONLY_3WAY(
const QAnyStringView aa = u"aa";
const QAnyStringView upperAa = u"AA";
const QAnyStringView bb = u"bb";
COMPARE_3WAY(aa, aa, std::strong_ordering::equal);
COMPARE_3WAY(aa, bb, std::strong_ordering::less);
COMPARE_3WAY(bb, aa, std::strong_ordering::greater)
);
#undef COMPARE_3WAY
}
QTEST_APPLESS_MAIN(tst_QAnyStringView)
#include "tst_qanystringview.moc"

View File

@ -0,0 +1,23 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qbytearray Test:
#####################################################################
qt_internal_add_test(tst_qbytearray
SOURCES
tst_qbytearray.cpp
LIBRARIES
Qt::CorePrivate
)
## Scopes:
#####################################################################
qt_internal_extend_target(tst_qbytearray CONDITION APPLE
SOURCES
tst_qbytearray_mac.mm
LIBRARIES
${FWFoundation}
)

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,74 @@
// Copyright (C) 2014 Samuel Gaist <samuel.gaist@edeltech.ch>
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include <QtCore/QByteArray>
#include <QTest>
#include <QtCore/private/qcore_mac_p.h>
#include <CoreFoundation/CoreFoundation.h>
#include <Foundation/Foundation.h>
void tst_QByteArray_macTypes()
{
// QByteArray <-> CFData
{
QByteArray qtByteArray("test bytearray");
const CFDataRef cfData = qtByteArray.toCFData();
QCOMPARE(QByteArray::fromCFData(cfData), qtByteArray);
CFRelease(cfData);
}
{
QByteArray qtByteArray("test bytearray");
const CFDataRef cfData = qtByteArray.toCFData();
QByteArray qtByteArrayCopy(qtByteArray);
qtByteArray = qtByteArray.toUpper(); // modify
QCOMPARE(QByteArray::fromCFData(cfData), qtByteArrayCopy);
}
// QByteArray <-> CFData Raw
{
QByteArray qtByteArray("test bytearray");
const CFDataRef cfData = qtByteArray.toRawCFData();
const UInt8 * cfDataPtr = CFDataGetBytePtr(cfData);
QCOMPARE(reinterpret_cast<const UInt8*>(qtByteArray.constData()), cfDataPtr);
CFRelease(cfData);
}
{
const UInt8 data[] = "cfdata test";
const CFDataRef cfData = CFDataCreate(kCFAllocatorDefault, data, sizeof(data));
const UInt8 * cfDataPtr = CFDataGetBytePtr(cfData);
QByteArray qtByteArray = QByteArray::fromRawCFData(cfData);
QCOMPARE(reinterpret_cast<const UInt8*>(qtByteArray.constData()), cfDataPtr);
CFRelease(cfData);
}
// QByteArray <-> NSData
{
QMacAutoReleasePool pool;
QByteArray qtByteArray("test bytearray");
const NSData *nsData = qtByteArray.toNSData();
QCOMPARE(QByteArray::fromNSData(nsData), qtByteArray);
}
{
QMacAutoReleasePool pool;
QByteArray qtByteArray("test bytearray");
const NSData *nsData = qtByteArray.toNSData();
QByteArray qtByteArrayCopy(qtByteArray);
qtByteArray = qtByteArray.toUpper(); // modify
QCOMPARE(QByteArray::fromNSData(nsData), qtByteArrayCopy);
}
// QByteArray <-> NSData Raw
{
QMacAutoReleasePool pool;
QByteArray qtByteArray("test bytearray");
const NSData *nsData = qtByteArray.toRawNSData();
QCOMPARE([nsData bytes], qtByteArray.constData());
}
{
QMacAutoReleasePool pool;
const char data[] = "nsdata test";
const NSData *nsData = [NSData dataWithBytes:data length:sizeof(data)];
QByteArray qtByteArray = QByteArray::fromRawNSData(nsData);
QCOMPARE(qtByteArray.constData(), [nsData bytes]);
}
}

View File

@ -0,0 +1,11 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
qt_internal_add_test(tst_qbytearray_large
SOURCES
tst_qbytearray_large.cpp
LIBRARIES
Qt::Core
TESTDATA "rfc3252.txt"
)

View File

@ -0,0 +1,899 @@
Network Working Group H. Kennedy
Request for Comments: 3252 Mimezine
Category: Informational 1 April 2002
Binary Lexical Octet Ad-hoc Transport
Status of this Memo
This memo provides information for the Internet community. It does
not specify an Internet standard of any kind. Distribution of this
memo is unlimited.
Copyright Notice
Copyright (C) The Internet Society (2002). All Rights Reserved.
Abstract
This document defines a reformulation of IP and two transport layer
protocols (TCP and UDP) as XML applications.
1. Introduction
1.1. Overview
This document describes the Binary Lexical Octet Ad-hoc Transport
(BLOAT): a reformulation of a widely-deployed network-layer protocol
(IP [RFC791]), and two associated transport layer protocols (TCP
[RFC793] and UDP [RFC768]) as XML [XML] applications. It also
describes methods for transporting BLOAT over Ethernet and IEEE 802
networks as well as encapsulating BLOAT in IP for gatewaying BLOAT
across the public Internet.
1.2. Motivation
The wild popularity of XML as a basis for application-level protocols
such as the Blocks Extensible Exchange Protocol [RFC3080], the Simple
Object Access Protocol [SOAP], and Jabber [JABBER] prompted
investigation into the possibility of extending the use of XML in the
protocol stack. Using XML at both the transport and network layer in
addition to the application layer would provide for an amazing amount
of power and flexibility while removing dependencies on proprietary
and hard-to-understand binary protocols. This protocol unification
would also allow applications to use a single XML parser for all
aspects of their operation, eliminating developer time spent figuring
out the intricacies of each new protocol, and moving the hard work of
Kennedy Informational [Page 1]
RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002
parsing to the XML toolset. The use of XML also mitigates concerns
over "network vs. host" byte ordering which is at the root of many
network application bugs.
1.3. Relation to Existing Protocols
The reformulations specified in this RFC follow as closely as
possible the spirit of the RFCs on which they are based, and so MAY
contain elements or attributes that would not be needed in a pure
reworking (e.g. length attributes, which are implicit in XML.)
The layering of network and transport protocols are maintained in
this RFC despite the optimizations that could be made if the line
were somewhat blurred (i.e. merging TCP and IP into a single, larger
element in the DTD) in order to foster future use of this protocol as
a basis for reformulating other protocols (such as ICMP.)
Other than the encoding, the behavioral aspects of each of the
existing protocols remain unchanged. Routing, address spaces, TCP
congestion control, etc. behave as specified in the extant standards.
Adapting to new standards and experimental algorithm heuristics for
improving performance will become much easier once the move to BLOAT
has been completed.
1.4. Requirement Levels
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
document are to be interpreted as described in BCP 14, RFC 2119
[RFC2119].
2. IPoXML
This protocol MUST be implemented to be compliant with this RFC.
IPoXML is the root protocol REQUIRED for effective use of TCPoXML
(section 3.) and higher-level application protocols.
The DTD for this document type can be found in section 7.1.
The routing of IPoXML can be easily implemented on hosts with an XML
parser, as the regular structure lends itself handily to parsing and
validation of the document/datagram and then processing the
destination address, TTL, and checksum before sending it on to its
next-hop.
The reformulation of IPv4 was chosen over IPv6 [RFC2460] due to the
wider deployment of IPv4 and the fact that implementing IPv6 as XML
would have exceeded the 1500 byte Ethernet MTU.
Kennedy Informational [Page 2]
RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002
All BLOAT implementations MUST use - and specify - the UTF-8 encoding
of RFC 2279 [RFC2279]. All BLOAT document/datagrams MUST be well-
formed and include the XMLDecl.
2.1. IP Description
A number of items have changed (for the better) from the original IP
specification. Bit-masks, where present have been converted into
human-readable values. IP addresses are listed in their dotted-
decimal notation [RFC1123]. Length and checksum values are present
as decimal integers.
To calculate the length and checksum fields of the IP element, a
canonicalized form of the element MUST be used. The canonical form
SHALL have no whitespace (including newline characters) between
elements and only one space character between attributes. There
SHALL NOT be a space following the last attribute in an element.
An iterative method SHOULD be used to calculate checksums, as the
length field will vary based on the size of the checksum.
The payload element bears special attention. Due to the character
set restrictions of XML, the payload of IP datagrams (which MAY
contain arbitrary data) MUST be encoded for transport. This RFC
REQUIRES the contents of the payload to be encoded in the base-64
encoding of RFC 2045 [RFC2045], but removes the requirement that the
encoded output MUST be wrapped on 76-character lines.
Kennedy Informational [Page 3]
RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002
2.2. Example Datagram
The following is an example IPoXML datagram with an empty payload:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ip PUBLIC "-//IETF//DTD BLOAT 1.0 IP//EN" "bloat.dtd">
<ip>
<header length="474">
<version value="4"/>
<tos precedence="Routine" delay="Normal" throughput="Normal"
relibility="Normal" reserved="0"/>
<total.length value="461"/>
<id value="1"/>
<flags reserved="0" df="dont" mf="last"/>
<offset value="0"/>
<ttl value="255"/>
<protocol value="6"/>
<checksum value="8707"/>
<source address="10.0.0.22"/>
<destination address="10.0.0.1"/>
<options>
<end copied="0" class="0" number="0"/>
</options>
<padding pad="0"/>
</header>
<payload>
</payload>
</ip>
3. TCPoXML
This protocol MUST be implemented to be compliant with this RFC. The
DTD for this document type can be found in section 7.2.
3.1. TCP Description
A number of items have changed from the original TCP specification.
Bit-masks, where present have been converted into human-readable
values. Length and checksum and port values are present as decimal
integers.
To calculate the length and checksum fields of the TCP element, a
canonicalized form of the element MUST be used as in section 2.1.
An iterative method SHOULD be used to calculate checksums as in
section 2.1.
The payload element MUST be encoded as in section 2.1.
Kennedy Informational [Page 4]
RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002
The TCP offset element was expanded to a maximum of 255 from 16 to
allow for the increased size of the header in XML.
TCPoXML datagrams encapsulated by IPoXML MAY omit the <?xml?> header
as well as the <!DOCTYPE> declaration.
3.2. Example Datagram
The following is an example TCPoXML datagram with an empty payload:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE tcp PUBLIC "-//IETF//DTD BLOAT 1.0 TCP//EN" "bloat.dtd">
<tcp>
<tcp.header>
<src port="31415"/>
<dest port="42424"/>
<sequence number="322622954"/>
<acknowledgement number="689715995"/>
<offset number=""/>
<reserved value="0"/>
<control syn="1" ack="1"/>
<window size="1"/>
<urgent pointer="0"/>
<checksum value="2988"/>
<tcp.options>
<tcp.end kind="0"/>
</tcp.options>
<padding pad="0"/>
</tcp.header>
<payload>
</payload>
</tcp>
4. UDPoXML
This protocol MUST be implemented to be compliant with this RFC. The
DTD for this document type can be found in section 7.3.
4.1. UDP Description
A number of items have changed from the original UDP specification.
Bit-masks, where present have been converted into human-readable
values. Length and checksum and port values are present as decimal
integers.
Kennedy Informational [Page 5]
RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002
To calculate the length and checksum fields of the UDP element, a
canonicalized form of the element MUST be used as in section 2.1. An
iterative method SHOULD be used to calculate checksums as in section
2.1.
The payload element MUST be encoded as in section 2.1.
UDPoXML datagrams encapsulated by IPoXML MAY omit the <?xml?> header
as well as the <!DOCTYPE> declaration.
4.2. Example Datagram
The following is an example UDPoXML datagram with an empty payload:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE udp PUBLIC "-//IETF//DTD BLOAT 1.0 UDP//EN" "bloat.dtd">
<udp>
<udp.header>
<src port="31415"/>
<dest port="42424"/>
<udp.length value="143"/>
<checksum value="2988"/>
</udp.header>
<payload>
</payload>
</udp>
5. Network Transport
This document provides for the transmission of BLOAT datagrams over
two common families of physical layer transport. Future RFCs will
address additional transports as routing vendors catch up to the
specification, and we begin to see BLOAT routed across the Internet
backbone.
5.1. Ethernet
BLOAT is encapsulated in Ethernet datagrams as in [RFC894] with the
exception that the type field of the Ethernet frame MUST contain the
value 0xBEEF. The first 5 octets of the Ethernet frame payload will
be 0x3c 3f 78 6d 6c ("<?xml".)
5.2. IEEE 802
BLOAT is encapsulated in IEEE 802 Networks as in [RFC1042] except
that the protocol type code for IPoXML is 0xBEEF.
Kennedy Informational [Page 6]
RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002
6. Gatewaying over IP
In order to facilitate the gradual introduction of BLOAT into the
public Internet, BLOAT MAY be encapsulated in IP as in [RFC2003] to
gateway between networks that run BLOAT natively on their LANs.
7. DTDs
The Transport DTDs (7.2. and 7.3.) build on the definitions in the
Network DTD (7.1.)
The DTDs are referenced by their PubidLiteral and SystemLiteral (from
[XML]) although it is understood that most IPoXML implementations
will not need to pull down the DTD, as it will normally be embedded
in the implementation, and presents something of a catch-22 if you
need to load part of your network protocol over the network.
7.1. IPoXML DTD
<!--
DTD for IP over XML.
Refer to this DTD as:
<!DOCTYPE ip PUBLIC "-//IETF//DTD BLOAT 1.0 IP//EN" "bloat.dtd">
-->
<!--
DTD data types:
Digits [0..9]+
Precedence "NetworkControl | InternetworkControl |
CRITIC | FlashOverride | Flash | Immediate |
Priority | Routine"
IP4Addr "dotted-decimal" notation of [RFC1123]
Class [0..3]
Sec "Unclassified | Confidential | EFTO | MMMM | PROG |
Restricted | Secret | Top Secret | Reserved"
Compartments [0..65535]
Handling [0..65535]
TCC [0..16777216]
-->
Kennedy Informational [Page 7]
RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002
<!ENTITY % Digits "CDATA">
<!ENTITY % Precedence "CDATA">
<!ENTITY % IP4Addr "CDATA">
<!ENTITY % Class "CDATA">
<!ENTITY % Sec "CDATA">
<!ENTITY % Compartments "CDATA">
<!ENTITY % Handling "CDATA">
<!ENTITY % TCC "CDATA">
<!ELEMENT ip (header, payload)>
<!ELEMENT header (version, tos, total.length, id, flags, offset, ttl,
protocol, checksum, source, destination, options,
padding)>
<!-- length of header in 32-bit words -->
<!ATTLIST header
length %Digits; #REQUIRED>
<!ELEMENT version EMPTY>
<!-- ip version. SHOULD be "4" -->
<!ATTLIST version
value %Digits; #REQUIRED>
<!ELEMENT tos EMPTY>
<!ATTLIST tos
precedence %Precedence; #REQUIRED
delay (normal | low) #REQUIRED
throughput (normal | high) #REQUIRED
relibility (normal | high) #REQUIRED
reserved CDATA #FIXED "0">
<!ELEMENT total.length EMPTY>
<!--
total length of datagram (header and payload) in octets, MUST be
less than 65,535 (and SHOULD be less than 1024 for IPoXML on local
ethernets).
-->
<!ATTLIST total.length
value %Digits; #REQUIRED>
<!ELEMENT id EMPTY>
<!-- 0 <= id <= 65,535 -->
<!ATTLIST id
value %Digits; #REQUIRED>
<!ELEMENT flags EMPTY>
<!-- df = don't fragment, mf = more fragments -->
<!ATTLIST flags
Kennedy Informational [Page 8]
RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002
reserved CDATA #FIXED "0"
df (may|dont) #REQUIRED
mf (last|more) #REQUIRED>
<!ELEMENT offset EMPTY>
<!-- 0 <= offset <= 8192 measured in 8 octet (64-bit) chunks -->
<!ATTLIST offset
value %Digits; #REQUIRED>
<!ELEMENT ttl EMPTY>
<!-- 0 <= ttl <= 255 -->
<!ATTLIST ttl
value %Digits; #REQUIRED>
<!ELEMENT protocol EMPTY>
<!-- 0 <= protocol <= 255 (per IANA) -->
<!ATTLIST protocol
value %Digits; #REQUIRED>
<!ELEMENT checksum EMPTY>
<!-- 0 <= checksum <= 65535 (over header only) -->
<!ATTLIST checksum
value %Digits; #REQUIRED>
<!ELEMENT source EMPTY>
<!ATTLIST source
address %IP4Addr; #REQUIRED>
<!ELEMENT destination EMPTY>
<!ATTLIST destination
address %IP4Addr; #REQUIRED>
<!ELEMENT options ( end | noop | security | loose | strict | record
| stream | timestamp )*>
<!ELEMENT end EMPTY>
<!ATTLIST end
copied (0|1) #REQUIRED
class CDATA #FIXED "0"
number CDATA #FIXED "0">
<!ELEMENT noop EMPTY>
<!ATTLIST noop
copied (0|1) #REQUIRED
class CDATA #FIXED "0"
number CDATA #FIXED "1">
<!ELEMENT security EMPTY>
Kennedy Informational [Page 9]
RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002
<!ATTLIST security
copied CDATA #FIXED "1"
class CDATA #FIXED "0"
number CDATA #FIXED "2"
length CDATA #FIXED "11"
security %Sec; #REQUIRED
compartments %Compartments; #REQUIRED
handling %Handling; #REQUIRED
tcc %TCC; #REQUIRED>
<!ELEMENT loose (hop)+>
<!ATTLIST loose
copied CDATA #FIXED "1"
class CDATA #FIXED "0"
number CDATA #FIXED "3"
length %Digits; #REQUIRED
pointer %Digits; #REQUIRED>
<!ELEMENT hop EMPTY>
<!ATTLIST hop
address %IP4Addr; #REQUIRED>
<!ELEMENT strict (hop)+>
<!ATTLIST strict
copied CDATA #FIXED "1"
class CDATA #FIXED "0"
number CDATA #FIXED "9"
length %Digits; #REQUIRED
pointer %Digits; #REQUIRED>
<!ELEMENT record (hop)+>
<!ATTLIST record
copied CDATA #FIXED "0"
class CDATA #FIXED "0"
number CDATA #FIXED "7"
length %Digits; #REQUIRED
pointer %Digits; #REQUIRED>
<!ELEMENT stream EMPTY>
<!-- 0 <= id <= 65,535 -->
<!ATTLIST stream
copied CDATA #FIXED "1"
class CDATA #FIXED "0"
number CDATA #FIXED "8"
length CDATA #FIXED "4"
id %Digits; #REQUIRED>
<!ELEMENT timestamp (tstamp)+>
<!-- 0 <= oflw <=15 -->
Kennedy Informational [Page 10]
RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002
<!ATTLIST timestamp
copied CDATA #FIXED "0"
class CDATA #FIXED "2"
number CDATA #FIXED "4"
length %Digits; #REQUIRED
pointer %Digits; #REQUIRED
oflw %Digits; #REQUIRED
flag (0 | 1 | 3) #REQUIRED>
<!ELEMENT tstamp EMPTY>
<!ATTLIST tstamp
time %Digits; #REQUIRED
address %IP4Addr; #IMPLIED>
<!--
padding to bring header to 32-bit boundary.
pad MUST be "0"*
-->
<!ELEMENT padding EMPTY>
<!ATTLIST padding
pad CDATA #REQUIRED>
<!-- payload MUST be encoded as base-64 [RFC2045], as modified
by section 2.1 of this RFC -->
<!ELEMENT payload (CDATA)>
7.2. TCPoXML DTD
<!--
DTD for TCP over XML.
Refer to this DTD as:
<!DOCTYPE tcp PUBLIC "-//IETF//DTD BLOAT 1.0 TCP//EN" "bloat.dtd">
-->
<!-- the pseudoheader is only included for checksum calculations -->
<!ELEMENT tcp (tcp.pseudoheader?, tcp.header, payload)>
<!ELEMENT tcp.header (src, dest, sequence, acknowledgement, offset,
reserved, control, window, checksum, urgent,
tcp.options, padding)>
<!ELEMENT src EMPTY>
<!-- 0 <= port <= 65,535 -->
<!ATTLIST src
port %Digits; #REQUIRED>
<!ELEMENT dest EMPTY>
<!-- 0 <= port <= 65,535 -->
Kennedy Informational [Page 11]
RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002
<!ATTLIST dest
port %Digits; #REQUIRED>
<!ELEMENT sequence EMPTY>
<!-- 0 <= number <= 4294967295 -->
<!ATTLIST sequence
number %Digits; #REQUIRED>
<!ELEMENT acknowledgement EMPTY>
<!-- 0 <= number <= 4294967295 -->
<!ATTLIST acknowledgement
number %Digits; #REQUIRED>
<!ELEMENT offset EMPTY>
<!-- 0 <= number <= 255 -->
<!ATTLIST offset
number %Digits; #REQUIRED>
<!ELEMENT reserved EMPTY>
<!ATTLIST reserved
value CDATA #FIXED "0">
<!ELEMENT control EMPTY>
<!ATTLIST control
urg (0|1) #IMPLIED
ack (0|1) #IMPLIED
psh (0|1) #IMPLIED
rst (0|1) #IMPLIED
syn (0|1) #IMPLIED
fin (0|1) #IMPLIED>
<!ELEMENT window EMPTY>
<!-- 0 <= size <= 65,535 -->
<!ATTLIST window
size %Digits; #REQUIRED>
<!--
checksum as in ip, but with
the following pseudo-header added into the tcp element:
-->
<!ELEMENT tcp.pseudoheader (source, destination, protocol,
tcp.length)>
<!--
tcp header + data length in octets. does not include the size of
the pseudoheader.
-->
Kennedy Informational [Page 12]
RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002
<!ELEMENT tcp.length EMPTY>
<!ATTLIST tcp.length
value %Digits; #REQUIRED>
<!ELEMENT urgent EMPTY>
<!-- 0 <= pointer <= 65,535 -->
<!ATTLIST urgent
pointer %Digits; #REQUIRED>
<!ELEMENT tcp.options (tcp.end | tcp.noop | tcp.mss)+>
<!ELEMENT tcp.end EMPTY>
<!ATTLIST tcp.end
kind CDATA #FIXED "0">
<!ELEMENT tcp.noop EMPTY>
<!ATTLIST tcp.noop
kind CDATA #FIXED "1">
<!ELEMENT tcp.mss EMPTY>
<!ATTLIST tcp.mss
kind CDATA #FIXED "2"
length CDATA #FIXED "4"
size %Digits; #REQUIRED>
7.3. UDPoXML DTD
<!--
DTD for UDP over XML.
Refer to this DTD as:
<!DOCTYPE udp PUBLIC "-//IETF//DTD BLOAT 1.0 UDP//EN" "bloat.dtd">
-->
<!ELEMENT udp (udp.pseudoheader?, udp.header, payload)>
<!ELEMENT udp.header (src, dest, udp.length, checksum)>
<!ELEMENT udp.pseudoheader (source, destination, protocol,
udp.length)>
<!--
udp header + data length in octets. does not include the size of
the pseudoheader.
-->
<!ELEMENT udp.length EMPTY>
<!ATTLIST udp.length
value %Digits; #REQUIRED>
Kennedy Informational [Page 13]
RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002
8. Security Considerations
XML, as a subset of SGML, has the same security considerations as
specified in SGML Media Types [RFC1874]. Security considerations
that apply to IP, TCP and UDP also likely apply to BLOAT as it does
not attempt to correct for issues not related to message format.
9. References
[JABBER] Miller, J., "Jabber", draft-miller-jabber-00.txt,
February 2002. (Work in Progress)
[RFC768] Postel, J., "User Datagram Protocol", STD 6, RFC 768,
August 1980.
[RFC791] Postel, J., "Internet Protocol", STD 5, RFC 791,
September 1981.
[RFC793] Postel, J., "Transmission Control Protocol", STD 7, RFC
793, September 1981.
[RFC894] Hornig, C., "Standard for the Transmission of IP
Datagrams over Ethernet Networks.", RFC 894, April 1984.
[RFC1042] Postel, J. and J. Reynolds, "Standard for the
Transmission of IP Datagrams Over IEEE 802 Networks", STD
43, RFC 1042, February 1988.
[RFC1123] Braden, R., "Requirements for Internet Hosts -
Application and Support", RFC 1123, October 1989.
[RFC1874] Levinson, E., "SGML Media Types", RFC 1874, December
1995.
[RFC2003] Perkins, C., "IP Encapsulation within IP", RFC 2003,
October 1996.
[RFC2045] Freed, N. and N. Borenstein, "Multipurpose Internet Mail
Extensions (MIME) Part One: Format of Internet Message
Bodies", RFC 2045, November 1996.
[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
Requirement Levels", BCP 14, RFC 2119, March 1997.
[RFC2279] Yergeau, F., "UTF-8, a transformation format of ISO
10646", RFC 2279, January 1998.
Kennedy Informational [Page 14]
RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002
[RFC2460] Deering, S. and R. Hinden, "Internet Protocol, Version 6
(IPv6) Specification", RFC 2460, December 1998.
[RFC3080] Rose, M., "The Blocks Extensible Exchange Protocol Core",
RFC 3080, March 2001.
[SOAP] Box, D., Ehnebuske, D., Kakivaya, G., Layman, A.,
Mendelsohn, N., Nielsen, H. F., Thatte, S. Winer, D.,
"Simple Object Access Protocol (SOAP) 1.1" World Wide Web
Consortium Note, May 2000 http://www.w3.org/TR/SOAP/
[XML] Bray, T., Paoli, J., Sperberg-McQueen, C. M., "Extensible
Markup Language (XML)" World Wide Web Consortium
Recommendation REC- xml-19980210.
http://www.w3.org/TR/1998/REC-xml-19980210
10. Author's Address
Hugh Kennedy
Mimezine
1060 West Addison
Chicago, IL 60613
USA
EMail: kennedyh@engin.umich.edu
Kennedy Informational [Page 15]
RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002
11. Full Copyright Statement
Copyright (C) The Internet Society (2002). All Rights Reserved.
This document and translations of it may be copied and furnished to
others, and derivative works that comment on or otherwise explain it
or assist in its implementation may be prepared, copied, published
and distributed, in whole or in part, without restriction of any
kind, provided that the above copyright notice and this paragraph are
included on all such copies and derivative works. However, this
document itself may not be modified in any way, such as by removing
the copyright notice or references to the Internet Society or other
Internet organizations, except as needed for the purpose of
developing Internet standards in which case the procedures for
copyrights defined in the Internet Standards process must be
followed, or as required to translate it into languages other than
English.
The limited permissions granted above are perpetual and will not be
revoked by the Internet Society or its successors or assigns.
This document and the information contained herein is provided on an
"AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
Acknowledgement
Funding for the RFC Editor function is currently provided by the
Internet Society.
Kennedy Informational [Page 16]

View File

@ -0,0 +1,224 @@
// Copyright (C) 2022 The Qt Company Ltd.
// Copyright (C) 2022 Intel Corporation.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include <QTest>
#include <qbytearray.h>
#include <q20iterator.h>
#include <stdexcept>
#include <string_view>
class tst_QByteArrayLarge : public QObject
{
Q_OBJECT
private slots:
void initTestCase();
#ifndef QT_NO_COMPRESS
void qCompress_data();
void qCompress();
void qUncompressCorruptedData_data();
void qUncompressCorruptedData();
void qUncompress4GiBPlus();
void qCompressionZeroTermination();
#endif
void base64_2GiB();
};
void tst_QByteArrayLarge::initTestCase()
{
#if defined(QT_ASAN_ENABLED)
QSKIP("Skipping QByteArray tests under ASAN as they are too slow");
#endif
}
#ifndef QT_NO_COMPRESS
void tst_QByteArrayLarge::qCompress_data()
{
QTest::addColumn<QByteArray>("ba");
const int size1 = 1024*1024;
QByteArray ba1( size1, 0 );
QTest::newRow( "00" ) << QByteArray();
int i;
for ( i=0; i<size1; i++ )
ba1[i] = (char)( i / 1024 );
QTest::newRow( "01" ) << ba1;
for ( i=0; i<size1; i++ )
ba1[i] = (char)( i % 256 );
QTest::newRow( "02" ) << ba1;
ba1.fill( 'A' );
QTest::newRow( "03" ) << ba1;
QFile file( QFINDTESTDATA("rfc3252.txt") );
QVERIFY( file.open(QIODevice::ReadOnly) );
QTest::newRow( "04" ) << file.readAll();
}
void tst_QByteArrayLarge::qCompress()
{
QFETCH( QByteArray, ba );
QByteArray compressed = ::qCompress( ba );
QTEST( ::qUncompress( compressed ), "ba" );
}
void tst_QByteArrayLarge::qUncompressCorruptedData_data()
{
QTest::addColumn<QByteArray>("in");
QTest::newRow("0x00000000") << QByteArray("\x00\x00\x00\x00", 4);
QTest::newRow("0x000000ff") << QByteArray("\x00\x00\x00\xff", 4);
QTest::newRow("0x3f000000") << QByteArray("\x3f\x00\x00\x00", 4);
QTest::newRow("0x3fffffff") << QByteArray("\x3f\xff\xff\xff", 4);
QTest::newRow("0x7fffff00") << QByteArray("\x7f\xff\xff\x00", 4);
QTest::newRow("0x7fffffff") << QByteArray("\x7f\xff\xff\xff", 4);
QTest::newRow("0x80000000") << QByteArray("\x80\x00\x00\x00", 4);
QTest::newRow("0x800000ff") << QByteArray("\x80\x00\x00\xff", 4);
QTest::newRow("0xcf000000") << QByteArray("\xcf\x00\x00\x00", 4);
QTest::newRow("0xcfffffff") << QByteArray("\xcf\xff\xff\xff", 4);
QTest::newRow("0xffffff00") << QByteArray("\xff\xff\xff\x00", 4);
QTest::newRow("0xffffffff") << QByteArray("\xff\xff\xff\xff", 4);
}
// This test is expected to produce some warning messages in the test output.
void tst_QByteArrayLarge::qUncompressCorruptedData()
{
QFETCH(QByteArray, in);
QByteArray res;
res = ::qUncompress(in);
QCOMPARE(res, QByteArray());
res = ::qUncompress(in + "blah");
QCOMPARE(res, QByteArray());
}
void tst_QByteArrayLarge::qUncompress4GiBPlus()
{
// after three rounds, this decompresses to 4GiB + 1 'X' bytes:
constexpr uchar compressed_3x[] = {
0x00, 0x00, 0x1a, 0x76, 0x78, 0x9c, 0x63, 0xb0, 0xdf, 0xb4, 0xad, 0x62,
0xce, 0xdb, 0x3b, 0x0b, 0xf3, 0x26, 0x27, 0x4a, 0xb4, 0x3d, 0x34, 0x5b,
0xed, 0xb4, 0x41, 0xf1, 0xc0, 0x99, 0x2f, 0x02, 0x05, 0x67, 0x26, 0x88,
0x6c, 0x66, 0x71, 0x34, 0x62, 0x9c, 0x75, 0x26, 0xb1, 0xa0, 0xe5, 0xcc,
0xda, 0x94, 0x83, 0xc9, 0x05, 0x73, 0x0e, 0x3c, 0x39, 0xc2, 0xc7, 0xd0,
0xae, 0x38, 0x53, 0x7b, 0x87, 0xdc, 0x01, 0x91, 0x45, 0x59, 0x4f, 0xda,
0xbf, 0xca, 0xcc, 0x52, 0xdb, 0xbb, 0xde, 0xbb, 0xf6, 0xd3, 0x55, 0xff,
0x7d, 0x77, 0x0e, 0x1b, 0xf0, 0xa4, 0xdf, 0xcf, 0xdb, 0x5f, 0x2f, 0xf5,
0xd7, 0x7c, 0xfe, 0xbf, 0x3f, 0xbf, 0x3f, 0x9d, 0x7c, 0xda, 0x2c, 0xc8,
0xc0, 0xc0, 0xb0, 0xe1, 0xf1, 0xb3, 0xfd, 0xfa, 0xdf, 0x8e, 0x7d, 0xef,
0x7f, 0xb9, 0xc1, 0xc2, 0xae, 0x92, 0x19, 0x28, 0xf2, 0x66, 0xd7, 0xe5,
0xbf, 0xed, 0x93, 0xbf, 0x6a, 0x14, 0x7c, 0xff, 0xf6, 0xe1, 0xe8, 0xb6,
0x7e, 0x46, 0xa0, 0x90, 0xd9, 0xbb, 0xcf, 0x9f, 0x17, 0x37, 0x7f, 0xe5,
0x6f, 0xb4, 0x7f, 0xfe, 0x5e, 0xfd, 0xb6, 0x1d, 0x1b, 0x50, 0xe8, 0xc6,
0x8e, 0xe3, 0xab, 0x9f, 0xe6, 0xec, 0x65, 0xfd, 0x23, 0xb1, 0x4e, 0x7e,
0xef, 0xbd, 0x6f, 0xa6, 0x40, 0xa1, 0x03, 0xc7, 0xfe, 0x0a, 0xf1, 0x00,
0xe9, 0x06, 0x91, 0x83, 0x40, 0x92, 0x21, 0x43, 0x10, 0xcc, 0x11, 0x03,
0x73, 0x3a, 0x90, 0x39, 0xa3, 0x32, 0xa3, 0x32, 0xa3, 0x32, 0xa3, 0x32,
0xa3, 0x32, 0xa3, 0x32, 0xa3, 0x32, 0xa3, 0x32, 0xa3, 0x32, 0xa3, 0x32,
0xa3, 0x32, 0xa3, 0x32, 0xa3, 0x32, 0xa3, 0x32, 0xa3, 0x32, 0xa3, 0x32,
0xa3, 0x32, 0xa3, 0x32, 0xa3, 0x32, 0xa3, 0x32, 0xa3, 0x32, 0xa3, 0x32,
0xa3, 0x32, 0xa3, 0x32, 0xa3, 0x32, 0x34, 0x90, 0x99, 0xb6, 0x7e, 0xf5,
0xd3, 0xe9, 0xbf, 0x35, 0x13, 0xca, 0x8c, 0x75, 0xec, 0xec, 0xa4, 0x2f,
0x7e, 0x2d, 0xf9, 0xf3, 0xf0, 0xee, 0xea, 0xd5, 0xf5, 0xd3, 0x14, 0x57,
0x06, 0x00, 0x00, 0xb9, 0x1e, 0x35, 0xce
};
constexpr qint64 GiB = 1024LL * 1024 * 1024;
if constexpr (sizeof(qsizetype) == sizeof(int)) {
QSKIP("This is a 64-bit-only test.");
} else {
// 1st
auto c = ::qUncompress(std::data(compressed_3x), q20::ssize(compressed_3x));
QVERIFY(!c.isNull()); // check for decompression error
// 2nd
c = ::qUncompress(c);
QVERIFY(!c.isNull());
// 3rd
try {
c = ::qUncompress(c);
if (c.isNull()) // this step (~18MiB -> 4GiB) might have run out of memory
QSKIP("Failed to allocate enough memory.");
} catch (const std::bad_alloc &) {
QSKIP("Failed to allocate enough memory.");
}
QCOMPARE(c.size(), 4 * GiB + 1);
QCOMPARE(std::string_view{c}.find_first_not_of('X'),
std::string_view::npos);
// re-compress once
// (produces 18MiB, we shouldn't use much more than that in allocated capacity)
c = ::qCompress(c);
QVERIFY(!c.isNull());
// and un-compress again, to make sure compression worked (we
// can't compare with compressed_3x, because zlib may change):
c = ::qUncompress(c);
QCOMPARE(c.size(), 4 * GiB + 1);
QCOMPARE(std::string_view{c}.find_first_not_of('X'),
std::string_view::npos);
}
}
void tst_QByteArrayLarge::qCompressionZeroTermination()
{
QByteArray s = "Hello, I'm a string.";
QByteArray ba = ::qUncompress(::qCompress(s));
QCOMPARE(ba.data()[ba.size()], '\0');
QCOMPARE(ba, s);
}
#endif
void tst_QByteArrayLarge::base64_2GiB()
{
#ifdef Q_OS_ANDROID
QSKIP("Android kills the test when using too much memory");
#endif
if constexpr (sizeof(qsizetype) > sizeof(int)) {
try {
constexpr qint64 GiB = 1024 * 1024 * 1024;
static_assert((2 * GiB + 1) % 3 == 0);
const char inputChar = '\0'; // all-NULs encode as
const char outputChar = 'A'; // all-'A's
const qint64 inputSize = 2 * GiB + 1;
const qint64 outputSize = inputSize / 3 * 4;
const auto sv = [](const QByteArray &ba) {
return std::string_view{ba.data(), size_t(ba.size())};
};
QByteArray output;
{
const QByteArray input(inputSize, inputChar);
output = input.toBase64();
QCOMPARE(output.size(), outputSize);
QCOMPARE(sv(output).find_first_not_of(outputChar),
std::string_view::npos);
}
{
auto r = QByteArray::fromBase64Encoding(output);
QCOMPARE_EQ(r.decodingStatus, QByteArray::Base64DecodingStatus::Ok);
QCOMPARE(r.decoded.size(), inputSize);
QCOMPARE(sv(r.decoded).find_first_not_of(inputChar),
std::string_view::npos);
}
} catch (const std::bad_alloc &) {
QSKIP("Could not allocate enough RAM.");
}
} else {
QSKIP("This is a 64-bit only test");
}
}
QTEST_MAIN(tst_QByteArrayLarge)
#include "tst_qbytearray_large.moc"

View File

@ -0,0 +1,11 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qbytearrayapisymmetry Test:
#####################################################################
qt_internal_add_test(tst_qbytearrayapisymmetry
SOURCES
tst_qbytearrayapisymmetry.cpp
)

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,11 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qbytearraylist Test:
#####################################################################
qt_internal_add_test(tst_qbytearraylist
SOURCES
tst_qbytearraylist.cpp
)

View File

@ -0,0 +1,304 @@
// Copyright (C) 2016 The Qt Company Ltd.
// Copyright (C) 2014 by Southwest Research Institute (R)
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#define QT_USE_QSTRINGBUILDER
#include <QTest>
#include <qbytearraylist.h>
#include <qmetatype.h>
#include <qproperty.h>
Q_DECLARE_METATYPE(QByteArrayList)
class tst_QByteArrayList : public QObject
{
Q_OBJECT
private slots:
void join_overloads() const;
void join() const;
void join_data() const;
void joinByteArray() const;
void joinByteArray_data() const;
void joinChar() const;
void joinChar_data() const;
void joinEmptiness() const;
void operator_plus() const;
void operator_plus_data() const;
void indexOf_data() const;
void indexOf() const;
void initializerList() const;
};
void tst_QByteArrayList::join_overloads() const
{
// Checks that there are no ambiguities between the different join() overloads:
const QByteArrayList list = {"a", "b", "c"};
const QByteArray expected = "aXbXc";
QCOMPARE(list.join('X'), expected);
QCOMPARE(list.join("X"), expected);
QCOMPARE(list.join(QByteArrayLiteral("X")), expected);
QCOMPARE(list.join(QByteArray("X")), expected);
QCOMPARE(list.join(QByteArrayView("X")), expected);
const char *sep = "X";
QCOMPARE(list.join(sep), expected);
QCOMPARE(list.join(QByteArray() % "X"), expected); // QStringBuilder expression
QProperty<QByteArray> prop("X"); // implicitly convertible to QByteArray
QCOMPARE(list.join(prop), expected);
QCOMPARE(list.join(std::as_const(prop)), expected);
}
void tst_QByteArrayList::join() const
{
QFETCH(QByteArrayList, input);
QFETCH(QByteArray, expectedResult);
QCOMPARE(input.join(), expectedResult);
QCOMPARE(input.join(QByteArrayView{}), expectedResult);
QCOMPARE(input.join(QByteArray{}), expectedResult);
}
void tst_QByteArrayList::join_data() const
{
QTest::addColumn<QByteArrayList>("input");
QTest::addColumn<QByteArray>("expectedResult");
QTest::newRow("data1") << QByteArrayList()
<< QByteArray();
QTest::newRow("data2") << (QByteArrayList() << "one")
<< QByteArray("one");
QTest::newRow("data3") << (QByteArrayList() << "a" << "b")
<< QByteArray("ab");
QTest::newRow("data4") << (QByteArrayList() << "a" << "b" << "c")
<< QByteArray("abc");
}
void tst_QByteArrayList::joinByteArray() const
{
QFETCH(QByteArrayList, input);
QFETCH(QByteArray, separator);
QFETCH(QByteArray, expectedResult);
QCOMPARE(input.join(separator), expectedResult);
QCOMPARE(input.join(QByteArrayView{separator}), expectedResult);
}
void tst_QByteArrayList::joinByteArray_data() const
{
QTest::addColumn<QByteArrayList>("input");
QTest::addColumn<QByteArray>("separator");
QTest::addColumn<QByteArray>("expectedResult");
QTest::newRow("data1") << QByteArrayList()
<< QByteArray()
<< QByteArray();
QTest::newRow("data2") << QByteArrayList()
<< QByteArray("separator")
<< QByteArray();
QTest::newRow("data3") << (QByteArrayList() << "one")
<< QByteArray("separator")
<< QByteArray("one");
QTest::newRow("data4") << (QByteArrayList() << "a" << "b")
<< QByteArray(" ")
<< QByteArray("a b");
QTest::newRow("data5") << (QByteArrayList() << "a" << "b" << "c")
<< QByteArray(" ")
<< QByteArray("a b c");
QTest::newRow("data6") << (QByteArrayList() << "a" << "b" << "c")
<< QByteArray()
<< QByteArray("abc");
QTest::newRow("data7") << (QByteArrayList() << "a" << "b" << "c")
<< QByteArray("") //empty
<< QByteArray("abc");
}
void tst_QByteArrayList::joinChar() const
{
QFETCH(QByteArrayList, input);
QFETCH(char, separator);
QFETCH(QByteArray, expectedResult);
QCOMPARE(input.join(separator), expectedResult);
QCOMPARE(input.join(QByteArrayView{&separator, 1}), expectedResult);
}
void tst_QByteArrayList::joinChar_data() const
{
QTest::addColumn<QByteArrayList>("input");
QTest::addColumn<char>("separator");
QTest::addColumn<QByteArray>("expectedResult");
QTest::newRow("data1") << QByteArrayList()
<< ' '
<< QByteArray();
QTest::newRow("data2") << (QByteArrayList() << "a a" << "b")
<< ' '
<< QByteArray("a a b");
QTest::newRow("data3") << (QByteArrayList() << "a" << "b" << "c c")
<< ' '
<< QByteArray("a b c c");
}
void tst_QByteArrayList::joinEmptiness() const
{
QByteArrayList list;
QByteArray string = list.join(QByteArray());
QVERIFY(string.isEmpty());
QVERIFY(string.isNull());
}
void tst_QByteArrayList::operator_plus() const
{
QFETCH(QByteArrayList, lhs);
QFETCH(QByteArrayList, rhs);
QFETCH(QByteArrayList, expectedResult);
// operator+ for const lvalues
{
const QByteArrayList bal1 = lhs;
const QByteArrayList bal2 = rhs;
QCOMPARE(bal1 + bal2, expectedResult);
}
{
const QList<QByteArray> lba1 = lhs;
const QByteArrayList bal2 = rhs;
QCOMPARE(lba1 + bal2, expectedResult);
}
{
const QByteArrayList bal1 = lhs;
const QList<QByteArray> lba2 = rhs;
QCOMPARE(bal1 + lba2, expectedResult);
}
{
const QList<QByteArray> lba1 = lhs;
const QList<QByteArray> lba2 = rhs;
QCOMPARE(lba1 + lba2, QList<QByteArray>(expectedResult)); // check we don't mess with old code
}
// operator+ for rvalues (only lhs)
{
QByteArrayList bal1 = lhs;
const QByteArrayList bal2 = rhs;
QCOMPARE(std::move(bal1) + bal2, expectedResult);
}
{
QList<QByteArray> lba1 = lhs;
const QByteArrayList bal2 = rhs;
QCOMPARE(std::move(lba1) + bal2, expectedResult);
}
{
QByteArrayList bal1 = lhs;
const QList<QByteArray> lba2 = rhs;
QCOMPARE(std::move(bal1) + lba2, expectedResult);
}
{
QList<QByteArray> lba1 = lhs;
const QList<QByteArray> lba2 = rhs;
QCOMPARE(std::move(lba1) + lba2, QList<QByteArray>(expectedResult)); // check we don't mess with old code
}
// operator += for const lvalues
{
QByteArrayList bal1 = lhs;
const QByteArrayList bal2 = rhs;
QCOMPARE(bal1 += bal2, expectedResult);
}
{
QByteArrayList bal1 = lhs;
const QList<QByteArray> lba2 = rhs;
QCOMPARE(bal1 += lba2, expectedResult);
}
{
QList<QByteArray> lba1 = lhs;
const QByteArrayList bal2 = rhs;
QCOMPARE(lba1 += bal2, QList<QByteArray>(expectedResult));
}
QByteArrayList t1 = lhs;
QByteArrayList t2 = rhs;
QCOMPARE(std::move(t1) + t2, expectedResult);
}
void tst_QByteArrayList::operator_plus_data() const
{
QTest::addColumn<QByteArrayList>("lhs");
QTest::addColumn<QByteArrayList>("rhs");
QTest::addColumn<QByteArrayList>("expectedResult");
QTest::newRow("simpl") << ( QByteArrayList() << "a" )
<< ( QByteArrayList() << "b" << "c" )
<< ( QByteArrayList() << "a" << "b" << "c" );
QTest::newRow("blank1") << QByteArrayList()
<< QByteArrayList()
<< QByteArrayList();
QTest::newRow("blank2") << ( QByteArrayList() )
<< ( QByteArrayList() << "b" << "c" )
<< ( QByteArrayList() << "b" << "c" );
QTest::newRow("empty1") << ( QByteArrayList() << "" )
<< ( QByteArrayList() << "b" << "c" )
<< ( QByteArrayList() << "" << "b" << "c" );
QTest::newRow("empty2") << ( QByteArrayList() << "a" )
<< ( QByteArrayList() << "" << "c" )
<< ( QByteArrayList() << "a" << "" << "c" );
}
void tst_QByteArrayList::indexOf_data() const
{
QTest::addColumn<QByteArrayList>("list");
QTest::addColumn<QByteArray>("item");
QTest::addColumn<int>("expectedResult");
QTest::newRow("empty") << QByteArrayList() << QByteArray("a") << -1;
QTest::newRow("found_1") << ( QByteArrayList() << "a" ) << QByteArray("a") << 0;
QTest::newRow("not_found_1") << ( QByteArrayList() << "a" ) << QByteArray("b") << -1;
QTest::newRow("found_2") << ( QByteArrayList() << "hello" << "world" ) << QByteArray("world") << 1;
QTest::newRow("returns_first") << ( QByteArrayList() << "hello" << "world" << "hello" << "again" ) << QByteArray("hello") << 0;
}
void tst_QByteArrayList::indexOf() const
{
QFETCH(QByteArrayList, list);
QFETCH(QByteArray, item);
QFETCH(int, expectedResult);
QCOMPARE(list.indexOf(item), expectedResult);
QCOMPARE(list.indexOf(item.constData()), expectedResult);
}
void tst_QByteArrayList::initializerList() const
{
// constructor
QByteArrayList v1 = {QByteArray("hello"),"world",QByteArray("plop")};
QCOMPARE(v1, (QByteArrayList() << "hello" << "world" << "plop"));
QCOMPARE(v1, (QByteArrayList{"hello","world","plop"}));
// assignment operator (through implicit temporary)
QByteArrayList v2;
v2 = {QByteArray("hello"),"world",QByteArray("plop")};
QCOMPARE(v2, v1);
}
QTEST_APPLESS_MAIN(tst_QByteArrayList)
#include "tst_qbytearraylist.moc"

View File

@ -0,0 +1,14 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qbytearraymatcher Test:
#####################################################################
qt_internal_add_test(tst_qbytearraymatcher
SOURCES
tst_qbytearraymatcher.cpp
)
## Scopes:
#####################################################################

View File

@ -0,0 +1,300 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include <QTest>
#include <qbytearraymatcher.h>
#include <numeric>
#include <string>
#if QT_CONFIG(cxx11_future)
# include <thread>
#endif
// COM interface
#if defined(Q_OS_WIN) && defined(interface)
# undef interface
#endif
class tst_QByteArrayMatcher : public QObject
{
Q_OBJECT
private slots:
void overloads();
void interface();
void indexIn();
void staticByteArrayMatcher();
void haystacksWithMoreThan4GiBWork();
};
void tst_QByteArrayMatcher::overloads()
{
QByteArray hello = QByteArrayLiteral("hello");
QByteArray hello2 = hello.repeated(2);
{
QByteArrayMatcher m("hello");
QCOMPARE(m.pattern(), "hello");
QCOMPARE(m.indexIn("hello"), 0);
}
{
QByteArrayMatcher m("hello", qsizetype(3));
QCOMPARE(m.pattern(), "hel");
QCOMPARE(m.indexIn("hellohello", qsizetype(2)), -1); // haystack is "he", not: from is 2
QCOMPARE(m.indexIn("hellohello", qsizetype(3)), 0); // haystack is "hel", not: from is 3
}
{
QByteArrayMatcher m(hello);
QCOMPARE(m.pattern(), "hello");
QCOMPARE(m.indexIn(hello), 0);
QCOMPARE(m.indexIn(hello2, qsizetype(1)), hello.size());
}
{
QStaticByteArrayMatcher m("hel");
QCOMPARE(m.pattern(), "hel");
QCOMPARE(m.indexIn("hello"), qsizetype(0));
QCOMPARE(m.indexIn("hellohello", qsizetype(2)), -1); // haystack is "he", not: from is 2
QCOMPARE(m.indexIn("hellohello", qsizetype(3)), 0); // haystack is "hel", not: from is 3
QCOMPARE(m.indexIn(hello), 0);
QCOMPARE(m.indexIn(hello2, qsizetype(2)), hello.size()); // from is 2
QCOMPARE(m.indexIn(hello2, qsizetype(3)), hello.size()); // from is 3
}
}
void tst_QByteArrayMatcher::interface()
{
const char needle[] = "abc123";
QByteArray haystack(500, 'a');
haystack.insert(6, "123");
haystack.insert(31, "abc");
haystack.insert(42, "abc123");
haystack.insert(84, "abc123");
QByteArrayMatcher matcher1;
matcher1 = QByteArrayMatcher(QByteArray(needle));
QByteArrayMatcher matcher2;
matcher2.setPattern(QByteArray(needle));
QByteArrayMatcher matcher3 = QByteArrayMatcher(QByteArray(needle));
QByteArrayMatcher matcher4(needle, sizeof(needle) - 1);
QByteArrayMatcher matcher5(matcher2);
QByteArrayMatcher matcher6;
matcher6 = matcher3;
QCOMPARE(matcher1.indexIn(haystack), 42);
QCOMPARE(matcher2.indexIn(haystack), 42);
QCOMPARE(matcher3.indexIn(haystack), 42);
QCOMPARE(matcher4.indexIn(haystack), 42);
QCOMPARE(matcher5.indexIn(haystack), 42);
QCOMPARE(matcher6.indexIn(haystack), 42);
QCOMPARE(matcher1.indexIn(haystack.constData(), haystack.size()), 42);
QCOMPARE(matcher1.indexIn(haystack, 43), 84);
QCOMPARE(matcher1.indexIn(haystack.constData(), haystack.size(), 43), 84);
QCOMPARE(matcher1.indexIn(haystack, 85), -1);
QCOMPARE(matcher1.indexIn(haystack.constData(), haystack.size(), 85), -1);
QByteArrayMatcher matcher7(QByteArray("123"));
QCOMPARE(matcher7.indexIn(haystack), 6);
matcher7 = QByteArrayMatcher(QByteArray("abc"));
QCOMPARE(matcher7.indexIn(haystack), 31);
matcher7.setPattern(matcher4.pattern());
QCOMPARE(matcher7.indexIn(haystack), 42);
}
#define LONG_STRING__32 "abcdefghijklmnopqrstuvwxyz012345"
#define LONG_STRING__64 LONG_STRING__32 LONG_STRING__32
#define LONG_STRING_128 LONG_STRING__64 LONG_STRING__64
#define LONG_STRING_256 LONG_STRING_128 LONG_STRING_128
void tst_QByteArrayMatcher::indexIn()
{
const char p_data[] = { 0x0, 0x0, 0x1 };
QByteArray pattern(p_data, sizeof(p_data));
QByteArray haystack(8, '\0');
haystack[7] = 0x1;
QByteArrayMatcher matcher;
matcher = QByteArrayMatcher(pattern);
QCOMPARE(matcher.indexIn(haystack, 0), 5);
QCOMPARE(matcher.indexIn(haystack, 1), 5);
QCOMPARE(matcher.indexIn(haystack, 2), 5);
matcher.setPattern(pattern);
QCOMPARE(matcher.indexIn(haystack, 0), 5);
QCOMPARE(matcher.indexIn(haystack, 1), 5);
QCOMPARE(matcher.indexIn(haystack, 2), 5);
QByteArray allChars(256, Qt::Uninitialized);
for (int i = 0; i < 256; ++i)
allChars[i] = char(i);
matcher = QByteArrayMatcher(allChars);
haystack = LONG_STRING__32 "x" + matcher.pattern();
QCOMPARE(matcher.indexIn(haystack, 0), 33);
QCOMPARE(matcher.indexIn(haystack, 1), 33);
QCOMPARE(matcher.indexIn(haystack, 2), 33);
QCOMPARE(matcher.indexIn(haystack, 33), 33);
QCOMPARE(matcher.indexIn(haystack, 34), -1);
matcher = QByteArrayMatcher(LONG_STRING_256);
haystack = LONG_STRING__32 "x" + matcher.pattern();
QCOMPARE(matcher.indexIn(haystack, 0), 33);
QCOMPARE(matcher.indexIn(haystack, 1), 33);
QCOMPARE(matcher.indexIn(haystack, 2), 33);
QCOMPARE(matcher.indexIn(haystack, 33), 33);
QCOMPARE(matcher.indexIn(haystack, 34), -1);
}
void tst_QByteArrayMatcher::staticByteArrayMatcher()
{
{
static constexpr auto smatcher = qMakeStaticByteArrayMatcher("Hello");
QCOMPARE(smatcher.pattern(), QByteArrayLiteral("Hello"));
QCOMPARE(smatcher.indexIn(QByteArray("Hello, World!")), 0);
QCOMPARE(smatcher.indexIn(QByteArray("Hello, World!"), 0), 0);
QCOMPARE(smatcher.indexIn(QByteArray("Hello, World!"), 1), -1);
QCOMPARE(smatcher.indexIn(QByteArray("aHello, World!")), 1);
QCOMPARE(smatcher.indexIn(QByteArray("aaHello, World!")), 2);
QCOMPARE(smatcher.indexIn(QByteArray("aaaHello, World!")), 3);
QCOMPARE(smatcher.indexIn(QByteArray("aaaaHello, World!")), 4);
QCOMPARE(smatcher.indexIn(QByteArray("aaaaaHello, World!")), 5);
QCOMPARE(smatcher.indexIn(QByteArray("aaaaaaHello, World!")), 6);
QCOMPARE(smatcher.indexIn(QByteArray("HHello, World!")), 1);
QCOMPARE(smatcher.indexIn(QByteArray("HeHello, World!")), 2);
QCOMPARE(smatcher.indexIn(QByteArray("HelHello, World!")), 3);
QCOMPARE(smatcher.indexIn(QByteArray("HellHello, World!")), 4);
QCOMPARE(smatcher.indexIn(QByteArray("HellaHello, World!")), 5);
QCOMPARE(smatcher.indexIn(QByteArray("HellauHello, World!")), 6);
QCOMPARE(smatcher.indexIn(QByteArray("aHella, World!")), -1);
QCOMPARE(smatcher.indexIn(QByteArray("aaHella, World!")), -1);
QCOMPARE(smatcher.indexIn(QByteArray("aaaHella, World!")), -1);
QCOMPARE(smatcher.indexIn(QByteArray("aaaaHella, World!")), -1);
QCOMPARE(smatcher.indexIn(QByteArray("aaaaaHella, World!")), -1);
QCOMPARE(smatcher.indexIn(QByteArray("aaaaaaHella, World!")), -1);
QCOMPARE(smatcher.indexIn(QByteArray("aHello")), 1);
QCOMPARE(smatcher.indexIn(QByteArray("aaHello")), 2);
QCOMPARE(smatcher.indexIn(QByteArray("aaaHello")), 3);
QCOMPARE(smatcher.indexIn(QByteArray("aaaaHello")), 4);
QCOMPARE(smatcher.indexIn(QByteArray("aaaaaHello")), 5);
QCOMPARE(smatcher.indexIn(QByteArray("aaaaaaHello")), 6);
QCOMPARE(smatcher.indexIn(QByteArray("HHello")), 1);
QCOMPARE(smatcher.indexIn(QByteArray("HeHello")), 2);
QCOMPARE(smatcher.indexIn(QByteArray("HelHello")), 3);
QCOMPARE(smatcher.indexIn(QByteArray("HellHello")), 4);
QCOMPARE(smatcher.indexIn(QByteArray("HellaHello")), 5);
QCOMPARE(smatcher.indexIn(QByteArray("HellauHello")), 6);
QCOMPARE(smatcher.indexIn(QByteArray("aHella")), -1);
QCOMPARE(smatcher.indexIn(QByteArray("aaHella")), -1);
QCOMPARE(smatcher.indexIn(QByteArray("aaaHella")), -1);
QCOMPARE(smatcher.indexIn(QByteArray("aaaaHella")), -1);
QCOMPARE(smatcher.indexIn(QByteArray("aaaaaHella")), -1);
QCOMPARE(smatcher.indexIn(QByteArray("aaaaaaHella")), -1);
}
{
static constexpr auto smatcher = qMakeStaticByteArrayMatcher(LONG_STRING_256);
QCOMPARE(smatcher.pattern(), QByteArrayLiteral(LONG_STRING_256));
QCOMPARE(smatcher.indexIn(QByteArray("a" LONG_STRING_256)), 1);
QCOMPARE(smatcher.indexIn(QByteArray("aa" LONG_STRING_256)), 2);
QCOMPARE(smatcher.indexIn(QByteArray("aaa" LONG_STRING_256)), 3);
QCOMPARE(smatcher.indexIn(QByteArray("aaaa" LONG_STRING_256)), 4);
QCOMPARE(smatcher.indexIn(QByteArray("aaaaa" LONG_STRING_256)), 5);
QCOMPARE(smatcher.indexIn(QByteArray("aaaaaa" LONG_STRING_256)), 6);
QCOMPARE(smatcher.indexIn(QByteArray("a" LONG_STRING_256 "a")), 1);
QCOMPARE(smatcher.indexIn(QByteArray("aa" LONG_STRING_256 "a")), 2);
QCOMPARE(smatcher.indexIn(QByteArray("aaa" LONG_STRING_256 "a")), 3);
QCOMPARE(smatcher.indexIn(QByteArray("aaaa" LONG_STRING_256 "a")), 4);
QCOMPARE(smatcher.indexIn(QByteArray("aaaaa" LONG_STRING_256 "a")), 5);
QCOMPARE(smatcher.indexIn(QByteArray("aaaaaa" LONG_STRING_256 "a")), 6);
QCOMPARE(smatcher.indexIn(QByteArray(LONG_STRING__32 "x" LONG_STRING_256)), 33);
QCOMPARE(smatcher.indexIn(QByteArray(LONG_STRING__64 "x" LONG_STRING_256)), 65);
QCOMPARE(smatcher.indexIn(QByteArray(LONG_STRING_128 "x" LONG_STRING_256)), 129);
}
}
void tst_QByteArrayMatcher::haystacksWithMoreThan4GiBWork()
{
#if QT_POINTER_SIZE > 4
// use a large needle to trigger long skips in the Boyer-Moore algorithm
// (to speed up the test)
constexpr std::string_view needle = LONG_STRING_256;
//
// GIVEN: a haystack with more than 4 GiB of data
//
// don't use QByteArray because freeSpaceAtEnd() may break reserve()
// semantics and a realloc is the last thing we need here
std::string large;
QElapsedTimer timer;
timer.start();
constexpr size_t GiB = 1024 * 1024 * 1024;
constexpr size_t BaseSize = 4 * GiB + 1;
try {
large.reserve(BaseSize + needle.size());
large.resize(BaseSize, '\0');
large.append(needle);
} catch (const std::bad_alloc &) {
QSKIP("Could not allocate 4GiB plus a couple hundred bytes of RAM.");
}
QCOMPARE(large.size(), BaseSize + needle.size());
qDebug("created dataset in %lld ms", timer.elapsed());
# if QT_CONFIG(cxx11_future)
using MaybeThread = std::thread;
# else
struct MaybeThread {
std::function<void()> func;
void join() { func(); }
};
# endif
//
// WHEN: trying to match an occurrence past the 4GiB mark
//
qsizetype dynamicResult, staticResult;
auto t = MaybeThread{[&]{
QByteArrayMatcher m(needle);
dynamicResult = m.indexIn(large);
}};
{
static_assert(needle == LONG_STRING_256); // need a string literal in the following line:
QStaticByteArrayMatcher m(LONG_STRING_256);
staticResult = m.indexIn(large.data(), large.size());
}
t.join();
//
// THEN: the result index is not trucated
//
QCOMPARE(staticResult, qsizetype(BaseSize));
QCOMPARE(dynamicResult, qsizetype(BaseSize));
#else
QSKIP("This test is 64-bit only.");
#endif
}
#undef LONG_STRING_256
#undef LONG_STRING_128
#undef LONG_STRING__64
#undef LONG_STRING__32
QTEST_APPLESS_MAIN(tst_QByteArrayMatcher)
#include "tst_qbytearraymatcher.moc"

View File

@ -0,0 +1,11 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qbytearrayview Test:
#####################################################################
qt_internal_add_test(tst_qbytearrayview
SOURCES
tst_qbytearrayview.cpp
)

View File

@ -0,0 +1,636 @@
// Copyright (C) 2020 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include <QByteArrayView>
#include <QTest>
// for negative testing (can't convert from)
#include <deque>
#include <list>
#include <QVarLengthArray>
template <typename T>
constexpr bool CanConvert = std::is_convertible_v<T, QByteArrayView>;
static_assert(!CanConvert<QString>);
static_assert(!CanConvert<QStringView>);
static_assert(!CanConvert<const char16_t*>);
static_assert(!CanConvert<char>);
static_assert(CanConvert<char[1]>);
static_assert(CanConvert<const char[1]>);
static_assert(CanConvert<char*>);
static_assert(CanConvert<const char*>);
static_assert(!CanConvert<uchar>);
static_assert(!CanConvert<uchar[1]>);
static_assert(!CanConvert<const uchar[1]>);
static_assert(CanConvert<uchar*>);
static_assert(CanConvert<const uchar*>);
static_assert(!CanConvert<signed char>);
static_assert(!CanConvert<signed char[1]>);
static_assert(!CanConvert<const signed char[1]>);
static_assert(CanConvert<signed char*>);
static_assert(CanConvert<const signed char*>);
static_assert(!CanConvert<std::byte>);
static_assert(!CanConvert<std::byte[1]>);
static_assert(!CanConvert<const std::byte[1]>);
static_assert(CanConvert<std::byte*>);
static_assert(CanConvert<const std::byte*>);
static_assert(CanConvert< QByteArray >);
static_assert(CanConvert<const QByteArray >);
static_assert(CanConvert< QByteArray&>);
static_assert(CanConvert<const QByteArray&>);
static_assert(CanConvert< std::string >);
static_assert(CanConvert<const std::string >);
static_assert(CanConvert< std::string&>);
static_assert(CanConvert<const std::string&>);
static_assert(CanConvert< std::string_view >);
static_assert(CanConvert<const std::string_view >);
static_assert(CanConvert< std::string_view&>);
static_assert(CanConvert<const std::string_view&>);
static_assert(CanConvert< QVector<char> >);
static_assert(CanConvert<const QVector<char> >);
static_assert(CanConvert< QVector<char>&>);
static_assert(CanConvert<const QVector<char>&>);
static_assert(CanConvert< QVarLengthArray<char> >);
static_assert(CanConvert<const QVarLengthArray<char> >);
static_assert(CanConvert< QVarLengthArray<char>&>);
static_assert(CanConvert<const QVarLengthArray<char>&>);
static_assert(CanConvert< std::vector<char> >);
static_assert(CanConvert<const std::vector<char> >);
static_assert(CanConvert< std::vector<char>&>);
static_assert(CanConvert<const std::vector<char>&>);
static_assert(CanConvert< std::array<char, 1> >);
static_assert(CanConvert<const std::array<char, 1> >);
static_assert(CanConvert< std::array<char, 1>&>);
static_assert(CanConvert<const std::array<char, 1>&>);
static_assert(!CanConvert<std::deque<char>>);
static_assert(!CanConvert<std::list<char>>);
class tst_QByteArrayView : public QObject
{
Q_OBJECT
private slots:
// Note: much of the shared API is tested in ../qbytearrayapisymmetry/
void constExpr() const;
void basics() const;
void literals() const;
void fromArray() const;
void literalsWithInternalNulls() const;
void at() const;
void fromQByteArray() const;
void fromCharStar() const
{
fromEmptyLiteral<char>();
conversionTests("Hello, World!");
}
void fromUCharStar() const
{
fromEmptyLiteral<uchar>();
const uchar data[] = { 'H', 'e', 'l', 'l', 'o', ',', ' ', 'W', 'o', 'r', 'l', 'd', '!', 0 };
conversionTests(data);
}
void fromSignedCharStar() const
{
fromEmptyLiteral<signed char>();
const signed char data[] = { 'H', 'e', 'l', 'l', 'o', ',', ' ', 'W', 'o', 'r', 'l', 'd', '!', 0 };
conversionTests(data);
}
void fromStdByteArray() const
{
fromEmptyLiteral<std::byte>();
const std::byte data[] = {std::byte{'H'}, std::byte{'e'}, std::byte{'l'}, std::byte{'l'},
std::byte{'o'}, std::byte{0}};
conversionTests(data);
}
void fromCharRange() const
{
const char data[] = { 'H', 'e', 'l', 'l', 'o', ',', ' ', 'W', 'o', 'r', 'l', 'd', '!' };
fromRange(std::begin(data), std::end(data));
}
void fromUCharRange() const
{
const uchar data[] = { 'H', 'e', 'l', 'l', 'o', ',', ' ', 'W', 'o', 'r', 'l', 'd', '!', 0 };
fromRange(std::begin(data), std::end(data));
}
void fromSignedCharRange() const
{
const signed char data[] = { 'H', 'e', 'l', 'l', 'o', ',', ' ', 'W', 'o', 'r', 'l', 'd', '!', 0 };
fromRange(std::begin(data), std::end(data));
}
void fromStdByteRange() const
{
const std::byte data[] = {std::byte{'H'}, std::byte{'e'}, std::byte{'l'}, std::byte{'l'},
std::byte{'o'}, std::byte{0}};
fromRange(std::begin(data), std::end(data));
}
void fromCharContainers() const
{
fromContainers<char>();
}
void fromUCharContainers() const
{
fromContainers<uchar>();
}
void fromSignedCharContainers() const
{
fromContainers<signed char>();
}
void fromStdByteContainers() const
{
fromContainers<std::byte>();
}
void comparison() const;
void compare() const;
private:
template <typename Data>
void conversionTests(Data arg) const;
template <typename Char>
void fromEmptyLiteral() const;
template <typename Char>
void fromRange(const Char *first, const Char *last) const;
template <typename Char, typename Container>
void fromContainer() const;
template <typename Char>
void fromContainers() const;
};
void tst_QByteArrayView::constExpr() const
{
// compile-time checks
{
constexpr QByteArrayView bv;
static_assert(bv.size() == 0);
static_assert(bv.isNull());
static_assert(bv.empty());
static_assert(bv.isEmpty());
static_assert(bv.data() == nullptr);
constexpr QByteArrayView bv2(bv.data(), bv.data() + bv.size());
static_assert(bv2.isNull());
static_assert(bv2.empty());
}
{
constexpr QByteArrayView bv = "";
static_assert(bv.size() == 0);
static_assert(!bv.isNull());
static_assert(bv.empty());
static_assert(bv.isEmpty());
static_assert(bv.data() != nullptr);
constexpr QByteArrayView bv2(bv.data(), bv.data() + bv.size());
static_assert(!bv2.isNull());
static_assert(bv2.empty());
}
{
static_assert(QByteArrayView("Hello").size() == 5);
constexpr QByteArrayView bv = "Hello";
static_assert(bv.size() == 5);
static_assert(!bv.empty());
static_assert(!bv.isEmpty());
static_assert(!bv.isNull());
static_assert(*bv.data() == 'H');
static_assert(bv[0] == 'H');
static_assert(bv.at(0) == 'H');
static_assert(bv.front() == 'H');
static_assert(bv.first() == 'H');
static_assert(bv[4] == 'o');
static_assert(bv.at(4) == 'o');
static_assert(bv.back() == 'o');
static_assert(bv.last() == 'o');
static_assert(*bv.begin() == 'H' );
static_assert(*(bv.end() - 1) == 'o' );
static_assert(*bv.cbegin() == 'H' );
static_assert(*(bv.cend() - 1) == 'o' );
static_assert(*bv.rbegin() == 'o' );
static_assert(*bv.crbegin() == 'o' );
// This is just to test that rend()/crend() are constexpr.
static_assert(bv.rbegin() != bv.rend());
static_assert(bv.crbegin() != bv.crend());
constexpr QByteArrayView bv2(bv.data(), bv.data() + bv.size());
static_assert(!bv2.isNull());
static_assert(!bv2.empty());
static_assert(bv2.size() == 5);
}
#if !defined(Q_CC_GNU) || defined(Q_CC_CLANG)
// Below checks are disabled because of a compilation issue with GCC and
// -fsanitize=undefined. See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71962.
// Note: Q_CC_GNU is also defined for Clang, so we need to check that too.
{
static constexpr char hello[] = "Hello";
constexpr QByteArrayView bv(hello);
static_assert(bv.size() == 5);
static_assert(!bv.empty());
static_assert(!bv.isEmpty());
static_assert(!bv.isNull());
static_assert(*bv.data() == 'H');
static_assert(bv[0] == 'H');
static_assert(bv.at(0) == 'H');
static_assert(bv.front() == 'H');
static_assert(bv.first() == 'H');
static_assert(bv[4] == 'o');
static_assert(bv.at(4) == 'o');
static_assert(bv.back() == 'o');
static_assert(bv.last() == 'o');
}
{
static constexpr char hello[] = { 'H', 'e', 'l', 'l', 'o' };
constexpr QByteArrayView bv(hello, std::size(hello));
static_assert(bv.size() == 5);
static_assert(!bv.empty());
static_assert(!bv.isEmpty());
static_assert(!bv.isNull());
static_assert(*bv.data() == 'H');
static_assert(bv[0] == 'H');
static_assert(bv.at(0) == 'H');
static_assert(bv.front() == 'H');
static_assert(bv.first() == 'H');
static_assert(bv[4] == 'o');
static_assert(bv.at(4) == 'o');
static_assert(bv.back() == 'o');
static_assert(bv.last() == 'o');
}
#endif
{
constexpr char *null = nullptr;
constexpr QByteArrayView bv(null);
static_assert(bv.isNull());
static_assert(bv.isEmpty());
static_assert(bv.size() == 0);
}
}
void tst_QByteArrayView::basics() const
{
QByteArrayView bv1;
// a default-constructed QByteArrayView is null:
QVERIFY(bv1.isNull());
// which implies it's empty();
QVERIFY(bv1.isEmpty());
QByteArrayView bv2;
QVERIFY(bv2 == bv1);
QVERIFY(!(bv2 != bv1));
}
// Note: initially the size would be deduced from the array literal,
// but it caused source compatibility issues so this is currently not the case.
void tst_QByteArrayView::literals() const
{
const char hello[] = "Hello\0This shouldn't be found";
QCOMPARE(QByteArrayView(hello).size(), 5);
QCOMPARE(QByteArrayView(hello + 0).size(), 5); // forces decay to pointer
QByteArrayView bv = hello;
QCOMPARE(bv.size(), 5);
QVERIFY(!bv.empty());
QVERIFY(!bv.isEmpty());
QVERIFY(!bv.isNull());
QCOMPARE(*bv.data(), 'H');
QCOMPARE(bv[0], 'H');
QCOMPARE(bv.at(0), 'H');
QCOMPARE(bv.front(), 'H');
QCOMPARE(bv.first(), 'H');
QCOMPARE(bv[4], 'o');
QCOMPARE(bv.at(4), 'o');
QCOMPARE(bv.back(), 'o');
QCOMPARE(bv.last(), 'o');
QByteArrayView bv2(bv.data(), bv.data() + bv.size());
QVERIFY(!bv2.isNull());
QVERIFY(!bv2.empty());
QCOMPARE(bv2.size(), 5);
const char abc[] = "abc";
bv = abc;
QCOMPARE(bv.size(), 3);
const char def[3] = {'d', 'e', 'f'};
bv = def;
QCOMPARE(bv.size(), 3);
}
void tst_QByteArrayView::fromArray() const
{
static constexpr char hello[] = "Hello\0abc\0\0.";
constexpr QByteArrayView bv = QByteArrayView::fromArray(hello);
QCOMPARE(bv.size(), 13);
QVERIFY(!bv.empty());
QVERIFY(!bv.isEmpty());
QVERIFY(!bv.isNull());
QCOMPARE(*bv.data(), 'H');
QCOMPARE(bv[0], 'H');
QCOMPARE(bv.at(0), 'H');
QCOMPARE(bv.front(), 'H');
QCOMPARE(bv.first(), 'H');
QCOMPARE(bv[4], 'o');
QCOMPARE(bv.at(4), 'o');
QCOMPARE(bv[5], '\0');
QCOMPARE(bv.at(5), '\0');
QCOMPARE(*(bv.data() + bv.size() - 2), '.');
QCOMPARE(bv.back(), '\0');
QCOMPARE(bv.last(), '\0');
const std::byte bytes[] = {std::byte(0x0), std::byte(0x1), std::byte(0x2)};
QByteArrayView bbv = QByteArrayView::fromArray(bytes);
QCOMPARE(bbv.data(), reinterpret_cast<const char *>(bytes + 0));
QCOMPARE(bbv.size(), 3);
QCOMPARE(bbv.first(), 0x0);
QCOMPARE(bbv.last(), 0x2);
}
void tst_QByteArrayView::literalsWithInternalNulls() const
{
const char withnull[] = "a\0zzz";
// these are different results
QCOMPARE(size_t(QByteArrayView::fromArray(withnull).size()), std::size(withnull));
QCOMPARE(QByteArrayView(withnull + 0).size(), 1);
QByteArrayView nulled = QByteArrayView::fromArray(withnull);
QCOMPARE(nulled.last(), '\0');
nulled.chop(1); // cut off trailing \0
QCOMPARE(nulled[1], '\0');
QCOMPARE(nulled.indexOf('\0'), 1);
QCOMPARE(nulled.indexOf('z'), 2);
QCOMPARE(nulled.lastIndexOf('z'), 4);
QCOMPARE(nulled.lastIndexOf('a'), 0);
QVERIFY(nulled.startsWith("a\0z"));
QVERIFY(nulled.startsWith("a\0y"));
QVERIFY(!nulled.startsWith(QByteArrayView("a\0y", 3)));
QVERIFY(nulled.endsWith("zz"));
QVERIFY(nulled.contains("z"));
QVERIFY(nulled.contains(QByteArrayView("\0z", 2)));
QVERIFY(!nulled.contains(QByteArrayView("\0y", 2)));
QCOMPARE(nulled.first(5), QByteArrayView(withnull, 5));
QCOMPARE(nulled.last(5), QByteArrayView(withnull, 5));
QCOMPARE(nulled.sliced(0), QByteArrayView(withnull, 5));
QCOMPARE(nulled.sliced(2, 2), "zz");
QCOMPARE(nulled.chopped(2), QByteArrayView("a\0z", 3));
QVERIFY(nulled.chopped(2) != QByteArrayView("a\0y", 3));
QCOMPARE(nulled.count('z'), 3);
const char nullfirst[] = "\0buzz";
QByteArrayView fromnull = QByteArrayView::fromArray(nullfirst);
QVERIFY(!fromnull.isEmpty());
const char nullNotEnd[] = { 'b', 'o', 'w', '\0', 'a', 'f', 't', 'z' };
QByteArrayView midNull = QByteArrayView::fromArray(nullNotEnd);
QCOMPARE(midNull.back(), 'z');
}
void tst_QByteArrayView::at() const
{
QByteArray hello("Hello");
QByteArrayView bv(hello);
QCOMPARE(bv.at(0), 'H'); QCOMPARE(bv[0], 'H');
QCOMPARE(bv.at(1), 'e'); QCOMPARE(bv[1], 'e');
QCOMPARE(bv.at(2), 'l'); QCOMPARE(bv[2], 'l');
QCOMPARE(bv.at(3), 'l'); QCOMPARE(bv[3], 'l');
QCOMPARE(bv.at(4), 'o'); QCOMPARE(bv[4], 'o');
}
void tst_QByteArrayView::fromQByteArray() const
{
QByteArray null;
QByteArray empty = "";
QVERIFY(QByteArrayView(null).isNull());
QVERIFY(!qToByteArrayViewIgnoringNull(null).isNull());
QVERIFY(QByteArrayView(null).isEmpty());
QVERIFY(qToByteArrayViewIgnoringNull(null).isEmpty());
QVERIFY(QByteArrayView(empty).isEmpty());
QVERIFY(qToByteArrayViewIgnoringNull(empty).isEmpty());
QVERIFY(!QByteArrayView(empty).isNull());
QVERIFY(!qToByteArrayViewIgnoringNull(empty).isNull());
conversionTests(QByteArray("Hello World!"));
}
namespace help {
template <typename T>
size_t size(const T &t) { return size_t(t.size()); }
template <typename T>
size_t size(const T *t) { return std::char_traits<T>::length(t); }
template <typename T>
decltype(auto) cbegin(const T &t) { return t.begin(); }
template <typename T>
const T * cbegin(const T *t) { return t; }
template <typename T>
decltype(auto) cend(const T &t) { return t.end(); }
template <typename T>
const T * cend(const T *t) { return t + size(t); }
template <typename T>
decltype(auto) crbegin(const T &t) { return t.rbegin(); }
template <typename T>
std::reverse_iterator<const T*> crbegin(const T *t) { return std::reverse_iterator<const T*>(cend(t)); }
template <typename T>
decltype(auto) crend(const T &t) { return t.rend(); }
template <typename T>
std::reverse_iterator<const T*> crend(const T *t) { return std::reverse_iterator<const T*>(cbegin(t)); }
} // namespace help
template <typename Data>
void tst_QByteArrayView::conversionTests(Data data) const
{
// copy-construct:
{
QByteArrayView bv = data;
QCOMPARE(help::size(bv), help::size(data));
const auto compare = [](auto v1, auto v2) {
if constexpr (std::is_same_v<decltype(v1), std::byte>)
return std::to_integer<char>(v1) == v2;
else
return v1 == v2;
};
QVERIFY(std::equal(help::cbegin(data), help::cend(data),
QT_MAKE_CHECKED_ARRAY_ITERATOR(bv.cbegin(), bv.size()), compare));
QVERIFY(std::equal(help::cbegin(data), help::cend(data),
QT_MAKE_CHECKED_ARRAY_ITERATOR(bv.begin(), bv.size()), compare));
QVERIFY(std::equal(help::crbegin(data), help::crend(data), bv.crbegin(), compare));
QVERIFY(std::equal(help::crbegin(data), help::crend(data), bv.rbegin(), compare));
QCOMPARE(bv, data);
}
QByteArrayView bv;
// copy-assign:
{
bv = data;
QCOMPARE(help::size(bv), help::size(data));
// check relational operators:
QCOMPARE(bv, data);
QCOMPARE(data, bv);
QVERIFY(!(bv != data));
QVERIFY(!(data != bv));
QVERIFY(!(bv < data));
QVERIFY(bv <= data);
QVERIFY(!(bv > data));
QVERIFY(bv >= data);
QVERIFY(!(data < bv));
QVERIFY(data <= bv);
QVERIFY(!(data > bv));
QVERIFY(data >= bv);
}
// copy-construct from rvalue (QByteArrayView never assumes ownership):
{
QByteArrayView bv2 = std::move(data);
QCOMPARE(bv2, bv);
QCOMPARE(bv2, data);
}
// copy-assign from rvalue (QByteArrayView never assumes ownership):
{
QByteArrayView bv2;
bv2 = std::move(data);
QCOMPARE(bv2, bv);
QCOMPARE(bv2, data);
}
}
template <typename Char>
void tst_QByteArrayView::fromEmptyLiteral() const
{
const Char *null = nullptr;
const Char empty[] = { Char{0} };
QCOMPARE(QByteArrayView(null).size(), 0);
QCOMPARE(QByteArrayView(null).data(), nullptr);
QCOMPARE(QByteArrayView::fromArray(empty).size(), 1);
QCOMPARE(static_cast<const void*>(QByteArrayView::fromArray(empty).data()),
static_cast<const void*>(empty));
QVERIFY(QByteArrayView(null).isNull());
QVERIFY(QByteArrayView(null).isEmpty());
QVERIFY(!QByteArrayView::fromArray(empty).isEmpty());
QVERIFY(!QByteArrayView::fromArray(empty).isNull());
}
template <typename Char>
void tst_QByteArrayView::fromRange(const Char *first, const Char *last) const
{
const Char *null = nullptr;
QCOMPARE(QByteArrayView(null, null).size(), 0);
QCOMPARE(QByteArrayView(null, null).data(), nullptr);
QCOMPARE(QByteArrayView(first, first).size(), 0);
QCOMPARE(static_cast<const void*>(QByteArrayView(first, first).data()),
static_cast<const void*>(first));
const auto bv = QByteArrayView(first, last);
QCOMPARE(bv.size(), last - first);
QCOMPARE(static_cast<const void*>(bv.data()),
static_cast<const void*>(first));
QCOMPARE(static_cast<const void*>(bv.last(0).data()),
static_cast<const void*>(last));
QCOMPARE(static_cast<const void*>(bv.sliced(bv.size()).data()),
static_cast<const void*>(last));
// can't call conversionTests() here, as it requires a single object
}
template <typename Char, typename Container>
void tst_QByteArrayView::fromContainer() const
{
const QByteArray s = "Hello World!";
Container c;
// unspecified whether empty containers make null QByteArrayView
QVERIFY(QByteArrayView(c).isEmpty());
QCOMPARE(sizeof(Char), sizeof(char));
const auto *data = reinterpret_cast<const Char *>(s.data());
std::copy(data, data + s.size(), std::back_inserter(c));
conversionTests(std::move(c));
}
template <typename Char>
void tst_QByteArrayView::fromContainers() const
{
fromContainer<Char, QVector<Char>>();
fromContainer<Char, QVarLengthArray<Char>>();
fromContainer<Char, std::vector<Char>>();
fromContainer<Char, std::basic_string<Char>>();
}
void tst_QByteArrayView::comparison() const
{
const QByteArrayView aa = "aa";
const QByteArrayView bb = "bb";
QVERIFY(aa == aa);
QVERIFY(aa != bb);
QVERIFY(aa < bb);
QVERIFY(bb > aa);
}
void tst_QByteArrayView::compare() const
{
QByteArrayView alpha = "original";
QVERIFY(alpha.compare("original", Qt::CaseSensitive) == 0);
QVERIFY(alpha.compare("Original", Qt::CaseSensitive) > 0);
QVERIFY(alpha.compare("Original", Qt::CaseInsensitive) == 0);
QByteArrayView beta = "unoriginal";
QVERIFY(alpha.compare(beta, Qt::CaseInsensitive) < 0);
beta = "Unoriginal";
QVERIFY(alpha.compare(beta, Qt::CaseInsensitive) < 0);
QVERIFY(alpha.compare(beta, Qt::CaseSensitive) > 0);
}
QTEST_APPLESS_MAIN(tst_QByteArrayView)
#include "tst_qbytearrayview.moc"

View File

@ -0,0 +1,13 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qbytedatabuffer Test:
#####################################################################
qt_internal_add_test(tst_qbytedatabuffer
SOURCES
tst_qbytedatabuffer.cpp
LIBRARIES
Qt::CorePrivate
)

View File

@ -0,0 +1,204 @@
// Copyright (C) 2012 Hewlett-Packard Development Company, L.P.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include <QTest>
#include <private/qbytedata_p.h>
// for QIODEVICE_BUFFERSIZE macro (== 16384):
#include <private/qiodevice_p.h>
class tst_QByteDataBuffer : public QObject
{
Q_OBJECT
private Q_SLOTS:
void canReadLine();
void positionHandling();
void appendBuffer();
void moveAppendBuffer();
void readCompleteBuffer_data();
void readCompleteBuffer();
void readPartialBuffer_data();
void readPartialBuffer();
void readPointer();
private:
void readBuffer(int size, int readSize);
};
void tst_QByteDataBuffer::canReadLine()
{
QByteDataBuffer buf;
buf.append(QByteArray("a"));
buf.append(QByteArray("\nb"));
QVERIFY(buf.canReadLine());
QVERIFY(buf.getChar() == 'a');
QVERIFY(buf.canReadLine());
QVERIFY(buf.getChar() == '\n');
QVERIFY(!buf.canReadLine());
}
void tst_QByteDataBuffer::positionHandling()
{
QByteDataBuffer buf;
buf.append(QByteArray("abc"));
buf.append(QByteArray("def"));
QCOMPARE(buf.byteAmount(), (qlonglong)6);
QCOMPARE(buf.sizeNextBlock(), (qlonglong)3);
QCOMPARE(buf.getChar(), 'a');
QCOMPARE(buf.byteAmount(), (qlonglong)5);
QCOMPARE(buf.sizeNextBlock(), (qlonglong)2);
QVERIFY(!strcmp(buf[0].constData(), "bc"));
QCOMPARE(buf.getChar(), 'b');
QCOMPARE(buf.byteAmount(), (qlonglong)4);
QCOMPARE(buf.sizeNextBlock(), (qlonglong)1);
QByteArray tmp("ab");
buf.prepend(tmp);
QCOMPARE(buf.byteAmount(), (qlonglong)6);
QVERIFY(!strcmp(buf.readAll().constData(), "abcdef"));
QCOMPARE(buf.byteAmount(), (qlonglong)0);
QByteDataBuffer buf2;
buf2.append(QByteArray("abc"));
buf2.getChar();
QCOMPARE(buf2.read(), QByteArray("bc"));
}
void tst_QByteDataBuffer::appendBuffer()
{
QByteDataBuffer buf;
QByteArray local("\1\2\3");
buf.append(local);
buf.getChar();
QByteDataBuffer tmp;
tmp.append(buf);
QCOMPARE(tmp.readAll(), buf.readAll());
}
void tst_QByteDataBuffer::moveAppendBuffer()
{
QByteDataBuffer buf;
buf.append(QByteArray("hello world"));
QCOMPARE(buf.getChar(), 'h');
QByteDataBuffer tmp;
tmp.append(std::move(buf));
QCOMPARE(tmp.readAll(), "ello world");
}
static QByteArray makeByteArray(int size)
{
QByteArray array;
array.resize(size);
char *data = array.data();
for (int i = 0; i < size; ++i)
data[i] = i % 256;
return array;
}
void tst_QByteDataBuffer::readBuffer(int size, int readSize)
{
QByteArray data = makeByteArray(size);
QByteDataBuffer buf;
buf.append(data);
QByteArray tmp;
tmp.resize(size);
QBENCHMARK_ONCE {
for (int i = 0; i < (size - 1) / readSize + 1; ++i)
buf.read(tmp.data() + i * readSize, readSize);
}
QCOMPARE(data.size(), tmp.size());
QCOMPARE(data, tmp);
}
void tst_QByteDataBuffer::readCompleteBuffer_data()
{
QTest::addColumn<int>("size");
QTest::newRow("10B") << (int)10;
QTest::newRow("1MB") << (int)1e6;
QTest::newRow("5MB") << (int)5e6;
QTest::newRow("10MB") << (int)10e6;
}
void tst_QByteDataBuffer::readCompleteBuffer()
{
QFETCH(int, size);
readBuffer(size, size);
}
void tst_QByteDataBuffer::readPartialBuffer_data()
{
readCompleteBuffer_data();
}
void tst_QByteDataBuffer::readPartialBuffer()
{
QFETCH(int, size);
// QIODevice::readAll() reads in QIODEVICE_BUFFERSIZE size
// increments.
readBuffer(size, QIODEVICE_BUFFERSIZE);
}
void tst_QByteDataBuffer::readPointer()
{
QByteDataBuffer buffer;
auto view = buffer.readPointer();
QCOMPARE(view.size(), 0);
QCOMPARE(view, "");
buffer.append("Hello");
buffer.append("World");
qint64 initialSize = buffer.byteAmount();
view = buffer.readPointer();
QCOMPARE(initialSize, buffer.byteAmount());
QCOMPARE(view.size(), 5);
QCOMPARE(view, "Hello");
buffer.advanceReadPointer(2);
view = buffer.readPointer();
QCOMPARE(initialSize - 2, buffer.byteAmount());
QCOMPARE(view.size(), 3);
QCOMPARE(view, "llo");
buffer.advanceReadPointer(3);
view = buffer.readPointer();
QCOMPARE(initialSize - 5, buffer.byteAmount());
QCOMPARE(view.size(), 5);
QCOMPARE(view, "World");
buffer.advanceReadPointer(5);
view = buffer.readPointer();
QVERIFY(buffer.isEmpty());
QCOMPARE(view.size(), 0);
QCOMPARE(view, "");
// Advance past the current view's size
buffer.append("Hello");
buffer.append("World");
buffer.advanceReadPointer(6);
view = buffer.readPointer();
QCOMPARE(view, "orld");
QCOMPARE(buffer.byteAmount(), 4);
// Advance past the end of all contained data
buffer.advanceReadPointer(6);
view = buffer.readPointer();
QCOMPARE(view, "");
}
QTEST_MAIN(tst_QByteDataBuffer)
#include "tst_qbytedatabuffer.moc"

View File

@ -0,0 +1,17 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qchar Test:
#####################################################################
# Collect test data
list(APPEND test_data "data/NormalizationTest.txt")
qt_internal_add_test(tst_qchar
SOURCES
tst_qchar.cpp
LIBRARIES
Qt::CorePrivate
TESTDATA ${test_data}
)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,15 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qcollator Test:
#####################################################################
qt_internal_add_test(tst_qcollator
SOURCES
tst_qcollator.cpp
DEFINES
QT_NO_CAST_TO_ASCII
LIBRARIES
Qt::CorePrivate
)

View File

@ -0,0 +1,349 @@
// Copyright (C) 2021 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include <QTest>
#include <qlocale.h>
#include <qcollator.h>
#include <private/qglobal_p.h>
#include <QScopeGuard>
#include <cstring>
class tst_QCollator : public QObject
{
Q_OBJECT
private Q_SLOTS:
void basics();
void moveSemantics();
void compare_data();
void compare();
void state();
};
static bool dpointer_is_null(QCollator &c)
{
char mem[sizeof c];
using namespace std;
memcpy(mem, &c, sizeof c);
for (size_t i = 0; i < sizeof c; ++i)
if (mem[i])
return false;
return true;
}
void tst_QCollator::basics()
{
const QLocale de_AT(QLocale::German, QLocale::Austria);
QCollator c1(de_AT);
QCOMPARE(c1.locale(), de_AT);
QCollator c2(c1);
QCOMPARE(c2.locale(), de_AT);
QCollator c3;
// Test copy assignment
c3 = c2;
QCOMPARE(c3.locale(), de_AT);
// posix implementation supports only C and default locale,
// so update it for Android and INTEGRITY builds
#if defined(Q_OS_ANDROID) || defined(Q_OS_INTEGRITY)
c3.setLocale(QLocale());
#endif
QCollatorSortKey key1 = c3.sortKey("test");
QCollatorSortKey key2(key1);
QCOMPARE(key1.compare(key2), 0);
QCollatorSortKey key3 = c3.sortKey("abc");
// Test copy assignment
key3 = key2;
QCOMPARE(key1.compare(key3), 0);
}
void tst_QCollator::moveSemantics()
{
const QLocale de_AT(QLocale::German, QLocale::Austria);
QCollator c1(de_AT);
QCOMPARE(c1.locale(), de_AT);
QCollator c2(std::move(c1));
QCOMPARE(c2.locale(), de_AT);
QVERIFY(dpointer_is_null(c1));
QCollator c3(c1);
QVERIFY(dpointer_is_null(c3));
c1 = std::move(c2);
QCOMPARE(c1.locale(), de_AT);
QVERIFY(dpointer_is_null(c2));
// test QCollatorSortKey move assignment
// posix implementation supports only C and default locale,
// so update it for Android and INTEGRITY builds
#if defined(Q_OS_ANDROID) || defined(Q_OS_INTEGRITY)
c1.setLocale(QLocale());
#endif
QCollatorSortKey key1 = c1.sortKey("1");
QCollatorSortKey key2 = c1.sortKey("2");
QVERIFY(key1.compare(key2) < 0);
QCollatorSortKey key3 = c1.sortKey("a");
// test move assignment
key3 = std::move(key2);
QVERIFY(key1.compare(key3) < 0);
}
void tst_QCollator::compare_data()
{
QTest::addColumn<QString>("locale");
QTest::addColumn<QString>("s1");
QTest::addColumn<QString>("s2");
QTest::addColumn<int>("result");
QTest::addColumn<int>("caseInsensitiveResult");
QTest::addColumn<bool>("numericMode");
QTest::addColumn<bool>("ignorePunctuation");
QTest::addColumn<int>("punctuationResult"); // Test ignores punctuation *and case*
/*
It's hard to test English, because it's treated differently
on different platforms. For example, on Linux, it uses the
iso14651_t1 template file, which happens to provide good
defaults for Swedish. OS X seems to do a pure bytewise
comparison of Latin-1 values, although I'm not sure. So I
just test digits to make sure that it's not totally broken.
*/
QTest::newRow("english1") << QString("en_US") << QString("5") << QString("4") << 1 << 1 << false << false << 1;
QTest::newRow("english2") << QString("en_US") << QString("4") << QString("6") << -1 << -1 << false << false << -1;
QTest::newRow("english3") << QString("en_US") << QString("5") << QString("6") << -1 << -1 << false << false << -1;
QTest::newRow("english4") << QString("en_US") << QString("a") << QString("b") << -1 << -1 << false << false << -1;
QTest::newRow("english5") << QString("en_US") << QString("test 9") << QString("test 19") << -1 << -1 << true << false << -1;
QTest::newRow("english6") << QString("en_US") << QString("test 9") << QString("test_19") << -1 << -1 << true << true << -1;
QTest::newRow("english7") << QString("en_US") << QString("test_19") << QString("test 19") << 1 << 1 << true << false << 1;
QTest::newRow("english8") << QString("en_US") << QString("test.19") << QString("test,19") << 1 << 1 << true << true << 0;
QTest::newRow("en-empty-word") << QString("en_US") << QString() << QString("non-empty") << -1 << -1 << false << true << -1;
QTest::newRow("en-empty-number") << QString("en_US") << QString() << QString("42") << -1 << -1 << true << true << -1;
QTest::newRow("en-word-empty") << QString("en_US") << QString("non-empty") << QString() << 1
<< 1 << false << true << 1;
QTest::newRow("en-number-empty")
<< QString("en_US") << QString("42") << QString() << 1 << 1 << true << true << 1;
QTest::newRow("en-empty-empty")
<< QString("en_US") << QString() << QString() << 0 << 0 << false << true << 0;
/*
In Swedish, a with ring above (E5) comes before a with
diaresis (E4), which comes before o diaresis (F6), which
all come after z.
*/
QTest::newRow("swedish1") << QString("sv_SE") << QString::fromLatin1("\xe5") << QString::fromLatin1("\xe4") << -1 << -1 << false << false << -1;
QTest::newRow("swedish2") << QString("sv_SE") << QString::fromLatin1("\xe4") << QString::fromLatin1("\xf6") << -1 << -1 << false << false << -1;
QTest::newRow("swedish3") << QString("sv_SE") << QString::fromLatin1("\xe5") << QString::fromLatin1("\xf6") << -1 << -1 << false << false << -1;
QTest::newRow("swedish4") << QString("sv_SE") << QString::fromLatin1("z") << QString::fromLatin1("\xe5") << -1 << -1 << false << false << -1;
QTest::newRow("swedish5") << QString("sv_SE") << QString("9") << QString("19") << -1 << -1 << true << false << -1;
QTest::newRow("swedish6") << QString("sv_SE") << QString("Test 9") << QString("Test_19") << -1 << -1 << true << true << -1;
QTest::newRow("swedish7") << QString("sv_SE") << QString("test_19") << QString("test 19") << 1 << 1 << true << false << 1;
QTest::newRow("swedish8") << QString("sv_SE") << QString("test.19") << QString("test,19") << 1 << 1 << true << true << 0;
QTest::newRow("sv-empty-word") << QString("sv_SE") << QString() << QString("mett") << -1 << -1 << false << true << -1;
QTest::newRow("sv-empty-number") << QString("sv_SE") << QString() << QString("42") << -1 << -1 << true << true << -1;
QTest::newRow("sv-word-empty")
<< QString("sv_SE") << QString("mett") << QString() << 1 << 1 << false << true << 1;
QTest::newRow("sv-number-empty")
<< QString("sv_SE") << QString("42") << QString() << 1 << 1 << true << true << 1;
QTest::newRow("sv-empty-empty")
<< QString("sv_SE") << QString() << QString() << 0 << 0 << false << true << 0;
/*
In Norwegian, ae (E6) comes before o with stroke (D8), which
comes before a with ring above (E5).
*/
QTest::newRow("norwegian1") << QString("no_NO") << QString::fromLatin1("\xe6") << QString::fromLatin1("\xd8") << -1 << -1 << false << false << -1;
QTest::newRow("norwegian2") << QString("no_NO") << QString::fromLatin1("\xd8") << QString::fromLatin1("\xe5") << -1 << -1 << false << false << -1;
QTest::newRow("norwegian3") << QString("no_NO") << QString::fromLatin1("\xe6") << QString::fromLatin1("\xe5") << -1 << -1 << false << false << -1;
QTest::newRow("norwegian4") << QString("no_NO") << QString("9") << QString("19") << -1 << -1 << true << false << -1;
QTest::newRow("norwegian5") << QString("no_NO") << QString("Test 9") << QString("Test_19") << -1 << -1 << true << true << -1;
QTest::newRow("norwegian6") << QString("no_NO") << QString("Test 9") << QString("Test_19") << -1 << -1 << true << true << -1;
QTest::newRow("norwegian7") << QString("no_NO") << QString("test_19") << QString("test 19") << 1 << 1 << true << false << 1;
QTest::newRow("norwegian8") << QString("no_NO") << QString("test.19") << QString("test,19") << 1 << 1 << true << true << 0;
QTest::newRow("nb-empty-word") << QString("nb_NO") << QString() << QString("mett") << -1 << -1 << false << true << -1;
QTest::newRow("nb-empty-number") << QString("nb_NO") << QString() << QString("42") << -1 << -1 << true << true << -1;
QTest::newRow("nb-word-empty")
<< QString("nb_NO") << QString("mett") << QString() << 1 << 1 << false << true << 1;
QTest::newRow("nb-number-empty")
<< QString("nb_NO") << QString("42") << QString() << 1 << 1 << true << true << 1;
QTest::newRow("nb-empty-empty")
<< QString("nb_NO") << QString() << QString() << 0 << 0 << false << true << 0;
/*
In German, z comes *after* a with diaresis (E4),
which comes before o diaresis (F6).
*/
QTest::newRow("german1") << QString("de_DE") << QString::fromLatin1("a") << QString::fromLatin1("\xe4") << -1 << -1 << false << false << -1;
QTest::newRow("german2") << QString("de_DE") << QString::fromLatin1("b") << QString::fromLatin1("\xe4") << 1 << 1 << false << false << 1;
QTest::newRow("german3") << QString("de_DE") << QString::fromLatin1("z") << QString::fromLatin1("\xe4") << 1 << 1 << false << false << 1;
QTest::newRow("german4") << QString("de_DE") << QString::fromLatin1("\xe4") << QString::fromLatin1("\xf6") << -1 << -1 << false << false << -1;
QTest::newRow("german5") << QString("de_DE") << QString::fromLatin1("z") << QString::fromLatin1("\xf6") << 1 << 1 << false << false << 1;
QTest::newRow("german6") << QString("de_DE") << QString::fromLatin1("\xc0") << QString::fromLatin1("\xe0") << 1 << 0 << false << false << 0;
QTest::newRow("german7") << QString("de_DE") << QString::fromLatin1("\xd6") << QString::fromLatin1("\xf6") << 1 << 0 << false << false << 0;
QTest::newRow("german8") << QString("de_DE") << QString::fromLatin1("oe") << QString::fromLatin1("\xf6") << 1 << 1 << false << false << 1;
QTest::newRow("german9") << QString("de_DE") << QString("A") << QString("a") << 1 << 0 << false << false << 0;
QTest::newRow("german10") << QString("de_DE") << QString("9") << QString("19") << -1 << -1 << true << false << -1;
QTest::newRow("german11") << QString("de_DE") << QString("Test 9") << QString("Test_19") << -1 << -1 << true << true << -1;
QTest::newRow("german12") << QString("de_DE") << QString("test_19") << QString("test 19") << 1 << 1 << true << false << 1;
QTest::newRow("german13") << QString("de_DE") << QString("test.19") << QString("test,19") << 1 << 1 << true << true << 0;
QTest::newRow("de-empty-word") << QString("de_DE") << QString() << QString("satt") << -1 << -1 << false << true << -1;
QTest::newRow("de-empty-number") << QString("de_DE") << QString() << QString("42") << -1 << -1 << true << true << -1;
QTest::newRow("de-word-empty")
<< QString("de_DE") << QString("satt") << QString() << 1 << 1 << false << true << 1;
QTest::newRow("de-number-empty")
<< QString("de_DE") << QString("42") << QString() << 1 << 1 << true << true << 1;
QTest::newRow("de-empty-empty")
<< QString("de_DE") << QString() << QString() << 0 << 0 << false << true << 0;
/*
French sorting of e and e with acute accent
*/
QTest::newRow("french1") << QString("fr_FR") << QString::fromLatin1("\xe9") << QString::fromLatin1("e") << 1 << 1 << false << false << 1;
QTest::newRow("french2") << QString("fr_FR") << QString::fromLatin1("\xe9t") << QString::fromLatin1("et") << 1 << 1 << false << false << 1;
QTest::newRow("french3") << QString("fr_FR") << QString::fromLatin1("\xe9") << QString::fromLatin1("d") << 1 << 1 << false << false << 1;
QTest::newRow("french4") << QString("fr_FR") << QString::fromLatin1("\xe9") << QString::fromLatin1("f") << -1 << -1 << false << false << -1;
QTest::newRow("french5") << QString("fr_FR") << QString("9") << QString("19") << -1 << -1 << true << false << -1;
QTest::newRow("french6") << QString("fr_FR") << QString("Test 9") << QString("Test_19") << -1 << -1 << true << true << -1;
QTest::newRow("french7") << QString("fr_FR") << QString("test_19") << QString("test 19") << 1 << 1 << true << false << 1;
QTest::newRow("french8") << QString("fr_FR") << QString("test.19") << QString("test,19") << 1 << 1 << true << true << 0;
QTest::newRow("fr-empty-word") << QString("fr_FR") << QString() << QString("plein") << -1 << -1 << false << true << -1;
QTest::newRow("fr-empty-number") << QString("fr_FR") << QString() << QString("42") << -1 << -1 << true << true << -1;
QTest::newRow("fr-word-empty")
<< QString("fr_FR") << QString("plein") << QString() << 1 << 1 << false << true << 1;
QTest::newRow("fr-number-empty")
<< QString("fr_FR") << QString("42") << QString() << 1 << 1 << true << true << 1;
QTest::newRow("fr-empty-empty")
<< QString("fr_FR") << QString() << QString() << 0 << 0 << false << true << 0;
// C locale: case sensitive [A-Z] < [a-z] but case insensitive [Aa] < [Bb] <...< [Zz]
const QString C = QStringLiteral("C");
QTest::newRow("C:ABBA:AaaA") << C << QStringLiteral("ABBA") << QStringLiteral("AaaA") << -1 << 1 << false << false << 1;
QTest::newRow("C:AZa:aAZ") << C << QStringLiteral("AZa") << QStringLiteral("aAZ") << -1 << 1 << false << false << 1;
QTest::newRow("C-empty-word") << QString(C) << QString() << QString("non-empty") << -1 << -1 << false << true << -1;
QTest::newRow("C-empty-number") << QString(C) << QString() << QString("42") << -1 << -1 << true << true << -1;
QTest::newRow("C-word-empty") << QString(C) << QString("non-empty") << QString() << 1 << 1
<< false << true << 1;
QTest::newRow("C-number-empty")
<< QString(C) << QString("42") << QString() << 1 << 1 << true << true << 1;
QTest::newRow("C-empty-empty")
<< QString(C) << QString() << QString() << 0 << 0 << false << true << 0;
}
void tst_QCollator::compare()
{
QFETCH(QString, locale);
QFETCH(QString, s1);
QFETCH(QString, s2);
QFETCH(int, result);
QFETCH(int, caseInsensitiveResult);
QFETCH(bool, numericMode);
QFETCH(bool, ignorePunctuation);
QFETCH(int, punctuationResult);
QCollator collator((QLocale(locale)));
// AFTER the QCollator initialization
auto localechanger = qScopeGuard([original = QLocale()] {
QLocale::setDefault(original); // reset back to what it was
});
QLocale::setDefault(QLocale(locale));
// Need to canonicalize sign to -1, 0 or 1, as .compare() can produce any -ve for <, any +ve for >.
auto asSign = [](int compared) {
return compared < 0 ? -1 : compared > 0 ? 1 : 0;
};
#if defined(Q_OS_ANDROID) || defined(Q_OS_INTEGRITY)
if (collator.locale() != QLocale::c() && collator.locale() != QLocale::system().collation())
QSKIP("POSIX implementation of collation only supports C and system collation locales");
#endif
if (numericMode)
collator.setNumericMode(true);
int keyCompareResult = result;
[[maybe_unused]]int keyCompareCaseInsensitiveResult = caseInsensitiveResult;
[[maybe_unused]]int keyComparePunctuationResultResult = punctuationResult;
// trying to deal with special behavior of different OS-dependent collators
if (collator.locale() == QLocale("C")) {
#if !QT_CONFIG(icu) && defined(Q_OS_MACOS)
// for MACOS C-locale is not supported, always providing empty string for sortKey()
keyCompareResult = 0;
keyCompareCaseInsensitiveResult = 0;
keyComparePunctuationResultResult = 0;
#else
// for other platforms C-locale strings are not modified by sortKey() anyhow
keyCompareCaseInsensitiveResult = keyCompareResult;
keyComparePunctuationResultResult = keyCompareResult;
#endif
}
// NOTE: currently QCollatorSortKey::compare is not working
// properly without icu: see QTBUG-88704 for details
QCOMPARE(asSign(collator.compare(s1, s2)), result);
if (!numericMode)
QCOMPARE(asSign(QCollator::defaultCompare(s1, s2)), result);
#if QT_CONFIG(icu)
auto key1 = collator.sortKey(s1);
auto key2 = collator.sortKey(s2);
QCOMPARE(asSign(key1.compare(key2)), keyCompareResult);
key1 = QCollator::defaultSortKey(s1);
key2 = QCollator::defaultSortKey(s2);
if (!numericMode)
QCOMPARE(asSign(key1.compare(key2)), keyCompareResult);
#endif
collator.setCaseSensitivity(Qt::CaseInsensitive);
QCOMPARE(asSign(collator.compare(s1, s2)), caseInsensitiveResult);
#if QT_CONFIG(icu)
key1 = collator.sortKey(s1);
key2 = collator.sortKey(s2);
QCOMPARE(asSign(key1.compare(key2)), keyCompareCaseInsensitiveResult);
#endif
collator.setIgnorePunctuation(ignorePunctuation);
QCOMPARE(asSign(collator.compare(s1, s2)), punctuationResult);
#if QT_CONFIG(icu)
key1 = collator.sortKey(s1);
key2 = collator.sortKey(s2);
QCOMPARE(asSign(key1.compare(key2)), keyComparePunctuationResultResult);
#endif
}
void tst_QCollator::state()
{
QCollator c;
c.setCaseSensitivity(Qt::CaseInsensitive);
c.setLocale(QLocale::German);
c.compare(QString("a"), QString("b"));
QCOMPARE(c.caseSensitivity(), Qt::CaseInsensitive);
QCOMPARE(c.locale(), QLocale(QLocale::German));
c.setLocale(QLocale::French);
c.setNumericMode(true);
c.setIgnorePunctuation(true);
c.setLocale(QLocale::NorwegianBokmal);
QCOMPARE(c.caseSensitivity(), Qt::CaseInsensitive);
QCOMPARE(c.numericMode(), true);
QCOMPARE(c.ignorePunctuation(), true);
QCOMPARE(c.locale(), QLocale(QLocale::NorwegianBokmal));
}
QTEST_APPLESS_MAIN(tst_QCollator)
#include "tst_qcollator.moc"

View File

@ -0,0 +1,14 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#####################################################################
## tst_qlatin1sgtringmatcher Test:
#####################################################################
qt_internal_add_test(tst_qlatin1stringmatcher
SOURCES
tst_qlatin1stringmatcher.cpp
)
## Scopes:
#####################################################################

View File

@ -0,0 +1,306 @@
// Copyright (C) 2022 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include <QTest>
#include <QtCore/QLatin1StringMatcher>
#include <numeric>
#include <string>
#if QT_CONFIG(cxx11_future)
# include <thread>
#endif
// COM interface
#if defined(interface)
# undef interface
#endif
using namespace Qt::Literals::StringLiterals;
class tst_QLatin1StringMatcher : public QObject
{
Q_OBJECT
private slots:
void overloads();
void interface();
void indexIn();
void haystacksWithMoreThan4GiBWork();
};
void tst_QLatin1StringMatcher::overloads()
{
QLatin1StringView hello = "hello"_L1;
QByteArray hello2B = QByteArrayView(hello).toByteArray().repeated(2);
QLatin1StringView hello2(hello2B);
{
QLatin1StringMatcher m("hello"_L1, Qt::CaseSensitive);
QCOMPARE(m.pattern(), "hello"_L1);
QCOMPARE(m.indexIn("hello"_L1), 0);
QCOMPARE(m.indexIn("Hello"_L1), -1);
QCOMPARE(m.indexIn("Hellohello"_L1), 5);
QCOMPARE(m.indexIn("helloHello"_L1), 0);
QCOMPARE(m.indexIn("helloHello"_L1, 1), -1);
}
{
QLatin1StringMatcher m("Hello"_L1, Qt::CaseSensitive);
QCOMPARE(m.pattern(), "Hello"_L1);
QCOMPARE(m.indexIn("hello"_L1), -1);
QCOMPARE(m.indexIn("Hello"_L1), 0);
QCOMPARE(m.indexIn("Hellohello"_L1), 0);
QCOMPARE(m.indexIn("helloHello"_L1), 5);
QCOMPARE(m.indexIn("helloHello"_L1, 6), -1);
}
{
QLatin1StringMatcher m("hello"_L1, Qt::CaseInsensitive);
QCOMPARE(m.pattern(), "hello"_L1);
QCOMPARE(m.indexIn("hello"_L1), 0);
QCOMPARE(m.indexIn("Hello"_L1), 0);
QCOMPARE(m.indexIn("Hellohello"_L1), 0);
QCOMPARE(m.indexIn("helloHello"_L1), 0);
QCOMPARE(m.indexIn("helloHello"_L1, 1), 5);
QCOMPARE(m.indexIn("helloHello"_L1, 6), -1);
}
{
QLatin1StringMatcher m("Hello"_L1, Qt::CaseInsensitive);
QCOMPARE(m.pattern(), "Hello"_L1);
QCOMPARE(m.indexIn("hello"_L1), 0);
QCOMPARE(m.indexIn("Hello"_L1), 0);
QCOMPARE(m.indexIn("Hellohello"_L1), 0);
QCOMPARE(m.indexIn("helloHello"_L1), 0);
QCOMPARE(m.indexIn("helloHello"_L1, 1), 5);
QCOMPARE(m.indexIn("helloHello"_L1, 6), -1);
}
{
QLatin1StringMatcher m(hello, Qt::CaseSensitive);
QCOMPARE(m.pattern(), "hello"_L1);
QCOMPARE(m.indexIn(hello), 0);
QCOMPARE(m.indexIn(hello, 1), -1);
QCOMPARE(m.indexIn(hello2, 1), hello.size());
QCOMPARE(m.indexIn(hello2, 6), -1);
}
}
void tst_QLatin1StringMatcher::interface()
{
QLatin1StringView needle = "abc123"_L1;
QByteArray haystackT(500, 'a');
haystackT.insert(6, "123");
haystackT.insert(31, "abc");
haystackT.insert(42, "abc123");
haystackT.insert(84, "abc123");
QLatin1StringView haystack(haystackT);
QLatin1StringMatcher matcher1;
matcher1 = QLatin1StringMatcher(needle, Qt::CaseSensitive);
QLatin1StringMatcher matcher2;
matcher2.setPattern(needle);
QLatin1StringMatcher matcher3 = QLatin1StringMatcher(needle, Qt::CaseSensitive);
QLatin1StringMatcher matcher4;
matcher4 = matcher3;
QCOMPARE(matcher1.indexIn(haystack), 42);
QCOMPARE(matcher2.indexIn(haystack), 42);
QCOMPARE(matcher3.indexIn(haystack), 42);
QCOMPARE(matcher4.indexIn(haystack), 42);
QCOMPARE(matcher1.indexIn(haystack, 43), 84);
QCOMPARE(matcher1.indexIn(haystack, 85), -1);
QLatin1StringMatcher matcher5("123"_L1, Qt::CaseSensitive);
QCOMPARE(matcher5.indexIn(haystack), 6);
matcher5 = QLatin1StringMatcher("abc"_L1, Qt::CaseSensitive);
QCOMPARE(matcher5.indexIn(haystack), 31);
matcher5.setPattern(matcher4.pattern());
QCOMPARE(matcher5.indexIn(haystack), 42);
QLatin1StringMatcher matcher6 = matcher5;
QCOMPARE(matcher6.indexIn(haystack), 42);
QLatin1StringMatcher matcher7 = std::move(matcher5);
QCOMPARE(matcher7.indexIn(haystack), 42);
matcher1.setPattern("123"_L1);
matcher7 = std::move(matcher1);
QCOMPARE(matcher7.indexIn(haystack), 6);
}
#define LONG_STRING__32 "abcdefghijklmnopqrstuvwxyz012345"
#define LONG_STRING__64 LONG_STRING__32 LONG_STRING__32
#define LONG_STRING_128 LONG_STRING__64 LONG_STRING__64
#define LONG_STRING_256 LONG_STRING_128 LONG_STRING_128
#define LONG_STRING_512 LONG_STRING_256 LONG_STRING_256
void tst_QLatin1StringMatcher::indexIn()
{
const char p_data[] = { 0x0, 0x0, 0x1 };
QLatin1StringView pattern(p_data, sizeof(p_data));
QByteArray haystackT(8, '\0');
haystackT[7] = 0x1;
QLatin1StringView haystack(haystackT);
QLatin1StringMatcher matcher;
matcher = QLatin1StringMatcher(pattern, Qt::CaseSensitive);
QCOMPARE(matcher.indexIn(haystack, 0), 5);
QCOMPARE(matcher.indexIn(haystack, 1), 5);
QCOMPARE(matcher.indexIn(haystack, 2), 5);
matcher.setPattern(pattern);
QCOMPARE(matcher.indexIn(haystack, 0), 5);
QCOMPARE(matcher.indexIn(haystack, 1), 5);
QCOMPARE(matcher.indexIn(haystack, 2), 5);
std::array<char, 256> allChars;
for (int i = 0; i < 256; ++i)
allChars[i] = char(i);
matcher = QLatin1StringMatcher(QLatin1StringView(allChars), Qt::CaseSensitive);
haystackT = LONG_STRING__32 "x";
haystackT += matcher.pattern();
haystack = QLatin1StringView(haystackT);
QCOMPARE(matcher.indexIn(haystack, 0), 33);
QCOMPARE(matcher.indexIn(haystack, 1), 33);
QCOMPARE(matcher.indexIn(haystack, 2), 33);
QCOMPARE(matcher.indexIn(haystack, 33), 33);
QCOMPARE(matcher.indexIn(haystack, 34), -1);
matcher = QLatin1StringMatcher(QLatin1StringView(LONG_STRING_256), Qt::CaseSensitive);
haystackT = QByteArray(LONG_STRING__32 "x");
haystackT += matcher.pattern();
haystackT += QByteArrayView("Just junk at the end");
haystack = QLatin1StringView(haystackT);
QCOMPARE(matcher.indexIn(haystack, 0), 33);
QCOMPARE(matcher.indexIn(haystack, 1), 33);
QCOMPARE(matcher.indexIn(haystack, 2), 33);
QCOMPARE(matcher.indexIn(haystack, 33), 33);
QCOMPARE(matcher.indexIn(haystack, 34), -1);
matcher.setCaseSensitivity(Qt::CaseInsensitive);
QCOMPARE(matcher.indexIn(haystack, 0), 33);
QCOMPARE(matcher.indexIn(haystack, 1), 33);
QCOMPARE(matcher.indexIn(haystack, 2), 33);
QCOMPARE(matcher.indexIn(haystack, 33), 33);
QCOMPARE(matcher.indexIn(haystack, 34), -1);
matcher = QLatin1StringMatcher(QLatin1StringView(LONG_STRING_512), Qt::CaseInsensitive);
haystackT = QByteArray(LONG_STRING__32 "x");
haystackT += matcher.pattern();
haystackT += QByteArrayView("Just junk at the end");
haystack = QLatin1StringView(haystackT);
QCOMPARE(matcher.indexIn(haystack, 0), 33);
QCOMPARE(matcher.indexIn(haystack, 1), 33);
QCOMPARE(matcher.indexIn(haystack, 2), 33);
QCOMPARE(matcher.indexIn(haystack, 33), 33);
QCOMPARE(matcher.indexIn(haystack, 34), -1);
matcher.setCaseSensitivity(Qt::CaseSensitive);
QCOMPARE(matcher.indexIn(haystack, 0), 33);
QCOMPARE(matcher.indexIn(haystack, 1), 33);
QCOMPARE(matcher.indexIn(haystack, 2), 33);
QCOMPARE(matcher.indexIn(haystack, 33), 33);
QCOMPARE(matcher.indexIn(haystack, 34), -1);
matcher = QLatin1StringMatcher(QLatin1StringView(""), Qt::CaseSensitive);
haystackT = QByteArray(LONG_STRING__32 "x");
haystack = QLatin1StringView(haystackT);
QCOMPARE(matcher.indexIn(haystack, 0), 0);
QCOMPARE(matcher.indexIn(haystack, 1), 1);
QCOMPARE(matcher.indexIn(haystack, 2), 2);
QCOMPARE(matcher.indexIn(haystack, 33), 33);
matcher = QLatin1StringMatcher(QLatin1StringView(""), Qt::CaseInsensitive);
haystackT = QByteArray(LONG_STRING__32 "x");
haystack = QLatin1StringView(haystackT);
QCOMPARE(matcher.indexIn(haystack, 0), 0);
QCOMPARE(matcher.indexIn(haystack, 1), 1);
QCOMPARE(matcher.indexIn(haystack, 2), 2);
QCOMPARE(matcher.indexIn(haystack, 33), 33);
matcher = QLatin1StringMatcher(QLatin1StringView("m\xF8"), Qt::CaseInsensitive);
haystackT = QByteArray("M\xF8m\xF8");
haystack = QLatin1StringView(haystackT);
QCOMPARE(matcher.indexIn(haystack, 0), 0);
QCOMPARE(matcher.indexIn(haystack, 1), 2);
QCOMPARE(matcher.indexIn(haystack, 2), 2);
QCOMPARE(matcher.indexIn(haystack, 3), -1);
matcher.setCaseSensitivity(Qt::CaseSensitive);
QCOMPARE(matcher.indexIn(haystack, 0), 2);
QCOMPARE(matcher.indexIn(haystack, 1), 2);
QCOMPARE(matcher.indexIn(haystack, 2), 2);
QCOMPARE(matcher.indexIn(haystack, 3), -1);
}
void tst_QLatin1StringMatcher::haystacksWithMoreThan4GiBWork()
{
#if QT_POINTER_SIZE > 4
// use a large needle to trigger long skips in the Boyer-Moore algorithm
// (to speed up the test)
constexpr std::string_view needle = LONG_STRING_256;
//
// GIVEN: a haystack with more than 4 GiB of data
//
// don't use QByteArray because freeSpaceAtEnd() may break reserve()
// semantics and a realloc is the last thing we need here
std::string large;
QElapsedTimer timer;
timer.start();
constexpr size_t GiB = 1024 * 1024 * 1024;
constexpr size_t BaseSize = 4 * GiB + 1;
try {
large.reserve(BaseSize + needle.size());
large.resize(BaseSize, '\0');
large.append(needle);
} catch (const std::bad_alloc &) {
QSKIP("Could not allocate 4GiB plus a couple hundred bytes of RAM.");
}
QCOMPARE(large.size(), BaseSize + needle.size());
qDebug("created dataset in %lld ms", timer.elapsed());
# if QT_CONFIG(cxx11_future)
using MaybeThread = std::thread;
# else
struct MaybeThread
{
std::function<void()> func;
void join() { func(); }
};
# endif
//
// WHEN: trying to match an occurrence past the 4GiB mark
//
qsizetype dynamicResult;
auto t = MaybeThread{ [&] {
QLatin1StringMatcher m(QLatin1StringView(needle), Qt::CaseSensitive);
dynamicResult = m.indexIn(QLatin1StringView(large));
} };
t.join();
//
// THEN: the result index is not trucated
//
QCOMPARE(dynamicResult, qsizetype(BaseSize));
#else
QSKIP("This test is 64-bit only.");
#endif
}
#undef LONG_STRING_512
#undef LONG_STRING_256
#undef LONG_STRING_128
#undef LONG_STRING__64
#undef LONG_STRING__32
QTEST_APPLESS_MAIN(tst_QLatin1StringMatcher)
#include "tst_qlatin1stringmatcher.moc"

View File

@ -0,0 +1,16 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qlatin1stringview Test:
#####################################################################
qt_internal_add_test(tst_qlatin1stringview
SOURCES
tst_qlatin1stringview.cpp
DEFINES
QT_NO_CAST_TO_ASCII
)
## Scopes:
#####################################################################

View File

@ -0,0 +1,519 @@
// Copyright (C) 2015 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Marc Mutz <marc.mutz@kdab.com>
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include <QTest>
#include <QString>
// Preserve QLatin1StringView-ness (QVariant(QLatin1StringView) creates a QVariant::String):
struct QLatin1StringViewContainer {
QLatin1StringView l1;
};
QT_BEGIN_NAMESPACE
Q_DECLARE_TYPEINFO(QLatin1StringViewContainer, Q_RELOCATABLE_TYPE);
QT_END_NAMESPACE
Q_DECLARE_METATYPE(QLatin1StringViewContainer)
class tst_QLatin1StringView : public QObject
{
Q_OBJECT
private Q_SLOTS:
void constExpr();
void construction();
void userDefinedLiterals();
void at();
void arg() const;
void midLeftRight();
void nullString();
void emptyString();
void iterators();
void relationalOperators_data();
void relationalOperators();
void count();
void indexOf_data();
void indexOf();
};
void tst_QLatin1StringView::constExpr()
{
// compile-time checks
{
constexpr QLatin1StringView l1s;
static_assert(l1s.size() == 0);
static_assert(l1s.isNull());
static_assert(l1s.empty());
static_assert(l1s.isEmpty());
static_assert(l1s.latin1() == nullptr);
constexpr QLatin1StringView l1s2(l1s.latin1(), l1s.latin1() + l1s.size());
static_assert(l1s2.isNull());
static_assert(l1s2.empty());
}
{
constexpr QLatin1StringView l1s = nullptr;
static_assert(l1s.size() == 0);
static_assert(l1s.isNull());
static_assert(l1s.empty());
static_assert(l1s.isEmpty());
static_assert(l1s.latin1() == nullptr);
}
{
constexpr QLatin1StringView l1s("");
static_assert(l1s.size() == 0);
static_assert(!l1s.isNull());
static_assert(l1s.empty());
static_assert(l1s.isEmpty());
static_assert(l1s.latin1() != nullptr);
constexpr QLatin1StringView l1s2(l1s.latin1(), l1s.latin1() + l1s.size());
static_assert(!l1s2.isNull());
static_assert(l1s2.empty());
}
{
static_assert(QLatin1StringView("Hello").size() == 5);
constexpr QLatin1StringView l1s("Hello");
static_assert(l1s.size() == 5);
static_assert(!l1s.empty());
static_assert(!l1s.isEmpty());
static_assert(!l1s.isNull());
static_assert(*l1s.latin1() == 'H');
static_assert(l1s[0] == QLatin1Char('H'));
static_assert(l1s.at(0) == QLatin1Char('H'));
static_assert(l1s.front() == QLatin1Char('H'));
static_assert(l1s.first() == QLatin1Char('H'));
static_assert(l1s[4] == QLatin1Char('o'));
static_assert(l1s.at(4) == QLatin1Char('o'));
static_assert(l1s.back() == QLatin1Char('o'));
static_assert(l1s.last() == QLatin1Char('o'));
constexpr QLatin1StringView l1s2(l1s.latin1(), l1s.latin1() + l1s.size());
static_assert(!l1s2.isNull());
static_assert(!l1s2.empty());
static_assert(l1s2.size() == 5);
}
}
void tst_QLatin1StringView::construction()
{
{
const char str[6] = "hello";
QLatin1StringView l1s(str);
QCOMPARE(l1s.size(), 5);
QCOMPARE(l1s.latin1(), reinterpret_cast<const void *>(&str[0]));
QCOMPARE(l1s.latin1(), "hello");
QLatin1StringView s1 = {str, 5};
QCOMPARE(s1, l1s);
QLatin1StringView s2 = {str, str + 5};
QCOMPARE(s2, l1s);
QByteArrayView helloView(str);
helloView = helloView.first(4);
l1s = QLatin1StringView(helloView);
QCOMPARE(l1s.latin1(), helloView.data());
QCOMPARE(l1s.latin1(), reinterpret_cast<const void *>(helloView.data()));
QCOMPARE(l1s.size(), helloView.size());
}
{
const QByteArray helloArray("hello");
QLatin1StringView l1s(helloArray);
QCOMPARE(l1s.latin1(), helloArray.data());
QCOMPARE(l1s.size(), helloArray.size());
QByteArrayView helloView(helloArray);
helloView = helloView.first(4);
l1s = QLatin1StringView(helloView);
QCOMPARE(l1s.latin1(), helloView.data());
QCOMPARE(l1s.size(), helloView.size());
}
}
void tst_QLatin1StringView::userDefinedLiterals()
{
{
using namespace Qt::Literals::StringLiterals;
auto str = "abcd"_L1;
static_assert(std::is_same_v<decltype(str), QLatin1StringView>);
QCOMPARE(str.size(), 4);
QCOMPARE(str, QLatin1StringView("abcd"));
QCOMPARE(str.latin1(), "abcd");
QCOMPARE("abcd"_L1, str.latin1());
QCOMPARE("M\xE5rten"_L1, QLatin1StringView("M\xE5rten"));
auto ch = 'a'_L1;
static_assert(std::is_same_v<decltype(ch), QLatin1Char>);
QCOMPARE(ch, QLatin1Char('a'));
QCOMPARE(ch.toLatin1(), 'a');
QCOMPARE('a'_L1, ch.toLatin1());
QCOMPARE('\xE5'_L1, QLatin1Char('\xE5'));
}
{
using namespace Qt::Literals;
auto str = "abcd"_L1;
static_assert(std::is_same_v<decltype(str), QLatin1StringView>);
QCOMPARE(str, QLatin1StringView("abcd"));
auto ch = 'a'_L1;
static_assert(std::is_same_v<decltype(ch), QLatin1Char>);
QCOMPARE(ch, QLatin1Char('a'));
}
{
using namespace Qt;
auto str = "abcd"_L1;
static_assert(std::is_same_v<decltype(str), QLatin1StringView>);
QCOMPARE(str, QLatin1StringView("abcd"));
auto ch = 'a'_L1;
static_assert(std::is_same_v<decltype(ch), QLatin1Char>);
QCOMPARE(ch, QLatin1Char('a'));
}
}
void tst_QLatin1StringView::at()
{
const QLatin1StringView l1("Hello World");
QCOMPARE(l1.at(0), QLatin1Char('H'));
QCOMPARE(l1.at(l1.size() - 1), QLatin1Char('d'));
QCOMPARE(l1[0], QLatin1Char('H'));
QCOMPARE(l1[l1.size() - 1], QLatin1Char('d'));
}
void tst_QLatin1StringView::arg() const
{
#define CHECK1(pattern, arg1, expected) \
do { \
auto p = QLatin1StringView(pattern); \
QCOMPARE(p.arg(QLatin1StringView(arg1)), expected); \
QCOMPARE(p.arg(u"" arg1), expected); \
QCOMPARE(p.arg(QStringLiteral(arg1)), expected); \
QCOMPARE(p.arg(QString(QLatin1StringView(arg1))), expected); \
} while (false) \
/*end*/
#define CHECK2(pattern, arg1, arg2, expected) \
do { \
auto p = QLatin1StringView(pattern); \
QCOMPARE(p.arg(QLatin1StringView(arg1), QLatin1StringView(arg2)), expected); \
QCOMPARE(p.arg(u"" arg1, QLatin1StringView(arg2)), expected); \
QCOMPARE(p.arg(QLatin1StringView(arg1), u"" arg2), expected); \
QCOMPARE(p.arg(u"" arg1, u"" arg2), expected); \
} while (false) \
/*end*/
CHECK1("", "World", "");
CHECK1("%1", "World", "World");
CHECK1("!%1?", "World", "!World?");
CHECK1("%1%1", "World", "WorldWorld");
CHECK1("%1%2", "World", "World%2");
CHECK1("%2%1", "World", "%2World");
CHECK2("", "Hello", "World", "");
CHECK2("%1", "Hello", "World", "Hello");
CHECK2("!%1, %2?", "Hello", "World", "!Hello, World?");
CHECK2("%1%1", "Hello", "World", "HelloHello");
CHECK2("%1%2", "Hello", "World", "HelloWorld");
CHECK2("%2%1", "Hello", "World", "WorldHello");
#undef CHECK2
#undef CHECK1
QCOMPARE(QLatin1StringView(" %2 %2 %1 %3 ").arg(QLatin1Char('c'), QChar::CarriageReturn, u'C'),
" \r \r c C ");
}
void tst_QLatin1StringView::midLeftRight()
{
const QLatin1StringView l1("Hello World");
QCOMPARE(l1.mid(0), l1);
QCOMPARE(l1.mid(0, l1.size()), l1);
QCOMPARE(l1.left(l1.size()), l1);
QCOMPARE(l1.right(l1.size()), l1);
QCOMPARE(l1.mid(6), QLatin1StringView("World"));
QCOMPARE(l1.mid(6, 5), QLatin1StringView("World"));
QCOMPARE(l1.right(5), QLatin1StringView("World"));
QCOMPARE(l1.mid(6, 1), QLatin1StringView("W"));
QCOMPARE(l1.right(5).left(1), QLatin1StringView("W"));
QCOMPARE(l1.left(5), QLatin1StringView("Hello"));
}
void tst_QLatin1StringView::nullString()
{
// default ctor
{
QLatin1StringView l1;
QCOMPARE(static_cast<const void*>(l1.data()), static_cast<const void*>(nullptr));
QCOMPARE(l1.size(), 0);
QString s = l1;
QVERIFY(s.isNull());
}
// from nullptr
{
const char *null = nullptr;
QLatin1StringView l1(null);
QCOMPARE(static_cast<const void*>(l1.data()), static_cast<const void*>(nullptr));
QCOMPARE(l1.size(), 0);
QString s = l1;
QVERIFY(s.isNull());
}
// from null QByteArray
{
const QByteArray null;
QVERIFY(null.isNull());
QLatin1StringView l1(null);
QEXPECT_FAIL("", "null QByteArrays become non-null QLatin1Strings...", Continue);
QCOMPARE(static_cast<const void*>(l1.data()), static_cast<const void*>(nullptr));
QCOMPARE(l1.size(), 0);
QString s = l1;
QEXPECT_FAIL("", "null QByteArrays become non-null QLatin1Strings become non-null QStrings...", Continue);
QVERIFY(s.isNull());
}
}
void tst_QLatin1StringView::emptyString()
{
{
const char *empty = "";
QLatin1StringView l1(empty);
QCOMPARE(static_cast<const void*>(l1.data()), static_cast<const void*>(empty));
QCOMPARE(l1.size(), 0);
QString s = l1;
QVERIFY(s.isEmpty());
QVERIFY(!s.isNull());
}
{
const char *notEmpty = "foo";
QLatin1StringView l1(notEmpty, qsizetype(0));
QCOMPARE(static_cast<const void*>(l1.data()), static_cast<const void*>(notEmpty));
QCOMPARE(l1.size(), 0);
QString s = l1;
QVERIFY(s.isEmpty());
QVERIFY(!s.isNull());
}
{
const QByteArray empty = "";
QLatin1StringView l1(empty);
QCOMPARE(static_cast<const void*>(l1.data()), static_cast<const void*>(empty.constData()));
QCOMPARE(l1.size(), 0);
QString s = l1;
QVERIFY(s.isEmpty());
QVERIFY(!s.isNull());
}
}
void tst_QLatin1StringView::iterators()
{
QLatin1StringView hello("hello");
QLatin1StringView olleh("olleh");
QVERIFY(std::equal(hello.begin(), hello.end(),
olleh.rbegin()));
QVERIFY(std::equal(hello.rbegin(), hello.rend(),
QT_MAKE_CHECKED_ARRAY_ITERATOR(olleh.begin(), olleh.size())));
QVERIFY(std::equal(hello.cbegin(), hello.cend(),
olleh.rbegin()));
QVERIFY(std::equal(hello.crbegin(), hello.crend(),
QT_MAKE_CHECKED_ARRAY_ITERATOR(olleh.begin(), olleh.size())));
}
void tst_QLatin1StringView::relationalOperators_data()
{
QTest::addColumn<QLatin1StringViewContainer>("lhs");
QTest::addColumn<int>("lhsOrderNumber");
QTest::addColumn<QLatin1StringViewContainer>("rhs");
QTest::addColumn<int>("rhsOrderNumber");
struct Data {
QLatin1StringView l1;
int order;
} data[] = {
{ QLatin1StringView(), 0 },
{ QLatin1StringView(""), 0 },
{ QLatin1StringView("a"), 1 },
{ QLatin1StringView("aa"), 2 },
{ QLatin1StringView("b"), 3 },
};
for (Data *lhs = data; lhs != data + sizeof data / sizeof *data; ++lhs) {
for (Data *rhs = data; rhs != data + sizeof data / sizeof *data; ++rhs) {
QLatin1StringViewContainer l = { lhs->l1 }, r = { rhs->l1 };
QTest::addRow("\"%s\" <> \"%s\"",
lhs->l1.data() ? lhs->l1.data() : "nullptr",
rhs->l1.data() ? rhs->l1.data() : "nullptr")
<< l << lhs->order << r << rhs->order;
}
}
}
void tst_QLatin1StringView::relationalOperators()
{
QFETCH(QLatin1StringViewContainer, lhs);
QFETCH(int, lhsOrderNumber);
QFETCH(QLatin1StringViewContainer, rhs);
QFETCH(int, rhsOrderNumber);
#define CHECK(op) \
QCOMPARE(lhs.l1 op rhs.l1, lhsOrderNumber op rhsOrderNumber) \
/*end*/
CHECK(==);
CHECK(!=);
CHECK(< );
CHECK(> );
CHECK(<=);
CHECK(>=);
#undef CHECK
}
void tst_QLatin1StringView::count()
{
QLatin1StringView a("ABCDEFGHIEfGEFG");
QCOMPARE(a.size(), 15);
QCOMPARE(a.count('A'), 1);
QCOMPARE(a.count('Z'), 0);
QCOMPARE(a.count('E'), 3);
QCOMPARE(a.count('F'), 2);
QCOMPARE(a.count('F', Qt::CaseInsensitive), 3);
QCOMPARE(a.count(QLatin1StringView("FG")), 2);
QCOMPARE(a.count(QLatin1StringView("FG"), Qt::CaseInsensitive), 3);
QCOMPARE(a.count(QLatin1StringView(), Qt::CaseInsensitive), 16);
QCOMPARE(a.count(QLatin1StringView(""), Qt::CaseInsensitive), 16);
QLatin1StringView nullStr;
QCOMPARE(nullStr.count('A'), 0);
QCOMPARE(nullStr.count(QLatin1StringView("AB")), 0);
QCOMPARE(nullStr.count(QLatin1StringView()), 1);
QCOMPARE(nullStr.count(QLatin1StringView("")), 1);
QLatin1StringView emptyStr("");
QCOMPARE(emptyStr.count('A'), 0);
QCOMPARE(emptyStr.count(QLatin1StringView("AB")), 0);
QCOMPARE(emptyStr.count(QLatin1StringView()), 1);
QCOMPARE(emptyStr.count(QLatin1StringView("")), 1);
using namespace Qt::Literals::StringLiterals;
QCOMPARE("a\0b"_L1.count(QChar::SpecialCharacter::LineSeparator), 0);
}
void tst_QLatin1StringView::indexOf_data()
{
using namespace Qt::Literals::StringLiterals;
QTest::addColumn<QLatin1StringView>("needle");
QTest::addColumn<QLatin1StringView>("haystack");
QTest::addColumn<int>("from");
QTest::addColumn<int>("indexCaseSensitive");
QTest::addColumn<int>("indexCaseInsensitive");
// Should never trigger Boyer Moore algorithm
QTest::newRow("Single letter match start")
<< QLatin1StringView("A") << QLatin1StringView("ABCDEF") << 0 << 0 << 0;
QTest::newRow("Single letter match second letter")
<< QLatin1StringView("B") << QLatin1StringView("ABCDEF") << 0 << 1 << 1;
QTest::newRow("Single letter mismatch")
<< QLatin1StringView("G") << QLatin1StringView("ABCDEF") << 0 << -1 << -1;
QTest::newRow("Single letter case sensitive start")
<< QLatin1StringView("a") << QLatin1StringView("ABCDEF") << 0 << -1 << 0;
QTest::newRow("Single letter case sensitive end")
<< QLatin1StringView("f") << QLatin1StringView("ABCDEF") << 0 << -1 << 5;
QTest::newRow("Single letter different match depending on case")
<< QLatin1StringView("a") << QLatin1StringView("ABCabc") << 0 << 3 << 0;
QTest::newRow("Single letter different match depending on case from 2")
<< QLatin1StringView("a") << QLatin1StringView("ABCABCabc") << 2 << 6 << 3;
QTest::newRow("Single letter negative from")
<< QLatin1StringView("a") << QLatin1StringView("abcabc") << -3 << 3 << 3;
QTest::newRow("Single letter non-ASCII") // searching for "ø" in "Øø"
<< "\xf8"_L1
<< "\xd8\xf8"_L1 << 0 << 1 << 0;
QTest::newRow("Single uppercase letter")
<< QLatin1StringView("A") << QLatin1StringView("aA") << 0 << 1 << 0;
// Might trigger Boyer Moore algorithm
QTest::newRow("Small match start")
<< QLatin1StringView("ABC") << QLatin1StringView("ABCDEF") << 0 << 0 << 0;
QTest::newRow("Small match second letter")
<< QLatin1StringView("BCD") << QLatin1StringView("ABCDEF") << 0 << 1 << 1;
QTest::newRow("Small mismatch")
<< QLatin1StringView("EFG") << QLatin1StringView("ABCDEF") << 0 << -1 << -1;
QTest::newRow("Small case sensitive start")
<< QLatin1StringView("abc") << QLatin1StringView("ABCDEF") << 0 << -1 << 0;
QTest::newRow("Small case sensitive end")
<< QLatin1StringView("DEF") << QLatin1StringView("abcdef") << 0 << -1 << 3;
QTest::newRow("Small different match depending on case")
<< QLatin1StringView("abcabc") << QLatin1StringView("!!ABCabcabcABC") << 0 << 5 << 2;
QTest::newRow("Small different match depending on case from 2")
<< QLatin1StringView("abcabc") << QLatin1StringView("ABCABCabcabcABC") << 2 << 6 << 3;
QTest::newRow("Small negative from") << QLatin1StringView("negative")
<< QLatin1StringView("negativenegative") << -8 << 8 << 8;
QTest::newRow("Small non-ASCII") // searching for "løve" in "LØVEløve"
<< "l\xf8ve"_L1
<< "L\xd8VEl\xf8ve"_L1 << 0 << 4 << 0;
QTest::newRow("Small skip test")
<< QLatin1StringView("ABBB") << QLatin1StringView("ABABBB") << 0 << 2 << 2;
QTest::newRow("Small uppercase needle")
<< QLatin1StringView("ABCDEF") << QLatin1StringView("abcdefABCDEF") << 0 << 6 << 0;
// Should trigger Boyer Moore algorithm
QTest::newRow("Medium match start")
<< QLatin1StringView("ABCDEFGHIJKLMNOP")
<< QLatin1StringView("ABCDEFGHIJKLMNOPQRSTUVWXYZ") << 0 << 0 << 0;
QTest::newRow("Medium match second letter")
<< QLatin1StringView("BCDEFGHIJKLMNOPQ")
<< QLatin1StringView("ABCDEFGHIJKLMNOPQRSTUVWXYZ") << 0 << 1 << 1;
QTest::newRow("Medium mismatch")
<< QLatin1StringView("PONMLKJIHGFEDCBA")
<< QLatin1StringView("ABCDEFGHIJKLMNOPQRSTUVWXYZ") << 0 << -1 << -1;
QTest::newRow("Medium case sensitive start")
<< QLatin1StringView("abcdefghijklmnopq")
<< QLatin1StringView("ABCDEFGHIJKLMNOPQRSTUVWXYZ") << 0 << -1 << 0;
QTest::newRow("Medium case sensitive second letter")
<< QLatin1StringView("BCDEFGHIJKLMNOPQR")
<< QLatin1StringView("abcdefghijklmnopqrstuvxyz") << 0 << -1 << 1;
QTest::newRow("Medium different match depending on case")
<< QLatin1StringView("testingtesting")
<< QLatin1StringView("TESTINGtestingtestingTESTING") << 0 << 7 << 0;
QTest::newRow("Medium different match depending on case from 2")
<< QLatin1StringView("testingtesting")
<< QLatin1StringView("TESTINGTESTINGtestingtestingTESTING") << 2 << 14 << 7;
QTest::newRow("Medium negative from")
<< QLatin1StringView("abcdefghijklmnop")
<< QLatin1StringView("abcdefghijklmnopabcdefghijklmnop") << -16 << 16 << 16;
QTest::newRow("Medium non-ASCII") // searching for "dampfschiffahrtsgesellschaftskapitän"
<< "dampfschiffahrtsgesellschaftskapit\xe4n"_L1
<< "DAMPFSCHIFFAHRTSGESELLSCHAFTSKAPIT\xc4Ndampfschiffahrtsgesellschaftskapit\xe4n"_L1
<< 0 << 36 << 0;
QTest::newRow("Medium skip test") << QLatin1StringView("ABBBBBBBBBBBBBBB")
<< QLatin1StringView("ABABBBBBBBBBBBBBBB") << 0 << 2 << 2;
}
void tst_QLatin1StringView::indexOf()
{
QFETCH(QLatin1StringView, needle);
QFETCH(QLatin1StringView, haystack);
QFETCH(int, from);
QFETCH(int, indexCaseSensitive);
QFETCH(int, indexCaseInsensitive);
QCOMPARE(haystack.indexOf(needle, from, Qt::CaseSensitive), (qsizetype)indexCaseSensitive);
QCOMPARE(haystack.indexOf(needle, from, Qt::CaseInsensitive), (qsizetype)indexCaseInsensitive);
}
QTEST_APPLESS_MAIN(tst_QLatin1StringView)
#include "tst_qlatin1stringview.moc"

View File

@ -0,0 +1,5 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
add_subdirectory(test)
add_subdirectory(syslocaleapp)

View File

@ -0,0 +1,12 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## syslocaleapp Binary:
#####################################################################
qt_internal_add_executable(syslocaleapp
OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/"
SOURCES
syslocaleapp.cpp
)

View File

@ -0,0 +1,15 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include <QLocale>
#include <QCoreApplication>
#include <QTextStream>
int main(int argc, char** argv)
{
QCoreApplication app(argc, argv);
QLocale l;
QTextStream str(stdout);
str << l.name();
return 0;
}

View File

@ -0,0 +1,32 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qlocale Test:
#####################################################################
qt_internal_add_test(tst_qlocale
OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/../"
SOURCES
../tst_qlocale.cpp
LIBRARIES
Qt::CorePrivate
)
## Scopes:
#####################################################################
qt_internal_extend_target(tst_qlocale CONDITION embedded
LIBRARIES
Qt::Gui
)
qt_internal_extend_target(tst_qlocale CONDITION NOT QT_FEATURE_doubleconversion AND NOT QT_FEATURE_system_doubleconversion
DEFINES
QT_NO_DOUBLECONVERSION
)
## Depends on ../syslocaleapp
if(QT_FEATURE_process)
add_dependencies(tst_qlocale syslocaleapp)
endif()

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,11 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qregularexpression Test:
#####################################################################
qt_internal_add_test(tst_qregularexpression
SOURCES
tst_qregularexpression.cpp
)

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,30 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
if(NOT QT_FEATURE_doubleconversion AND NOT QT_FEATURE_system_doubleconversion)
list(APPEND tst_qstring_extra_defines QT_NO_DOUBLECONVERSION)
endif()
if(APPLE)
list(APPEND tst_qstring_extra_libraries ${FWFoundation})
list(APPEND tst_qstring_extra_sources tst_qstring_mac.mm)
endif()
foreach(test tst_qstring tst_qstring_restricted_ascii)
qt_internal_add_test(${test}
SOURCES
tst_qstring.cpp
${tst_qstring_extra_sources}
LIBRARIES
Qt::CorePrivate
${tst_qstring_extra_libraries}
DEFINES
${tst_qstring_extra_defines}
)
endforeach()
qt_internal_extend_target(tst_qstring_restricted_ascii
DEFINES
QT_RESTRICTED_CAST_FROM_ASCII
tst_QString=tst_QString_restricted_ascii
)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,45 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include <QtCore/QString>
#include <QTest>
#include <QtCore/private/qcore_mac_p.h>
#include <CoreFoundation/CoreFoundation.h>
#include <Foundation/Foundation.h>
void tst_QString_macTypes()
{
// QString <-> CFString
{
QString qtString("test string");
const CFStringRef cfString = qtString.toCFString();
QCOMPARE(QString::fromCFString(cfString), qtString);
CFRelease(cfString);
}
{
QString qtString("test string");
const CFStringRef cfString = qtString.toCFString();
QString qtStringCopy(qtString);
qtString = qtString.toUpper(); // modify
QCOMPARE(QString::fromCFString(cfString), qtStringCopy);
}
// QString <-> NSString
{
QMacAutoReleasePool pool;
QString qtString("test string");
const NSString *nsString = qtString.toNSString();
QCOMPARE(QString::fromNSString(nsString), qtString);
}
{
QMacAutoReleasePool pool;
QString qtString("test string");
const NSString *nsString = qtString.toNSString();
QString qtStringCopy(qtString);
qtString = qtString.toUpper(); // modify
QCOMPARE(QString::fromNSString(nsString), qtStringCopy);
}
}

View File

@ -0,0 +1,13 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qstring_no_cast_from_bytearray Test:
#####################################################################
qt_internal_add_test(tst_qstring_no_cast_from_bytearray
SOURCES
tst_qstring_no_cast_from_bytearray.cpp
DEFINES
QT_NO_CAST_FROM_BYTEARRAY
)

View File

@ -0,0 +1,21 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include <QTest>
#include <QtCore/QtCore>
class tst_QString_NoCastFromByteArray: public QObject
{
Q_OBJECT
private Q_SLOTS:
void initTestCase();
};
void tst_QString_NoCastFromByteArray::initTestCase()
{
qWarning("This is a compile test only");
}
QTEST_APPLESS_MAIN(tst_QString_NoCastFromByteArray)
#include "tst_qstring_no_cast_from_bytearray.moc"

View File

@ -0,0 +1,16 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qstringapisymmetry Test:
#####################################################################
qt_internal_add_test(tst_qstringapisymmetry
SOURCES
tst_qstringapisymmetry.cpp
LIBRARIES
Qt::CorePrivate
)
## Scopes:
#####################################################################

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,7 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
add_subdirectory(qstringbuilder1)
add_subdirectory(qstringbuilder2)
add_subdirectory(qstringbuilder3)
add_subdirectory(qstringbuilder4)

View File

@ -0,0 +1,11 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qstringbuilder1 Test:
#####################################################################
qt_internal_add_test(tst_qstringbuilder1
SOURCES
tst_qstringbuilder1.cpp
)

View File

@ -0,0 +1,363 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
// Do not include anything in this file. We are being #included with
// a bunch of defines that may break other legitimate code.
#define LITERAL "some literal"
#define LITERAL_LEN (sizeof(LITERAL)-1)
#define LITERAL_EXTRA "some literal" "EXTRA"
// "some literal", but replacing all vowels by their umlauted UTF-8 string :)
#define UTF8_LITERAL "s\xc3\xb6m\xc3\xab l\xc3\xaft\xc3\xabr\xc3\xa4l"
#define UTF8_LITERAL_LEN (sizeof(UTF8_LITERAL)-1)
#define UTF8_LITERAL_EXTRA "s\xc3\xb6m\xc3\xab l\xc3\xaft\xc3\xabr\xc3\xa4l" "EXTRA"
// "some literal", but replacing all vocals by their umlauted UTF-8 string :)
#define UNICODE_LITERAL u"s\u00f6m\u00eb l\u00eft\u00ebr\u00e4l"
#define UNICODE_LITERAL_LEN ((sizeof(UNICODE_LITERAL) - 1) / 2)
#define UNICODE_LITERAL_EXTRA u"s\u00f6m\u00eb l\u00eft\u00ebr\u00e4l" "EXTRA"
#ifndef P
# error You need to define P
#endif
//fix for gcc4.0: if the operator+ does not exist without QT_USE_FAST_OPERATOR_PLUS
#ifndef QT_USE_FAST_CONCATENATION
#define Q %
#else
#define Q P
#endif
template <typename T> QString toQString(const T &t);
template <> QString toQString(const QString &s) { return s; }
template <> QString toQString(const QStringView &v) { return v.toString(); }
template <> QString toQString(const QLatin1String &l) { return l; }
template <> QString toQString(const QLatin1Char &l) { return QChar(l); }
template <> QString toQString(const QChar &c) { return c; }
template <> QString toQString(const QChar::SpecialCharacter &c) { return QChar(c); }
template <> QString toQString(char16_t * const &p) { return QStringView(p).toString(); }
template <size_t N> QString toQString(const char16_t (&a)[N]) { return QStringView(a).toString(); }
template <> QString toQString(const char16_t &c) { return QChar(c); }
template <typename T> QByteArray toQByteArray(const T &t);
template <> QByteArray toQByteArray(const QByteArray &b) { return b; }
template <> QByteArray toQByteArray(char * const &p) { return p; }
template <size_t N> QByteArray toQByteArray(const char (&a)[N]) { return a; }
template <> QByteArray toQByteArray(const char &c) { return QByteArray(&c, 1); }
template <typename String, typename Separator>
void checkItWorksWithFreeSpaceAtBegin(const String &chunk, const Separator &separator)
{
// GIVEN: a String with freeSpaceAtBegin() and less than chunk.size() freeSpaceAtEnd()
String str;
int prepends = 0;
const int max_prepends = 10;
while (str.data_ptr().freeSpaceAtBegin() < chunk.size() && prepends++ < max_prepends)
str.prepend(chunk);
QVERIFY(prepends < max_prepends);
int appends = 0;
const int max_appends = 100;
while (str.data_ptr().freeSpaceAtEnd() >= chunk.size() && appends++ < max_appends)
str.append(chunk);
QVERIFY(appends < max_appends);
QVERIFY(str.capacity() - str.size() >= chunk.size());
QVERIFY(str.data_ptr().freeSpaceAtEnd() < chunk.size());
// WHEN: adding a QStringBuilder expression which exceeds freeSpaceAtEnd()
str += separator P chunk;
// THEN: it doesn't crash (QTBUG-99330)
const String expected = chunk.repeated(prepends + appends) + separator + chunk;
QCOMPARE(str, expected);
}
void runScenario()
{
// this code is latin1. TODO: replace it with the utf8 block below, once
// strings default to utf8.
QLatin1String l1string(LITERAL);
QString string(l1string);
QStringView stringview = QStringView{ string }.mid(2, 10);
QLatin1Char lchar('c');
QChar qchar(lchar);
QChar::SpecialCharacter special(QChar::Nbsp);
char16_t u16char = UNICODE_LITERAL[0];
char16_t u16chararray[] = { u's', 0xF6, u'm', 0xEB, u' ', u'l', 0xEF, u't', 0xEB, u'r', 0xE4, u'l', 0x00 };
QCOMPARE(QStringView(u16chararray), QStringView(UNICODE_LITERAL));
char16_t *u16charstar = u16chararray;
#define CHECK(QorP, a1, a2) \
do { \
DO(QorP, a1, a2); \
DO(QorP, a2, a1); \
} while (0)
#define DO(QorP, a1, a2) \
QCOMPARE(QString(a1 QorP a2), \
toQString(a1).append(toQString(a2))) \
/* end */
CHECK(P, l1string, l1string);
CHECK(P, l1string, string);
CHECK(Q, l1string, stringview);
CHECK(P, l1string, lchar);
CHECK(P, l1string, qchar);
CHECK(P, l1string, special);
CHECK(P, l1string, QStringLiteral(LITERAL));
CHECK(Q, l1string, u16char);
CHECK(Q, l1string, u16chararray);
CHECK(Q, l1string, u16charstar);
CHECK(P, string, string);
CHECK(Q, string, stringview);
CHECK(P, string, lchar);
CHECK(P, string, qchar);
CHECK(P, string, special);
CHECK(P, string, QStringLiteral(LITERAL));
CHECK(Q, string, u16char);
CHECK(Q, string, u16chararray);
CHECK(Q, string, u16charstar);
CHECK(Q, stringview, stringview);
CHECK(Q, stringview, lchar);
CHECK(Q, stringview, qchar);
CHECK(Q, stringview, special);
CHECK(P, stringview, QStringLiteral(LITERAL));
CHECK(Q, stringview, u16char);
CHECK(Q, stringview, u16chararray);
CHECK(Q, stringview, u16charstar);
CHECK(P, lchar, lchar);
CHECK(P, lchar, qchar);
CHECK(P, lchar, special);
CHECK(P, lchar, QStringLiteral(LITERAL));
CHECK(Q, lchar, u16char);
CHECK(Q, lchar, u16chararray);
CHECK(Q, lchar, u16charstar);
CHECK(P, qchar, qchar);
CHECK(P, qchar, special);
CHECK(P, qchar, QStringLiteral(LITERAL));
CHECK(Q, qchar, u16char);
CHECK(Q, qchar, u16chararray);
CHECK(Q, qchar, u16charstar);
CHECK(P, special, special);
CHECK(P, special, QStringLiteral(LITERAL));
CHECK(Q, special, u16char);
CHECK(Q, special, u16chararray);
CHECK(Q, special, u16charstar);
CHECK(P, QStringLiteral(LITERAL), QStringLiteral(LITERAL));
CHECK(Q, QStringLiteral(LITERAL), u16char);
CHECK(Q, QStringLiteral(LITERAL), u16chararray);
CHECK(Q, QStringLiteral(LITERAL), u16charstar);
// CHECK(Q, u16char, u16char); // BUILTIN <-> BUILTIN cat't be overloaded
// CHECK(Q, u16char, u16chararray);
// CHECK(Q, u16char, u16charstar);
// CHECK(Q, u16chararray, u16chararray); // BUILTIN <-> BUILTIN cat't be overloaded
// CHECK(Q, u16chararray, u16charstar);
// CHECK(Q, u16charstar, u16charstar); // BUILTIN <-> BUILTIN cat't be overloaded
#undef DO
#define DO(QorP, a1, a2) \
QCOMPARE(QByteArray(a1 QorP a2), \
toQByteArray(a1).append(toQByteArray(a2))) \
/* end */
QByteArray bytearray = stringview.toUtf8();
char *charstar = bytearray.data();
char chararray[3] = { 'H', 'i', '\0' };
const char constchararray[3] = { 'H', 'i', '\0' };
char achar = 'a';
CHECK(P, bytearray, bytearray);
CHECK(P, bytearray, charstar);
#ifndef Q_CC_MSVC // see QTBUG-65359
CHECK(P, bytearray, chararray);
#else
Q_UNUSED(chararray);
#endif
CHECK(P, bytearray, constchararray);
CHECK(P, bytearray, achar);
//CHECK(Q, charstar, charstar); // BUILTIN <-> BUILTIN cat't be overloaded
//CHECK(Q, charstar, chararray);
//CHECK(Q, charstar, achar);
//CHECK(Q, chararray, chararray); // BUILTIN <-> BUILTIN cat't be overloaded
//CHECK(Q, chararray, achar);
//CHECK(Q, achar, achar); // BUILTIN <-> BUILTIN cat't be overloaded
#undef DO
#undef CHECK
QString r2(QLatin1String(LITERAL LITERAL));
QString r3 = QString::fromUtf8(UTF8_LITERAL UTF8_LITERAL);
QString r;
// self-assignment:
r = stringview.toString();
r = lchar + r;
QCOMPARE(r, QString(lchar P stringview));
r = QStringLiteral(UNICODE_LITERAL);
r = r Q QStringLiteral(UNICODE_LITERAL);
QCOMPARE(r, r3);
#ifndef QT_NO_CAST_FROM_ASCII
r = string P LITERAL;
QCOMPARE(r, r2);
r = LITERAL P string;
QCOMPARE(r, r2);
QByteArray ba = QByteArray(LITERAL);
r = ba P string;
QCOMPARE(r, r2);
r = string P ba;
QCOMPARE(r, r2);
r = string P QByteArrayLiteral(LITERAL);
QCOMPARE(r, r2);
r = QByteArrayLiteral(LITERAL) P string;
QCOMPARE(r, r2);
static const char badata[] = LITERAL_EXTRA;
ba = QByteArray::fromRawData(badata, LITERAL_LEN);
r = ba P string;
QCOMPARE(r, r2);
r = string P ba;
QCOMPARE(r, r2);
string = QString::fromUtf8(UTF8_LITERAL);
ba = UTF8_LITERAL;
r = string P UTF8_LITERAL;
QCOMPARE(r.size(), r3.size());
QCOMPARE(r, r3);
r = UTF8_LITERAL P string;
QCOMPARE(r, r3);
r = ba P string;
QCOMPARE(r, r3);
r = string P ba;
QCOMPARE(r, r3);
ba = QByteArray::fromRawData(UTF8_LITERAL_EXTRA, UTF8_LITERAL_LEN);
r = ba P string;
QCOMPARE(r, r3);
r = string P ba;
QCOMPARE(r, r3);
ba = QByteArray(); // empty
r = ba P string;
QCOMPARE(r, string);
r = string P ba;
QCOMPARE(r, string);
const char *zero = nullptr;
r = string P zero;
QCOMPARE(r, string);
r = zero P string;
QCOMPARE(r, string);
#endif
string = QString::fromLatin1(LITERAL);
QCOMPARE(QByteArray(qPrintable(string P string)), QByteArray(string.toLatin1() + string.toLatin1()));
//QByteArray
{
QByteArray ba = LITERAL;
QByteArray superba = ba P ba P LITERAL;
QCOMPARE(superba, QByteArray(LITERAL LITERAL LITERAL));
ba = QByteArrayLiteral(LITERAL);
QCOMPARE(ba, QByteArray(LITERAL));
superba = ba P QByteArrayLiteral(LITERAL) P LITERAL;
QCOMPARE(superba, QByteArray(LITERAL LITERAL LITERAL));
QByteArray testWith0 = ba P "test\0with\0zero" P ba;
QCOMPARE(testWith0, QByteArray(LITERAL "test" LITERAL));
QByteArray ba2 = ba P '\0' + LITERAL;
QCOMPARE(ba2, QByteArray(LITERAL "\0" LITERAL, ba.size()*2+1));
const char *mmh = "test\0foo";
QCOMPARE(QByteArray(ba P mmh P ba), testWith0);
QByteArray raw = QByteArray::fromRawData(UTF8_LITERAL_EXTRA, UTF8_LITERAL_LEN);
QByteArray r = "hello" P raw;
QByteArray r2 = "hello" UTF8_LITERAL;
QCOMPARE(r, r2);
r2 = QByteArray("hello\0") P UTF8_LITERAL;
QCOMPARE(r, r2);
const char *zero = nullptr;
r = ba P zero;
QCOMPARE(r, ba);
r = zero P ba;
QCOMPARE(r, ba);
QByteArrayView qbav = LITERAL;
superba = qbav P qbav P LITERAL;
QCOMPARE(superba, QByteArray(LITERAL LITERAL LITERAL));
}
//operator QString +=
{
QString str = QString::fromUtf8(UTF8_LITERAL);
str += QLatin1String(LITERAL) P str;
QCOMPARE(str, QString::fromUtf8(UTF8_LITERAL LITERAL UTF8_LITERAL));
#ifndef QT_NO_CAST_FROM_ASCII
str = (QString::fromUtf8(UTF8_LITERAL) += QLatin1String(LITERAL) P UTF8_LITERAL);
QCOMPARE(str, QString::fromUtf8(UTF8_LITERAL LITERAL UTF8_LITERAL));
#endif
QString str2 = QString::fromUtf8(UTF8_LITERAL);
QString str2_e = QString::fromUtf8(UTF8_LITERAL);
const char * nullData = 0;
str2 += QLatin1String(nullData) P str2;
str2_e += QLatin1String("") P str2_e;
QCOMPARE(str2, str2_e);
}
checkItWorksWithFreeSpaceAtBegin(QString::fromUtf8(UTF8_LITERAL),
#ifdef QT_NO_CAST_FROM_ASCII
QLatin1String("1234")
#else
"1234"
#endif
);
if (QTest::currentTestFailed())
return;
//operator QByteArray +=
{
QByteArray ba = UTF8_LITERAL;
ba += QByteArray(LITERAL) P UTF8_LITERAL;
QCOMPARE(ba, QByteArray(UTF8_LITERAL LITERAL UTF8_LITERAL));
ba += LITERAL P QByteArray::fromRawData(UTF8_LITERAL_EXTRA, UTF8_LITERAL_LEN);
QCOMPARE(ba, QByteArray(UTF8_LITERAL LITERAL UTF8_LITERAL LITERAL UTF8_LITERAL));
QByteArray withZero = QByteArray(LITERAL "\0" LITERAL, LITERAL_LEN*2+1);
QByteArray ba2 = withZero;
ba2 += ba2 P withZero;
QCOMPARE(ba2, QByteArray(withZero + withZero + withZero));
}
checkItWorksWithFreeSpaceAtBegin(QByteArray(UTF8_LITERAL), "1234");
if (QTest::currentTestFailed())
return;
}

View File

@ -0,0 +1,36 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include <QtCore/qglobal.h>
// SCENARIO 1
// this is the "no harm done" version. Only operator% is active,
// with NO_CAST * defined
#undef QT_USE_QSTRINGBUILDER
#define QT_NO_CAST_FROM_ASCII
#define QT_NO_CAST_TO_ASCII
#include <QtCore/QObject>
#include <QtCore/QString>
#include <QtCore/QStringBuilder>
#include <QtTest/QTest>
#define LITERAL "some literal"
void runScenario(); // Defined in stringbuilder.cpp #included below.
class tst_QStringBuilder1 : public QObject
{
Q_OBJECT
private slots:
void scenario() { runScenario(); }
};
#define P %
#include "stringbuilder.cpp"
#undef P
#include "tst_qstringbuilder1.moc"
QTEST_APPLESS_MAIN(tst_QStringBuilder1)

View File

@ -0,0 +1,11 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qstringbuilder2 Test:
#####################################################################
qt_internal_add_test(tst_qstringbuilder2
SOURCES
tst_qstringbuilder2.cpp
)

View File

@ -0,0 +1,37 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include <QtCore/qglobal.h>
// SCENARIO 2
// this is the "full" version. Operator+ is replaced by a QStringBuilder
// based version
// with NO_CAST * defined
#define QT_USE_QSTRINGBUILDER
#define QT_NO_CAST_FROM_ASCII
#define QT_NO_CAST_TO_ASCII
#include <QtCore/QObject>
#include <QtCore/QString>
#include <QtCore/QStringBuilder>
#include <QtTest/QTest>
#define LITERAL "some literal"
void runScenario(); // Defined in stringbuilder.cpp #included below.
class tst_QStringBuilder2 : public QObject
{
Q_OBJECT
private slots:
void scenario() { runScenario(); }
};
#define P +
#include "../qstringbuilder1/stringbuilder.cpp"
#undef P
#include "tst_qstringbuilder2.moc"
QTEST_APPLESS_MAIN(tst_QStringBuilder2)

View File

@ -0,0 +1,11 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qstringbuilder3 Test:
#####################################################################
qt_internal_add_test(tst_qstringbuilder3
SOURCES
tst_qstringbuilder3.cpp
)

View File

@ -0,0 +1,36 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include <QtCore/qglobal.h>
// SCENARIO 3
// this is the "no harm done" version. Only operator% is active,
// with NO_CAST * _not_ defined
#undef QT_USE_QSTRINGBUILDER
#undef QT_NO_CAST_FROM_ASCII
#undef QT_NO_CAST_TO_ASCII
#include <QtCore/QObject>
#include <QtCore/QString>
#include <QtCore/QStringBuilder>
#include <QtTest/QTest>
#define LITERAL "some literal"
void runScenario(); // Defined in stringbuilder.cpp #included below.
class tst_QStringBuilder3 : public QObject
{
Q_OBJECT
private slots:
void scenario() { runScenario(); }
};
#define P %
#include "../qstringbuilder1/stringbuilder.cpp"
#undef P
#include "tst_qstringbuilder3.moc"
QTEST_APPLESS_MAIN(tst_QStringBuilder3)

View File

@ -0,0 +1,11 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qstringbuilder4 Test:
#####################################################################
qt_internal_add_test(tst_qstringbuilder4
SOURCES
tst_qstringbuilder4.cpp
)

View File

@ -0,0 +1,37 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include <QtCore/qglobal.h>
// SCENARIO 4
// this is the "full" version. Operator+ is replaced by a QStringBuilder
// based version
// with NO_CAST * _not_ defined
#define QT_USE_QSTRINGBUILDER
#undef QT_NO_CAST_FROM_ASCII
#undef QT_NO_CAST_TO_ASCII
#include <QtCore/QObject>
#include <QtCore/QString>
#include <QtCore/QStringBuilder>
#include <QtTest/QTest>
#define LITERAL "some literal"
void runScenario(); // Defined in stringbuilder.cpp #included below.
class tst_QStringBuilder4 : public QObject
{
Q_OBJECT
private slots:
void scenario() { runScenario(); }
};
#define P +
#include "../qstringbuilder1/stringbuilder.cpp"
#undef P
#include "tst_qstringbuilder4.moc"
QTEST_APPLESS_MAIN(tst_QStringBuilder4)

View File

@ -0,0 +1,22 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qstringconverter Test:
#####################################################################
qt_internal_add_test(tst_qstringconverter
SOURCES
tst_qstringconverter.cpp
TESTDATA ${test_data}
LIBRARIES
Qt::CorePrivate # for access to Qt's feature system
)
qt_internal_add_resource(tst_qstringconverter "compressedtexture_bc1"
PREFIX
"/"
FILES
"euc_kr.txt"
)

View File

@ -0,0 +1 @@
<EFBFBD>Ы<EFBFBD><EFBFBD><EFBFBD>?<3F>Ȫ<EFBFBD>ʦ?<3F><><EFBFBD><EFBFBD>?<3F>ɪǪ<C9AA><C7AA><EFBFBD>EUC Packed Format<61>ȡ<EFBFBD>2<EFBFBD>Ы<EFBFBD><D0AB><EFBFBD>ͳ<EFBFBD><CDB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>EUC Fixed Width Format<61><74><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EBA1A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ġ<EFBFBD><C4A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?ݻ?<3F><><EFBFBD>Īǡ<C4AA><C7A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>EUC<55>Ȫ<EFBFBD><C8AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>򦪹<EFBFBD><F2A6AAB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ǫ<EFBFBD><C7AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˪Ī<CBAA><C4AA><EFBFBD><EFBFBD><EFBFBD>?<3F><><EFBFBD>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,13 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qstringiterator Test:
#####################################################################
qt_internal_add_test(tst_qstringiterator
SOURCES
tst_qstringiterator.cpp
LIBRARIES
Qt::CorePrivate
)

View File

@ -0,0 +1,637 @@
// Copyright (C) 2014 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include <QTest>
#include <QtCore/QString>
#include <private/qstringiterator_p.h>
class tst_QStringIterator : public QObject
{
Q_OBJECT
private slots:
void sweep_data();
void sweep();
void position();
};
void tst_QStringIterator::sweep_data()
{
QTest::addColumn<QString>("string");
QTest::addColumn<bool>("valid");
QTest::addColumn<int>("count");
QTest::newRow("sweep_00") << QString::fromUtf8("", 0) << true << 0;
QTest::newRow("sweep_01") << QString::fromUtf8("a", 1) << true << 1;
QTest::newRow("sweep_02") << QString::fromUtf8("a string", 8) << true << 8;
QTest::newRow("sweep_03") << QString::fromUtf8("\xc3\xa0\xc3\xa8\xc3\xac\xc3\xb2\xc3\xb9", 10) << true << 5;
QTest::newRow("sweep_04") << QString::fromUtf8("\xc3\x9f\xe2\x80\x94\xc2\xa1", 7) << true << 3;
QTest::newRow("sweep_05") << QString::fromUtf8("\xe6\xb0\xb4\xe6\xb0\xb5\xe6\xb0\xb6\xe6\xb0\xb7\xe6\xb0\xb8\xe6\xb0\xb9", 18) << true << 6;
QTest::newRow("sweep_06") << QString::fromUtf8("\xf0\x9f\x98\x81\xf0\x9f\x98\x82\x61\x62\x63\xf0\x9f\x98\x83\xc4\x91\xc3\xa8\xef\xac\x80\xf0\x9f\x98\x84\xf0\x9f\x98\x85", 30) << true << 11;
QTest::newRow("sweep_07") << QString::fromUtf8("\xf0\x9f\x82\xaa\xf0\x9f\x82\xab\xf0\x9f\x82\xad\xf0\x9f\x82\xae\xf0\x9f\x82\xa1\x20\x52\x4f\x59\x41\x4c\x20\x46\x4c\x55\x53\x48\x20\x4f\x46\x20\x53\x50\x41\x44\x45\x53", 42) << true << 27;
QTest::newRow("sweep_08") << QString::fromUtf8("abc\0def", 7) << true << 7;
QTest::newRow("sweep_09") << QString::fromUtf8("\xc3\xa0\xce\xb2\xc3\xa7\xf0\x9f\x80\xb9\xf0\x9f\x80\xb8\x00\xf0\x9f\x80\xb1\x00\xf0\x9f\x80\xb3\xf0\x9f\x81\x85\xe1\xb8\x8a\xc4\x99\xc6\x92", 35) << true << 13;
QTest::newRow("sweep_invalid_00") << QString(QChar(0xd800)) << false << 1;
QTest::newRow("sweep_invalid_01") << QString(QChar(0xdc00)) << false << 1;
QTest::newRow("sweep_invalid_02") << QString(QChar(0xdbff)) << false << 1;
QTest::newRow("sweep_invalid_03") << QString(QChar(0xdfff)) << false << 1;
#define QSTRING_FROM_QCHARARRAY(x) (QString((x), sizeof(x)/sizeof((x)[0])))
static const QChar invalid_04[] = {
QLatin1Char('i'), QLatin1Char('n'), QLatin1Char('v'),
QLatin1Char('a'), QLatin1Char('l'), QLatin1Char('i'),
QLatin1Char('d'), QChar(0xd800)
};
QTest::newRow("sweep_invalid_04") << QSTRING_FROM_QCHARARRAY(invalid_04) << false << 8;
static const QChar invalid_05[] = {
QLatin1Char('i'), QLatin1Char('n'), QLatin1Char('v'),
QLatin1Char('a'), QLatin1Char('l'), QLatin1Char('i'),
QLatin1Char('d'), QChar(0xd800), QLatin1Char('x')
};
QTest::newRow("sweep_invalid_05") << QSTRING_FROM_QCHARARRAY(invalid_05) << false << 9;
static const QChar invalid_06[] = {
QLatin1Char('i'), QLatin1Char('n'), QLatin1Char('v'),
QLatin1Char('a'), QLatin1Char('l'), QLatin1Char('i'),
QLatin1Char('d'), QChar(0xdc00)
};
QTest::newRow("sweep_invalid_06") << QSTRING_FROM_QCHARARRAY(invalid_06) << false << 8;
static const QChar invalid_07[] = {
QLatin1Char('i'), QLatin1Char('n'), QLatin1Char('v'),
QLatin1Char('a'), QLatin1Char('l'), QLatin1Char('i'),
QLatin1Char('d'), QChar(0xdc00), QLatin1Char('x')
};
QTest::newRow("sweep_invalid_07") << QSTRING_FROM_QCHARARRAY(invalid_07) << false << 9;
static const QChar invalid_08[] = {
QChar(0xd800),
QLatin1Char('i'), QLatin1Char('n'), QLatin1Char('v'),
QLatin1Char('a'), QLatin1Char('l'), QLatin1Char('i'),
QLatin1Char('d')
};
QTest::newRow("sweep_invalid_08") << QSTRING_FROM_QCHARARRAY(invalid_08) << false << 8;
static const QChar invalid_09[] = {
QChar(0xdc00),
QLatin1Char('i'), QLatin1Char('n'), QLatin1Char('v'),
QLatin1Char('a'), QLatin1Char('l'), QLatin1Char('i'),
QLatin1Char('d')
};
QTest::newRow("sweep_invalid_09") << QSTRING_FROM_QCHARARRAY(invalid_09) << false << 8;
static const QChar invalid_10[] = {
QChar(0xd800), QChar(0xd800),
QLatin1Char('i'), QLatin1Char('n'), QLatin1Char('v'),
QLatin1Char('a'), QLatin1Char('l'), QLatin1Char('i'),
QLatin1Char('d')
};
QTest::newRow("sweep_invalid_10") << QSTRING_FROM_QCHARARRAY(invalid_10) << false << 9;
static const QChar invalid_11[] = {
QChar(0xdc00), QChar(0xd800),
QLatin1Char('i'), QLatin1Char('n'), QLatin1Char('v'),
QLatin1Char('a'), QLatin1Char('l'), QLatin1Char('i'),
QLatin1Char('d')
};
QTest::newRow("sweep_invalid_11") << QSTRING_FROM_QCHARARRAY(invalid_11) << false << 9;
static const QChar invalid_12[] = {
QChar(0xdc00), QChar(0xdc00),
QLatin1Char('i'), QLatin1Char('n'), QLatin1Char('v'),
QLatin1Char('a'), QLatin1Char('l'), QLatin1Char('i'),
QLatin1Char('d')
};
QTest::newRow("sweep_invalid_12") << QSTRING_FROM_QCHARARRAY(invalid_12) << false << 9;
static const QChar invalid_13[] = {
QLatin1Char('i'), QLatin1Char('n'), QLatin1Char('v'),
QChar(0xd800), QChar(0xdf00), // U+10300 OLD ITALIC LETTER A
QLatin1Char('a'), QLatin1Char('l'), QLatin1Char('i'),
QLatin1Char('d'), QChar(0xd800)
};
QTest::newRow("sweep_invalid_13") << QSTRING_FROM_QCHARARRAY(invalid_13) << false << 9;
static const QChar invalid_14[] = {
QLatin1Char('i'), QLatin1Char('n'), QLatin1Char('v'),
QChar(0xd800), QChar(0xdf00), // U+10300 OLD ITALIC LETTER A
QLatin1Char('a'), QLatin1Char('l'), QLatin1Char('i'),
QLatin1Char('d'), QChar(0xd800), QLatin1Char('x')
};
QTest::newRow("sweep_invalid_14") << QSTRING_FROM_QCHARARRAY(invalid_14) << false << 10;
static const QChar invalid_15[] = {
QLatin1Char('i'), QLatin1Char('n'), QLatin1Char('v'),
QChar(0xd800), QChar(0xdf00), // U+10300 OLD ITALIC LETTER A
QLatin1Char('a'), QLatin1Char('l'), QLatin1Char('i'),
QLatin1Char('d'), QChar(0xdc00)
};
QTest::newRow("sweep_invalid_15") << QSTRING_FROM_QCHARARRAY(invalid_15) << false << 9;
static const QChar invalid_16[] = {
QLatin1Char('i'), QLatin1Char('n'), QLatin1Char('v'),
QChar(0xd800), QChar(0xdf00), // U+10300 OLD ITALIC LETTER A
QLatin1Char('a'), QLatin1Char('l'), QLatin1Char('i'),
QLatin1Char('d'), QChar(0xdc00), QLatin1Char('x')
};
QTest::newRow("sweep_invalid_16") << QSTRING_FROM_QCHARARRAY(invalid_16) << false << 10;
static const QChar invalid_17[] = {
QChar(0xd800),
QLatin1Char('i'), QLatin1Char('n'), QLatin1Char('v'),
QChar(0xd800), QChar(0xdf00), // U+10300 OLD ITALIC LETTER A
QLatin1Char('a'), QLatin1Char('l'), QLatin1Char('i'),
QLatin1Char('d')
};
QTest::newRow("sweep_invalid_17") << QSTRING_FROM_QCHARARRAY(invalid_17) << false << 9;
static const QChar invalid_18[] = {
QChar(0xdc00),
QLatin1Char('i'), QLatin1Char('n'), QLatin1Char('v'),
QChar(0xd800), QChar(0xdf00), // U+10300 OLD ITALIC LETTER A
QLatin1Char('a'), QLatin1Char('l'), QLatin1Char('i'),
QLatin1Char('d')
};
QTest::newRow("sweep_invalid_18") << QSTRING_FROM_QCHARARRAY(invalid_18) << false << 9;
#undef QSTRING_FROM_QCHARARRAY
}
void tst_QStringIterator::sweep()
{
QFETCH(QString, string);
QFETCH(bool, valid);
QStringIterator i(string);
int count = 0;
QString rebuiltString;
while (i.hasNext()) {
const char32_t peekedCodePoint = i.peekNext(~0u);
const char32_t codePoint = i.next(~0u);
QVERIFY(peekedCodePoint == codePoint);
if (codePoint == ~0u)
rebuiltString += *(i.position() - 1);
else
rebuiltString += QChar::fromUcs4(codePoint);
++count;
}
QTEST(count, "count");
QTEST(rebuiltString, "string");
rebuiltString.clear();
while (i.hasPrevious()) {
const char32_t peekedCodePoint = i.peekPrevious(~0u);
const char32_t codePoint = i.previous(~0u);
QVERIFY(peekedCodePoint == codePoint);
--count;
}
QCOMPARE(count, 0);
while (i.hasNext()) {
i.advance();
++count;
}
QTEST(count, "count");
while (i.hasPrevious()) {
i.recede();
--count;
}
QCOMPARE(count, 0);
if (valid) {
while (i.hasNext()) {
const char32_t peekedCodePoint = i.peekNextUnchecked();
const char32_t codePoint = i.nextUnchecked();
QVERIFY(peekedCodePoint == codePoint);
QVERIFY(codePoint <= 0x10FFFFu);
rebuiltString += QChar::fromUcs4(codePoint);
++count;
}
QTEST(count, "count");
QTEST(rebuiltString, "string");
while (i.hasPrevious()) {
const char32_t peekedCodePoint = i.peekPreviousUnchecked();
const char32_t codePoint = i.previousUnchecked();
QVERIFY(peekedCodePoint == codePoint);
--count;
}
QCOMPARE(count, 0);
while (i.hasNext()) {
i.advanceUnchecked();
++count;
}
QTEST(count, "count");
while (i.hasPrevious()) {
i.recedeUnchecked();
--count;
}
QCOMPARE(count, 0);
}
}
void tst_QStringIterator::position()
{
static const QChar stringData[] =
{
// codeunit count: 0
QLatin1Char('a'), QLatin1Char('b'), QLatin1Char('c'),
// codeunit count: 3
QChar(0x00A9), // U+00A9 COPYRIGHT SIGN
// codeunit count: 4
QChar(0x00AE), // U+00AE REGISTERED SIGN
// codeunit count: 5
QLatin1Char('d'), QLatin1Char('e'), QLatin1Char('f'),
// codeunit count: 8
QLatin1Char('\0'),
// codeunit count: 9
QLatin1Char('g'), QLatin1Char('h'), QLatin1Char('i'),
// codeunit count: 12
QChar(0xD834), QChar(0xDD1E), // U+1D11E MUSICAL SYMBOL G CLEF
// codeunit count: 14
QChar(0xD834), QChar(0xDD21), // U+1D121 MUSICAL SYMBOL C CLEF
// codeunit count: 16
QLatin1Char('j'),
// codeunit count: 17
QChar(0xD800), // stray high surrogate
// codeunit count: 18
QLatin1Char('k'),
// codeunit count: 19
QChar(0xDC00), // stray low surrogate
// codeunit count: 20
QLatin1Char('l'),
// codeunit count: 21
QChar(0xD800), QChar(0xD800), // two high surrogates
// codeunit count: 23
QLatin1Char('m'),
// codeunit count: 24
QChar(0xDC00), QChar(0xDC00), // two low surrogates
// codeunit count: 26
QLatin1Char('n'),
// codeunit count: 27
QChar(0xD800), QChar(0xD800), QChar(0xDC00), // stray high surrogate followed by valid pair
// codeunit count: 30
QLatin1Char('o'),
// codeunit count: 31
QChar(0xDC00), QChar(0xD800), QChar(0xDC00), // stray low surrogate followed by valid pair
// codeunit count: 34
QLatin1Char('p')
// codeunit count: 35
};
static const int stringDataSize = sizeof(stringData) / sizeof(stringData[0]);
QStringIterator i(QStringView(stringData, stringDataSize));
QCOMPARE(i.position(), stringData);
QVERIFY(i.hasNext());
QVERIFY(!i.hasPrevious());
i.setPosition(stringData + stringDataSize);
QCOMPARE(i.position(), stringData + stringDataSize);
QVERIFY(!i.hasNext());
QVERIFY(i.hasPrevious());
#define QCHAR_UNICODE_VALUE(x) ((uint)(QChar(x).unicode()))
const QChar *begin = stringData;
i.setPosition(begin);
QCOMPARE(i.position(), begin);
QCOMPARE(i.peekNext(), QCHAR_UNICODE_VALUE(QLatin1Char('a')));
QCOMPARE(i.next(), QCHAR_UNICODE_VALUE(QLatin1Char('a')));
QCOMPARE(i.position(), begin + 1);
i.setPosition(begin + 2);
QCOMPARE(i.position(), begin + 2);
QCOMPARE(i.peekNext(), QCHAR_UNICODE_VALUE(QLatin1Char('c')));
QCOMPARE(i.next(), QCHAR_UNICODE_VALUE(QLatin1Char('c')));
QCOMPARE(i.position(), begin + 3);
QCOMPARE(i.peekNext(), QCHAR_UNICODE_VALUE(0x00A9));
QCOMPARE(i.next(), QCHAR_UNICODE_VALUE(0x00A9));
QCOMPARE(i.position(), begin + 4);
QCOMPARE(i.peekNext(), QCHAR_UNICODE_VALUE(0x00AE));
QCOMPARE(i.next(), QCHAR_UNICODE_VALUE(0x00AE));
QCOMPARE(i.position(), begin + 5);
QCOMPARE(i.peekPrevious(), QCHAR_UNICODE_VALUE(0x00AE));
QCOMPARE(i.previous(), QCHAR_UNICODE_VALUE(0x00AE));
QCOMPARE(i.position(), begin + 4);
QCOMPARE(i.peekPrevious(), QCHAR_UNICODE_VALUE(0x00A9));
QCOMPARE(i.previous(), QCHAR_UNICODE_VALUE(0x00A9));
QCOMPARE(i.position(), begin + 3);
i.setPosition(begin + 8);
QCOMPARE(i.position(), begin + 8);
QCOMPARE(i.peekNext(), QCHAR_UNICODE_VALUE(QLatin1Char('\0')));
QCOMPARE(i.next(), QCHAR_UNICODE_VALUE(QLatin1Char('\0')));
QCOMPARE(i.position(), begin + 9);
QCOMPARE(i.peekNext(), QCHAR_UNICODE_VALUE(QLatin1Char('g')));
QCOMPARE(i.next(), QCHAR_UNICODE_VALUE(QLatin1Char('g')));
QCOMPARE(i.position(), begin + 10);
QCOMPARE(i.peekPrevious(), QCHAR_UNICODE_VALUE(QLatin1Char('g')));
QCOMPARE(i.previous(), QCHAR_UNICODE_VALUE(QLatin1Char('g')));
QCOMPARE(i.position(), begin + 9);
QCOMPARE(i.peekPrevious(), QCHAR_UNICODE_VALUE(QLatin1Char('\0')));
QCOMPARE(i.previous(), QCHAR_UNICODE_VALUE(QLatin1Char('\0')));
QCOMPARE(i.position(), begin + 8);
QCOMPARE(i.peekPrevious(), QCHAR_UNICODE_VALUE(QLatin1Char('f')));
QCOMPARE(i.previous(), QCHAR_UNICODE_VALUE(QLatin1Char('f')));
QCOMPARE(i.position(), begin + 7);
i.advanceUnchecked();
i.advanceUnchecked();
i.advanceUnchecked();
i.advanceUnchecked();
i.advanceUnchecked();
QCOMPARE(i.position(), begin + 12);
QCOMPARE(i.peekNext(), 0x1D11Eu);
QCOMPARE(i.next(), 0x1D11Eu);
QCOMPARE(i.position(), begin + 14);
QCOMPARE(i.peekNext(), 0x1D121u);
QCOMPARE(i.next(), 0x1D121u);
QCOMPARE(i.position(), begin + 16);
QCOMPARE(i.peekNext(), QCHAR_UNICODE_VALUE(QLatin1Char('j')));
QCOMPARE(i.next(), QCHAR_UNICODE_VALUE(QLatin1Char('j')));
QCOMPARE(i.position(), begin + 17);
QCOMPARE(i.peekPrevious(), QCHAR_UNICODE_VALUE(QLatin1Char('j')));
QCOMPARE(i.previous(), QCHAR_UNICODE_VALUE(QLatin1Char('j')));
QCOMPARE(i.position(), begin + 16);
QCOMPARE(i.peekPrevious(), 0x1D121u);
QCOMPARE(i.previous(), 0x1D121u);
QCOMPARE(i.position(), begin + 14);
QCOMPARE(i.peekPrevious(), 0x1D11Eu);
QCOMPARE(i.previous(), 0x1D11Eu);
QCOMPARE(i.position(), begin + 12);
i.setPosition(begin + 13);
QCOMPARE(i.position(), begin + 13);
QCOMPARE(i.peekNext(), 0xFFFDu);
QCOMPARE(i.next(), 0xFFFDu);
QCOMPARE(i.position(), begin + 14);
QCOMPARE(i.peekNext(), 0x1D121u);
QCOMPARE(i.next(), 0x1D121u);
QCOMPARE(i.position(), begin + 16);
i.setPosition(begin + 15);
QCOMPARE(i.position(), begin + 15);
QCOMPARE(i.peekPrevious(), 0xFFFDu);
QCOMPARE(i.previous(), 0xFFFDu);
QCOMPARE(i.position(), begin + 14);
QCOMPARE(i.peekPrevious(), 0x1D11Eu);
QCOMPARE(i.previous(), 0x1D11Eu);
QCOMPARE(i.position(), begin + 12);
i.advanceUnchecked();
i.advanceUnchecked();
QCOMPARE(i.position(), begin + 16);
QCOMPARE(i.peekNext(), QCHAR_UNICODE_VALUE(QLatin1Char('j')));
QCOMPARE(i.next(), QCHAR_UNICODE_VALUE(QLatin1Char('j')));
QCOMPARE(i.position(), begin + 17);
QCOMPARE(i.peekNext(), 0xFFFDu);
QCOMPARE(i.next(), 0xFFFDu);
QCOMPARE(i.position(), begin + 18);
QCOMPARE(i.peekNext(), QCHAR_UNICODE_VALUE(QLatin1Char('k')));
QCOMPARE(i.next(), QCHAR_UNICODE_VALUE(QLatin1Char('k')));
QCOMPARE(i.position(), begin + 19);
QCOMPARE(i.peekNext(), 0xFFFDu);
QCOMPARE(i.next(), 0xFFFDu);
QCOMPARE(i.position(), begin + 20);
QCOMPARE(i.peekNext(), QCHAR_UNICODE_VALUE(QLatin1Char('l')));
QCOMPARE(i.next(), QCHAR_UNICODE_VALUE(QLatin1Char('l')));
QCOMPARE(i.position(), begin + 21);
QCOMPARE(i.peekNext(), 0xFFFDu);
QCOMPARE(i.next(), 0xFFFDu);
QCOMPARE(i.position(), begin + 22);
QCOMPARE(i.peekNext(), 0xFFFDu);
QCOMPARE(i.next(), 0xFFFDu);
QCOMPARE(i.position(), begin + 23);
QCOMPARE(i.peekNext(), QCHAR_UNICODE_VALUE(QLatin1Char('m')));
QCOMPARE(i.next(), QCHAR_UNICODE_VALUE(QLatin1Char('m')));
QCOMPARE(i.position(), begin + 24);
QCOMPARE(i.peekNext(), 0xFFFDu);
QCOMPARE(i.next(), 0xFFFDu);
QCOMPARE(i.position(), begin + 25);
QCOMPARE(i.peekNext(), 0xFFFDu);
QCOMPARE(i.next(), 0xFFFDu);
QCOMPARE(i.position(), begin + 26);
QCOMPARE(i.peekNext(), QCHAR_UNICODE_VALUE(QLatin1Char('n')));
QCOMPARE(i.next(), QCHAR_UNICODE_VALUE(QLatin1Char('n')));
QCOMPARE(i.position(), begin + 27);
QCOMPARE(i.peekNext(), 0xFFFDu);
QCOMPARE(i.next(), 0xFFFDu);
QCOMPARE(i.position(), begin + 28);
QCOMPARE(i.peekNext(), 0x10000u);
QCOMPARE(i.next(), 0x10000u);
QCOMPARE(i.position(), begin + 30);
QCOMPARE(i.peekNext(), QCHAR_UNICODE_VALUE(QLatin1Char('o')));
QCOMPARE(i.next(), QCHAR_UNICODE_VALUE(QLatin1Char('o')));
QCOMPARE(i.position(), begin + 31);
QCOMPARE(i.peekNext(), 0xFFFDu);
QCOMPARE(i.next(), 0xFFFDu);
QCOMPARE(i.position(), begin + 32);
QCOMPARE(i.peekNext(), 0x10000u);
QCOMPARE(i.next(), 0x10000u);
QCOMPARE(i.position(), begin + 34);
QCOMPARE(i.peekNext(), QCHAR_UNICODE_VALUE(QLatin1Char('p')));
QCOMPARE(i.next(), QCHAR_UNICODE_VALUE(QLatin1Char('p')));
QVERIFY(!i.hasNext());
QCOMPARE(i.position(), begin + 35);
QCOMPARE(i.peekPrevious(), QCHAR_UNICODE_VALUE(QLatin1Char('p')));
QCOMPARE(i.previous(), QCHAR_UNICODE_VALUE(QLatin1Char('p')));
QCOMPARE(i.position(), begin + 34);
QCOMPARE(i.peekPrevious(), 0x10000u);
QCOMPARE(i.previous(), 0x10000u);
QCOMPARE(i.position(), begin + 32);
QCOMPARE(i.peekPrevious(), 0xFFFDu);
QCOMPARE(i.previous(), 0xFFFDu);
QCOMPARE(i.position(), begin + 31);
QCOMPARE(i.peekPrevious(), QCHAR_UNICODE_VALUE(QLatin1Char('o')));
QCOMPARE(i.previous(), QCHAR_UNICODE_VALUE(QLatin1Char('o')));
QCOMPARE(i.position(), begin + 30);
QCOMPARE(i.peekPrevious(), 0x10000u);
QCOMPARE(i.previous(), 0x10000u);
QCOMPARE(i.position(), begin + 28);
QCOMPARE(i.peekPrevious(), 0xFFFDu);
QCOMPARE(i.previous(), 0xFFFDu);
QCOMPARE(i.position(), begin + 27);
QCOMPARE(i.peekPrevious(), QCHAR_UNICODE_VALUE(QLatin1Char('n')));
QCOMPARE(i.previous(), QCHAR_UNICODE_VALUE(QLatin1Char('n')));
QCOMPARE(i.position(), begin + 26);
QCOMPARE(i.peekPrevious(), 0xFFFDu);
QCOMPARE(i.previous(), 0xFFFDu);
QCOMPARE(i.position(), begin + 25);
QCOMPARE(i.peekPrevious(), 0xFFFDu);
QCOMPARE(i.previous(), 0xFFFDu);
QCOMPARE(i.position(), begin + 24);
QCOMPARE(i.peekPrevious(), QCHAR_UNICODE_VALUE(QLatin1Char('m')));
QCOMPARE(i.previous(), QCHAR_UNICODE_VALUE(QLatin1Char('m')));
QCOMPARE(i.position(), begin + 23);
QCOMPARE(i.peekPrevious(), 0xFFFDu);
QCOMPARE(i.previous(), 0xFFFDu);
QCOMPARE(i.position(), begin + 22);
QCOMPARE(i.peekPrevious(), 0xFFFDu);
QCOMPARE(i.previous(), 0xFFFDu);
QCOMPARE(i.position(), begin + 21);
QCOMPARE(i.peekPrevious(), QCHAR_UNICODE_VALUE(QLatin1Char('l')));
QCOMPARE(i.previous(), QCHAR_UNICODE_VALUE(QLatin1Char('l')));
QCOMPARE(i.position(), begin + 20);
QCOMPARE(i.peekPrevious(), 0xFFFDu);
QCOMPARE(i.previous(), 0xFFFDu);
QCOMPARE(i.position(), begin + 19);
QCOMPARE(i.peekPrevious(), QCHAR_UNICODE_VALUE(QLatin1Char('k')));
QCOMPARE(i.previous(), QCHAR_UNICODE_VALUE(QLatin1Char('k')));
QCOMPARE(i.position(), begin + 18);
QCOMPARE(i.peekPrevious(), 0xFFFDu);
QCOMPARE(i.previous(), 0xFFFDu);
QCOMPARE(i.position(), begin + 17);
QCOMPARE(i.peekPrevious(), QCHAR_UNICODE_VALUE(QLatin1Char('j')));
QCOMPARE(i.previous(), QCHAR_UNICODE_VALUE(QLatin1Char('j')));
i.setPosition(begin + 29);
QCOMPARE(i.position(), begin + 29);
QCOMPARE(i.peekNext(), 0xFFFDu);
QCOMPARE(i.next(), 0xFFFDu);
QCOMPARE(i.position(), begin + 30);
QCOMPARE(i.peekNext(), QCHAR_UNICODE_VALUE(QLatin1Char('o')));
QCOMPARE(i.next(), QCHAR_UNICODE_VALUE(QLatin1Char('o')));
QCOMPARE(i.position(), begin + 31);
QCOMPARE(i.peekPrevious(), QCHAR_UNICODE_VALUE(QLatin1Char('o')));
QCOMPARE(i.previous(), QCHAR_UNICODE_VALUE(QLatin1Char('o')));
QCOMPARE(i.position(), begin + 30);
QCOMPARE(i.peekPrevious(), 0x10000u);
QCOMPARE(i.previous(), 0x10000u);
QCOMPARE(i.position(), begin + 28);
i.setPosition(begin + 33);
QCOMPARE(i.position(), begin + 33);
QCOMPARE(i.peekNext(), 0xFFFDu);
QCOMPARE(i.next(), 0xFFFDu);
QCOMPARE(i.position(), begin + 34);
QCOMPARE(i.peekNext(), QCHAR_UNICODE_VALUE(QLatin1Char('p')));
QCOMPARE(i.next(), QCHAR_UNICODE_VALUE(QLatin1Char('p')));
QCOMPARE(i.position(), begin + 35);
QCOMPARE(i.peekPrevious(), QCHAR_UNICODE_VALUE(QLatin1Char('p')));
QCOMPARE(i.previous(), QCHAR_UNICODE_VALUE(QLatin1Char('p')));
QCOMPARE(i.position(), begin + 34);
QCOMPARE(i.peekPrevious(), 0x10000u);
QCOMPARE(i.previous(), 0x10000u);
QCOMPARE(i.position(), begin + 32);
i.setPosition(begin + 16);
QCOMPARE(i.position(), begin + 16);
i.recedeUnchecked();
i.recedeUnchecked();
QCOMPARE(i.position(), begin + 12);
i.recedeUnchecked();
i.recedeUnchecked();
i.recedeUnchecked();
i.recedeUnchecked();
QCOMPARE(i.position(), begin + 8);
i.recedeUnchecked();
i.recedeUnchecked();
i.recedeUnchecked();
i.recedeUnchecked();
i.recedeUnchecked();
i.recedeUnchecked();
QCOMPARE(i.position(), begin + 2);
#undef QCHAR_UNICODE_VALUE
}
QTEST_APPLESS_MAIN(tst_QStringIterator)
#include "tst_qstringiterator.moc"

View File

@ -0,0 +1,11 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qstringlist Test:
#####################################################################
qt_internal_add_test(tst_qstringlist
SOURCES
tst_qstringlist.cpp
)

View File

@ -0,0 +1,430 @@
// Copyright (C) 2021 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include <QTest>
#include <qlist.h>
#include <qregularexpression.h>
#include <qstringlist.h>
#include <QScopeGuard>
#include <locale.h>
#include <algorithm>
class tst_QStringList : public QObject
{
Q_OBJECT
private slots:
void constructors();
void sort();
void filter();
void replaceInStrings();
void removeDuplicates();
void removeDuplicates_data();
void contains();
void indexOf_data();
void indexOf();
void lastIndexOf_data();
void lastIndexOf();
void streamingOperator();
void assignmentOperator();
void join() const;
void join_data() const;
void joinEmptiness() const;
void joinChar() const;
void joinChar_data() const;
void initializeList() const;
};
extern const char email[];
void tst_QStringList::constructors()
{
{
QStringList list;
QVERIFY(list.isEmpty());
QCOMPARE(list.size(), 0);
QVERIFY(list == QStringList());
}
{
QString str = "abc";
QStringList list(str);
QVERIFY(!list.isEmpty());
QCOMPARE(list.size(), 1);
QCOMPARE(list.at(0), str);
}
{
QStringList list{ "a", "b", "c" };
QVERIFY(!list.isEmpty());
QCOMPARE(list.size(), 3);
QCOMPARE(list.at(0), "a");
QCOMPARE(list.at(1), "b");
QCOMPARE(list.at(2), "c");
}
{
const QList<QString> reference{ "a", "b", "c" };
QCOMPARE(reference.size(), 3);
QStringList list(reference.cbegin(), reference.cend());
QCOMPARE(list.size(), reference.size());
QVERIFY(std::equal(list.cbegin(), list.cend(), reference.cbegin()));
}
}
void tst_QStringList::indexOf_data()
{
QTest::addColumn<QString>("search");
QTest::addColumn<int>("from");
QTest::addColumn<int>("expectedResult");
QTest::newRow("harald") << "harald" << 0 << 0;
QTest::newRow("trond") << "trond" << 0 << 1;
QTest::newRow("vohi") << "vohi" << 0 << 2;
QTest::newRow("harald-1") << "harald" << 1 << 3;
QTest::newRow("hans") << "hans" << 0 << -1;
QTest::newRow("trond-1") << "trond" << 2 << -1;
QTest::newRow("harald-2") << "harald" << -1 << 3;
QTest::newRow("vohi-1") << "vohi" << -3 << 2;
}
void tst_QStringList::indexOf()
{
QStringList list;
list << "harald" << "trond" << "vohi" << "harald";
QFETCH(QString, search);
QFETCH(int, from);
QFETCH(int, expectedResult);
QCOMPARE(list.indexOf(search, from), expectedResult);
QCOMPARE(list.indexOf(QStringView(search), from), expectedResult);
QCOMPARE(list.indexOf(QLatin1String(search.toLatin1()), from), expectedResult);
}
void tst_QStringList::lastIndexOf_data()
{
QTest::addColumn<QString>("search");
QTest::addColumn<int>("from");
QTest::addColumn<int>("expectedResult");
QTest::newRow("harald") << "harald" << -1 << 3;
QTest::newRow("trond") << "trond" << -1 << 1;
QTest::newRow("vohi") << "vohi" << -1 << 2;
QTest::newRow("harald-1") << "harald" << 2 << 0;
QTest::newRow("hans") << "hans" << -1 << -1;
QTest::newRow("vohi-1") << "vohi" << 1 << -1;
QTest::newRow("vohi-2") << "vohi" << -1 << 2;
QTest::newRow("vohi-3") << "vohi" << -3 << -1;
}
void tst_QStringList::lastIndexOf()
{
QStringList list;
list << "harald" << "trond" << "vohi" << "harald";
QFETCH(QString, search);
QFETCH(int, from);
QFETCH(int, expectedResult);
QCOMPARE(list.lastIndexOf(search, from), expectedResult);
QCOMPARE(list.lastIndexOf(QStringView(search), from), expectedResult);
QCOMPARE(list.lastIndexOf(QLatin1String(search.toLatin1()), from), expectedResult);
}
void tst_QStringList::filter()
{
QStringList list1, list2;
list1 << "Bill Gates" << "Joe Blow" << "Bill Clinton";
list1 = list1.filter( "Bill" );
list2 << "Bill Gates" << "Bill Clinton";
QCOMPARE( list1, list2 );
QStringList list5, list6;
list5 << "Bill Gates" << "Joe Blow" << "Bill Clinton";
list5 = list5.filter( QRegularExpression("[i]ll") );
list6 << "Bill Gates" << "Bill Clinton";
QCOMPARE( list5, list6 );
QStringList list7, list8;
list7 << "Bill Gates" << "Joe Blow" << "Bill Clinton";
list7 = list7.filter( QStringView(QString("Bill")) );
list8 << "Bill Gates" << "Bill Clinton";
QCOMPARE( list7, list8 );
}
void tst_QStringList::sort()
{
QStringList list1, list2;
list1 << "alpha" << "beta" << "BETA" << "gamma" << "Gamma" << "gAmma" << "epsilon";
list1.sort();
list2 << "BETA" << "Gamma" << "alpha" << "beta" << "epsilon" << "gAmma" << "gamma";
QCOMPARE( list1, list2 );
const char *const currentLocale = setlocale(LC_ALL, "C.UTF-8");
if (!currentLocale)
QSKIP("Failed to set C locale, needed for testing");
const QScopeGuard restore([currentLocale]() { setlocale(LC_ALL, currentLocale); });
QStringList list3, list4;
list3 << "alpha" << "beta" << "BETA" << "gamma" << "Gamma" << "gAmma" << "epsilon";
list3.sort(Qt::CaseInsensitive);
list4 << "alpha" << "beta" << "BETA" << "epsilon" << "Gamma" << "gAmma" << "gamma";
// with this list, case insensitive sorting can give more than one permutation for "equivalent"
// elements; so we check that the sort gave the formally correct result (list[i] <= list[i+1])
for (int i = 0; i < list4.size() - 1; ++i)
QVERIFY2(QString::compare(list4.at(i), list4.at(i + 1), Qt::CaseInsensitive) <= 0, qPrintable(QString("index %1 failed").arg(i)));
// additional checks
QCOMPARE(list4.at(0), QString("alpha"));
QVERIFY(list4.indexOf("epsilon") > 0);
QVERIFY(list4.indexOf("epsilon") < (list4.size() - 1));
}
void tst_QStringList::replaceInStrings()
{
QStringList list1, list2;
list1 << "alpha" << "beta" << "gamma" << "epsilon";
list1.replaceInStrings( "a", "o" );
list2 << "olpho" << "beto" << "gommo" << "epsilon";
QCOMPARE( list1, list2 );
QStringList list7, list8;
list7 << "alpha" << "beta" << "gamma" << "epsilon";
list7.replaceInStrings( QRegularExpression("^a"), "o" );
list8 << "olpha" << "beta" << "gamma" << "epsilon";
QCOMPARE( list7, list8 );
QStringList list9, list10;
list9 << "Bill Clinton" << "Gates, Bill";
list10 << "Bill Clinton" << "Bill Gates";
list9.replaceInStrings( QRegularExpression("^(.*), (.*)$"), "\\2 \\1" );
QCOMPARE( list9, list10 );
QStringList list11, list12, list13, list14;
list11 << "alpha" << "beta" << "gamma" << "epsilon";
list12 << "alpha" << "beta" << "gamma" << "epsilon";
list13 << "alpha" << "beta" << "gamma" << "epsilon";
list11.replaceInStrings( QStringView(QString("a")), QStringView(QString("o")) );
list12.replaceInStrings( QStringView(QString("a")), QString("o") );
list13.replaceInStrings( QString("a"), QStringView(QString("o")) );
list14 << "olpho" << "beto" << "gommo" << "epsilon";
QCOMPARE( list11, list12 );
}
void tst_QStringList::contains()
{
QStringList list;
list << "arthur" << "Arthur" << "arthuR" << "ARTHUR" << "Dent" << "Hans Dent";
QVERIFY(list.contains("arthur"));
QVERIFY(!list.contains("ArthuR"));
QVERIFY(!list.contains("Hans"));
QVERIFY(list.contains("arthur", Qt::CaseInsensitive));
QVERIFY(list.contains("ArthuR", Qt::CaseInsensitive));
QVERIFY(list.contains("ARTHUR", Qt::CaseInsensitive));
QVERIFY(list.contains("dent", Qt::CaseInsensitive));
QVERIFY(!list.contains("hans", Qt::CaseInsensitive));
QVERIFY(list.contains(QLatin1String("arthur")));
QVERIFY(!list.contains(QLatin1String("ArthuR")));
QVERIFY(!list.contains(QLatin1String("Hans")));
QVERIFY(list.contains(QLatin1String("arthur"), Qt::CaseInsensitive));
QVERIFY(list.contains(QLatin1String("ArthuR"), Qt::CaseInsensitive));
QVERIFY(list.contains(QLatin1String("ARTHUR"), Qt::CaseInsensitive));
QVERIFY(list.contains(QLatin1String("dent"), Qt::CaseInsensitive));
QVERIFY(!list.contains(QLatin1String("hans"), Qt::CaseInsensitive));
QVERIFY(list.contains(QStringView(QString("arthur"))));
QVERIFY(!list.contains(QStringView(QString("ArthuR"))));
QVERIFY(!list.contains(QStringView(QString("Hans"))));
QVERIFY(list.contains(QStringView(QString("arthur")), Qt::CaseInsensitive));
QVERIFY(list.contains(QStringView(QString("ArthuR")), Qt::CaseInsensitive));
QVERIFY(list.contains(QStringView(QString("ARTHUR")), Qt::CaseInsensitive));
QVERIFY(list.contains(QStringView(QString("dent")), Qt::CaseInsensitive));
QVERIFY(!list.contains(QStringView(QString("hans")), Qt::CaseInsensitive));
}
void tst_QStringList::removeDuplicates_data()
{
QTest::addColumn<QString>("before");
QTest::addColumn<QString>("after");
QTest::addColumn<int>("count");
QTest::addColumn<bool>("detached");
QTest::newRow("empty-1") << "Hello,Hello" << "Hello" << 1 << true;
QTest::newRow("empty-2") << "Hello,World" << "Hello,World" << 0 << false;
QTest::newRow("middle") << "Hello,World,Hello" << "Hello,World" << 1 << true;
}
void tst_QStringList::removeDuplicates()
{
QFETCH(QString, before);
QFETCH(QString, after);
QFETCH(int, count);
QFETCH(bool, detached);
QStringList lbefore = before.split(',');
const QStringList oldlbefore = lbefore;
QStringList lafter = after.split(',');
int removed = lbefore.removeDuplicates();
QCOMPARE(removed, count);
QCOMPARE(lbefore, lafter);
QCOMPARE(detached, !oldlbefore.isSharedWith(lbefore));
}
void tst_QStringList::streamingOperator()
{
QStringList list;
list << "hei";
list << list << "hopp" << list;
QList<QString> slist = list;
list << slist;
QCOMPARE(list, QStringList()
<< "hei" << "hei" << "hopp"
<< "hei" << "hei" << "hopp"
<< "hei" << "hei" << "hopp"
<< "hei" << "hei" << "hopp");
QStringList list2;
list2 << "adam";
QStringList list3;
list3 << "eva";
QCOMPARE(list2 << list3, QStringList() << "adam" << "eva");
}
void tst_QStringList::assignmentOperator()
{
// compile-only test
QStringList adam;
adam << "adam";
QList<QString> eva;
eva << "eva";
QStringList result;
QStringList &ref1 = (result = adam);
QStringList &ref2 = (result = eva);
Q_UNUSED(ref1);
Q_UNUSED(ref2);
}
void tst_QStringList::join() const
{
QFETCH(QStringList, input);
QFETCH(QString, separator);
QFETCH(QString, expectedResult);
QCOMPARE(input.join(separator), expectedResult);
QCOMPARE(input.join(QLatin1String(separator.toLatin1())), expectedResult);
QCOMPARE(input.join(QStringView(separator)), expectedResult);
}
void tst_QStringList::join_data() const
{
QTest::addColumn<QStringList>("input");
QTest::addColumn<QString>("separator");
QTest::addColumn<QString>("expectedResult");
QTest::newRow("data1")
<< QStringList()
<< QString()
<< QString();
QTest::newRow("data2")
<< QStringList()
<< QString(QLatin1String("separator"))
<< QString();
QTest::newRow("data3")
<< QStringList("one")
<< QString(QLatin1String("separator"))
<< QString("one");
QTest::newRow("data4")
<< QStringList("one")
<< QString(QLatin1String("separator"))
<< QString("one");
QTest::newRow("data5")
<< (QStringList()
<< QLatin1String("a")
<< QLatin1String("b"))
<< QString(QLatin1String(" "))
<< QString("a b");
QTest::newRow("data6")
<< (QStringList()
<< QLatin1String("a")
<< QLatin1String("b")
<< QLatin1String("c"))
<< QString(QLatin1String(" "))
<< QString("a b c");
}
void tst_QStringList::joinChar() const
{
QFETCH(QStringList, input);
QFETCH(QChar, separator);
QFETCH(QString, expectedResult);
QCOMPARE(input.join(separator), expectedResult);
}
void tst_QStringList::joinChar_data() const
{
QTest::addColumn<QStringList>("input");
QTest::addColumn<QChar>("separator");
QTest::addColumn<QString>("expectedResult");
QTest::newRow("data1")
<< QStringList()
<< QChar(QLatin1Char(' '))
<< QString();
QTest::newRow("data5")
<< (QStringList()
<< QLatin1String("a")
<< QLatin1String("b"))
<< QChar(QLatin1Char(' '))
<< QString("a b");
QTest::newRow("data6")
<< (QStringList()
<< QLatin1String("a")
<< QLatin1String("b")
<< QLatin1String("c"))
<< QChar(QLatin1Char(' '))
<< QString("a b c");
QTest::newRow("null separator")
<< QStringList{QStringLiteral("a"), QStringLiteral("b"), QStringLiteral("c")}
<< QChar(u'\0')
<< QStringLiteral("a\0b\0c");
}
void tst_QStringList::joinEmptiness() const
{
QStringList list;
QString string = list.join(QString());
QVERIFY(string.isEmpty());
QVERIFY(string.isNull());
}
void tst_QStringList::initializeList() const
{
QStringList v1{QLatin1String("hello"),"world",QString::fromLatin1("plop")};
QCOMPARE(v1, (QStringList() << "hello" << "world" << "plop"));
QCOMPARE(v1, (QStringList{"hello","world","plop"}));
}
QTEST_APPLESS_MAIN(tst_QStringList)
#include "tst_qstringlist.moc"

View File

@ -0,0 +1,13 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qstringmatcher Test:
#####################################################################
qt_internal_add_test(tst_qstringmatcher
SOURCES
tst_qstringmatcher.cpp
DEFINES
QT_NO_CAST_TO_ASCII
)

View File

@ -0,0 +1,151 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include <QTest>
#include <qstringmatcher.h>
class tst_QStringMatcher : public QObject
{
Q_OBJECT
private slots:
void qstringmatcher();
void caseSensitivity();
void indexIn_data();
void indexIn();
void setCaseSensitivity_data();
void setCaseSensitivity();
void assignOperator();
};
void tst_QStringMatcher::qstringmatcher()
{
QStringMatcher matcher;
QCOMPARE(matcher.caseSensitivity(), Qt::CaseSensitive);
QCOMPARE(matcher.indexIn("foo", 1), 1);
QCOMPARE(matcher.pattern(), QString());
}
// public Qt::CaseSensitivity caseSensitivity() const
void tst_QStringMatcher::caseSensitivity()
{
const QString haystack = QStringLiteral("foobarFoo");
const QStringView needle = QStringView{ haystack }.right(3); // "Foo"
QStringMatcher matcher(needle.data(), needle.size());
QCOMPARE(matcher.caseSensitivity(), Qt::CaseSensitive);
QCOMPARE(matcher.indexIn(haystack), 6);
matcher.setCaseSensitivity(Qt::CaseInsensitive);
QCOMPARE(matcher.caseSensitivity(), Qt::CaseInsensitive);
QCOMPARE(matcher.indexIn(haystack), 0);
matcher.setCaseSensitivity(Qt::CaseSensitive);
QCOMPARE(matcher.caseSensitivity(), Qt::CaseSensitive);
QCOMPARE(matcher.indexIn(haystack), 6);
}
void tst_QStringMatcher::indexIn_data()
{
QTest::addColumn<QString>("needle");
QTest::addColumn<QString>("haystack");
QTest::addColumn<int>("from");
QTest::addColumn<int>("indexIn");
QTest::newRow("empty-1") << QString() << QString("foo") << 0 << 0;
QTest::newRow("empty-2") << QString() << QString("foo") << 10 << -1;
QTest::newRow("empty-3") << QString() << QString("foo") << -10 << 0;
QTest::newRow("simple-1") << QString("a") << QString("foo") << 0 << -1;
QTest::newRow("simple-2") << QString("a") << QString("bar") << 0 << 1;
QTest::newRow("harder-1") << QString("foo") << QString("slkdf sldkjf slakjf lskd ffools ldjf") << 0 << 26;
QTest::newRow("harder-2") << QString("foo") << QString("slkdf sldkjf slakjf lskd ffools ldjf") << 20 << 26;
QTest::newRow("harder-3") << QString("foo") << QString("slkdf sldkjf slakjf lskd ffools ldjf") << 26 << 26;
QTest::newRow("harder-4") << QString("foo") << QString("slkdf sldkjf slakjf lskd ffools ldjf") << 27 << -1;
}
void tst_QStringMatcher::indexIn()
{
QFETCH(QString, needle);
QFETCH(QString, haystack);
QFETCH(int, from);
QFETCH(int, indexIn);
QStringMatcher matcher;
matcher.setPattern(needle);
QCOMPARE(matcher.indexIn(haystack, from), indexIn);
const auto needleSV = QStringView(needle);
QStringMatcher matcherSV(needleSV);
QCOMPARE(matcherSV.indexIn(QStringView(haystack), from), indexIn);
}
void tst_QStringMatcher::setCaseSensitivity_data()
{
QTest::addColumn<QString>("needle");
QTest::addColumn<QString>("haystack");
QTest::addColumn<int>("from");
QTest::addColumn<int>("indexIn");
QTest::addColumn<int>("cs");
QTest::newRow("overshot") << QString("foo") << QString("baFooz foo bar") << 14 << -1 << (int) Qt::CaseSensitive;
QTest::newRow("sensitive") << QString("foo") << QString("baFooz foo bar") << 1 << 7 << (int) Qt::CaseSensitive;
QTest::newRow("insensitive-1")
<< QString("foo") << QString("baFooz foo bar") << 0 << 2 << (int)Qt::CaseInsensitive;
QTest::newRow("insensitive-2")
<< QString("foo") << QString("baFooz foo bar") << 1 << 2 << (int)Qt::CaseInsensitive;
QTest::newRow("insensitive-3")
<< QString("foo") << QString("baFooz foo bar") << 4 << 7 << (int)Qt::CaseInsensitive;
QTest::newRow("insensitive-4")
<< QString("foogabooga") << QString("baFooGaBooga foogabooga bar") << 1 << 2
<< (int)Qt::CaseInsensitive;
QTest::newRow("insensitive-5")
<< QString("foogabooga") << QString("baFooGaBooga foogabooga bar") << 3 << 13
<< (int)Qt::CaseInsensitive;
QTest::newRow("insensitive-6") << QString("foogabooga") << QString("GaBoogaFoogaBooga bar") << 0
<< 7 << (int)Qt::CaseInsensitive;
QTest::newRow("insensitive-7") << QString("foogabooga") << QString("FoGaBoogaFoogaBooga") << 9
<< 9 << (int)Qt::CaseInsensitive;
QTest::newRow("insensitive-8") << QString("foogaBooga") << QString("zzzzaazzffoogaBooga") << 0
<< 9 << (int)Qt::CaseInsensitive;
QString stringOf32("abcdefghijklmnopqrstuvwxyz123456");
Q_ASSERT(stringOf32.size() == 32);
QString stringOf128 = stringOf32 + stringOf32 + stringOf32 + stringOf32;
QString needle = stringOf128 + stringOf128 + "CAse";
QString haystack = stringOf128 + stringOf128 + "caSE";
QTest::newRow("insensitive-9") << needle << haystack << 0 << 0 << (int)Qt::CaseInsensitive;
}
void tst_QStringMatcher::setCaseSensitivity()
{
QFETCH(QString, needle);
QFETCH(QString, haystack);
QFETCH(int, from);
QFETCH(int, indexIn);
QFETCH(int, cs);
QStringMatcher matcher;
matcher.setPattern(needle);
matcher.setCaseSensitivity(static_cast<Qt::CaseSensitivity> (cs));
QCOMPARE(matcher.indexIn(haystack, from), indexIn);
QCOMPARE(matcher.indexIn(QStringView(haystack), from), indexIn);
}
void tst_QStringMatcher::assignOperator()
{
QString needle("d");
QString hayStack("abcdef");
QStringMatcher m1(needle);
QCOMPARE(m1.indexIn(hayStack), 3);
QStringMatcher m2 = m1;
QCOMPARE(m2.pattern(), needle);
QCOMPARE(m2.indexIn(hayStack), 3);
}
QTEST_MAIN(tst_QStringMatcher)
#include "tst_qstringmatcher.moc"

View File

@ -0,0 +1,14 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qstringtokenizer Test:
#####################################################################
qt_internal_add_test(tst_qstringtokenizer
SOURCES
tst_qstringtokenizer.cpp
)
## Scopes:
#####################################################################

View File

@ -0,0 +1,139 @@
// Copyright (C) 2020 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Marc Mutz <marc.mutz@kdab.com>
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include <QStringTokenizer>
#include <QStringBuilder>
#include <QTest>
#include <string>
Q_DECLARE_METATYPE(Qt::SplitBehavior)
class tst_QStringTokenizer : public QObject
{
Q_OBJECT
private Q_SLOTS:
void constExpr() const;
void basics_data() const;
void basics() const;
void toContainer() const;
};
static QStringList skipped(const QStringList &sl)
{
QStringList result;
result.reserve(sl.size());
for (const QString &s : sl) {
if (!s.isEmpty())
result.push_back(s);
}
return result;
}
QString toQString(QStringView str)
{
return str.toString();
}
template <typename Container>
QStringList toQStringList(const Container &c)
{
QStringList r;
for (auto &&e : c)
r.push_back(toQString(e));
return r;
}
void tst_QStringTokenizer::constExpr() const
{
// compile-time checks
{
constexpr auto tok = qTokenize(u"a,b,c", u",");
Q_UNUSED(tok);
}
{
constexpr auto tok = qTokenize(u"a,b,c", u',');
Q_UNUSED(tok);
}
}
void tst_QStringTokenizer::basics_data() const
{
QTest::addColumn<Qt::SplitBehavior>("sb");
QTest::addColumn<Qt::CaseSensitivity>("cs");
#define ROW(sb, cs) \
do { QTest::addRow("%s/%s", #sb, #cs) << Qt::SplitBehavior{Qt::sb} << Qt::cs; } while (0)
ROW(KeepEmptyParts, CaseSensitive);
ROW(KeepEmptyParts, CaseInsensitive);
ROW(SkipEmptyParts, CaseSensitive);
ROW(SkipEmptyParts, CaseInsensitive);
#undef ROW
}
void tst_QStringTokenizer::basics() const
{
QFETCH(const Qt::SplitBehavior, sb);
QFETCH(const Qt::CaseSensitivity, cs);
auto expected = QStringList{"", "a", "b", "c", "d", "e", ""};
if (sb & Qt::SkipEmptyParts)
expected = skipped(expected);
QCOMPARE(toQStringList(qTokenize(u",a,b,c,d,e,", u',', sb, cs)), expected);
QCOMPARE(toQStringList(qTokenize(u",a,b,c,d,e,", u',', cs, sb)), expected);
{
auto tok = qTokenize(expected.join(u'x'), u"X" % QString(), Qt::CaseInsensitive);
// the temporary QStrings returned from join() and the QStringBuilder expression
// are now destroyed, but 'tok' should keep both alive
QCOMPARE(toQStringList(tok), expected);
}
using namespace std::string_literals;
{
auto tok = qTokenize(expected.join(u'x'), u"X"s, Qt::CaseInsensitive);
QCOMPARE(toQStringList(tok), expected);
}
{
auto tok = qTokenize(expected.join(u'x'), QLatin1Char('x'), cs, sb);
QCOMPARE(toQStringList(tok), expected);
}
}
void tst_QStringTokenizer::toContainer() const
{
// QStringView value_type:
{
auto tok = qTokenize(u"a,b,c", u',');
auto v = tok.toContainer();
QVERIFY((std::is_same_v<decltype(v), QList<QStringView>>));
}
// QLatin1String value_type
{
auto tok = qTokenize(QLatin1String{"a,b,c"}, u',');
auto v = tok.toContainer();
QVERIFY((std::is_same_v<decltype(v), QList<QLatin1String>>));
}
// QLatin1String value_type into QStringList
{
auto tok = qTokenize(QLatin1String{"a,b,c"}, u',');
QStringList result;
tok.toContainer(result);
QCOMPARE(result, QStringList({"a", "b", "c"}));
}
// QLatin1String value_type into QStringList: rvalue overload
{
QStringList result;
qTokenize(QLatin1String{"a,b,c"}, u',').toContainer(result);
QCOMPARE(result, QStringList({"a", "b", "c"}));
}
}
QTEST_APPLESS_MAIN(tst_QStringTokenizer)
#include "tst_qstringtokenizer.moc"

View File

@ -0,0 +1,16 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qstringview Test:
#####################################################################
qt_internal_add_test(tst_qstringview
SOURCES
tst_qstringview.cpp
LIBRARIES
Qt::CorePrivate
)
## Scopes:
#####################################################################

View File

@ -0,0 +1,883 @@
// Copyright (C) 2020 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Marc Mutz <marc.mutz@kdab.com>
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include <QStringView>
#include <QStringTokenizer>
#include <QString>
#include <QChar>
#include <QVarLengthArray>
#include <QList>
#if QT_CONFIG(cpp_winrt)
# include <private/qt_winrtbase_p.h>
#endif
#include <private/qxmlstream_p.h>
#include <QTest>
#include <string>
#include <string_view>
#include <array>
#include <vector>
#include <algorithm>
#include <memory>
// for negative testing (can't convert from)
#include <deque>
#include <list>
template <typename T>
using CanConvert = std::is_convertible<T, QStringView>;
static_assert(!CanConvert<QLatin1String>::value);
static_assert(!CanConvert<const char*>::value);
static_assert(!CanConvert<QByteArray>::value);
// QStringView qchar_does_not_compile() { return QStringView(QChar('a')); }
// QStringView qlatin1string_does_not_compile() { return QStringView(QLatin1String("a")); }
// QStringView const_char_star_does_not_compile() { return QStringView("a"); }
// QStringView qbytearray_does_not_compile() { return QStringView(QByteArray("a")); }
//
// QChar
//
static_assert(!CanConvert<QChar>::value);
static_assert(CanConvert<QChar[123]>::value);
static_assert(CanConvert< QString >::value);
static_assert(CanConvert<const QString >::value);
static_assert(CanConvert< QString&>::value);
static_assert(CanConvert<const QString&>::value);
//
// ushort
//
static_assert(!CanConvert<ushort>::value);
static_assert(CanConvert<ushort[123]>::value);
static_assert(CanConvert< ushort*>::value);
static_assert(CanConvert<const ushort*>::value);
static_assert(CanConvert<QList<ushort>>::value);
static_assert(CanConvert<QVarLengthArray<ushort>>::value);
static_assert(CanConvert<std::vector<ushort>>::value);
static_assert(CanConvert<std::array<ushort, 123>>::value);
static_assert(!CanConvert<std::deque<ushort>>::value);
static_assert(!CanConvert<std::list<ushort>>::value);
//
// char16_t
//
static_assert(!CanConvert<char16_t>::value);
static_assert(CanConvert< char16_t*>::value);
static_assert(CanConvert<const char16_t*>::value);
static_assert(CanConvert< std::u16string >::value);
static_assert(CanConvert<const std::u16string >::value);
static_assert(CanConvert< std::u16string&>::value);
static_assert(CanConvert<const std::u16string&>::value);
static_assert(CanConvert< std::u16string_view >::value);
static_assert(CanConvert<const std::u16string_view >::value);
static_assert(CanConvert< std::u16string_view&>::value);
static_assert(CanConvert<const std::u16string_view&>::value);
static_assert(CanConvert<QList<char16_t>>::value);
static_assert(CanConvert<QVarLengthArray<char16_t>>::value);
static_assert(CanConvert<std::vector<char16_t>>::value);
static_assert(CanConvert<std::array<char16_t, 123>>::value);
static_assert(!CanConvert<std::deque<char16_t>>::value);
static_assert(!CanConvert<std::list<char16_t>>::value);
static_assert(CanConvert<QtPrivate::XmlStringRef>::value);
//
// wchar_t
//
constexpr bool CanConvertFromWCharT =
#ifdef Q_OS_WIN
true
#else
false
#endif
;
static_assert(!CanConvert<wchar_t>::value);
static_assert(CanConvert< wchar_t*>::value == CanConvertFromWCharT);
static_assert(CanConvert<const wchar_t*>::value == CanConvertFromWCharT);
static_assert(CanConvert< std::wstring >::value == CanConvertFromWCharT);
static_assert(CanConvert<const std::wstring >::value == CanConvertFromWCharT);
static_assert(CanConvert< std::wstring&>::value == CanConvertFromWCharT);
static_assert(CanConvert<const std::wstring&>::value == CanConvertFromWCharT);
static_assert(CanConvert< std::wstring_view >::value == CanConvertFromWCharT);
static_assert(CanConvert<const std::wstring_view >::value == CanConvertFromWCharT);
static_assert(CanConvert< std::wstring_view&>::value == CanConvertFromWCharT);
static_assert(CanConvert<const std::wstring_view&>::value == CanConvertFromWCharT);
static_assert(CanConvert<QList<wchar_t>>::value == CanConvertFromWCharT);
static_assert(CanConvert<QVarLengthArray<wchar_t>>::value == CanConvertFromWCharT);
static_assert(CanConvert<std::vector<wchar_t>>::value == CanConvertFromWCharT);
static_assert(CanConvert<std::array<wchar_t, 123>>::value == CanConvertFromWCharT);
static_assert(!CanConvert<std::deque<wchar_t>>::value);
static_assert(!CanConvert<std::list<wchar_t>>::value);
#if QT_CONFIG(cpp_winrt)
//
// winrt::hstring (QTBUG-111886)
//
static_assert(CanConvert< winrt::hstring >::value);
static_assert(CanConvert<const winrt::hstring >::value);
static_assert(CanConvert< winrt::hstring&>::value);
static_assert(CanConvert<const winrt::hstring&>::value);
#endif // QT_CONFIG(cpp_winrt)
class tst_QStringView : public QObject
{
Q_OBJECT
private Q_SLOTS:
void constExpr() const;
void basics() const;
void literals() const;
void fromArray() const;
void at() const;
void arg() const;
void fromQString() const;
void fromQCharStar() const
{
const QChar str[] = { 'H', 'e', 'l', 'l', 'o', ',', ' ', 'W', 'o', 'r', 'l', 'd', '!', '\0' };
fromLiteral(str);
}
void fromUShortStar() const
{
const ushort str[] = { 'H', 'e', 'l', 'l', 'o', ',', ' ', 'W', 'o', 'r', 'l', 'd', '!', '\0' };
fromLiteral(str);
}
void fromChar16TStar() const
{
fromLiteral(u"Hello, World!");
}
void fromWCharTStar() const
{
#ifdef Q_OS_WIN
fromLiteral(L"Hello, World!");
#else
QSKIP("This is a Windows-only test");
#endif
}
void fromQCharRange() const
{
const QChar str[] = { 'H', 'e', 'l', 'l', 'o', ',', ' ', 'W', 'o', 'r', 'l', 'd', '!' };
fromRange(std::begin(str), std::end(str));
}
void fromUShortRange() const
{
const ushort str[] = { 'H', 'e', 'l', 'l', 'o', ',', ' ', 'W', 'o', 'r', 'l', 'd', '!' };
fromRange(std::begin(str), std::end(str));
}
void fromChar16TRange() const
{
const char16_t str[] = { 'H', 'e', 'l', 'l', 'o', ',', ' ', 'W', 'o', 'r', 'l', 'd', '!' };
fromRange(std::begin(str), std::end(str));
}
void fromWCharTRange() const
{
#ifdef Q_OS_WIN
const wchar_t str[] = { 'H', 'e', 'l', 'l', 'o', ',', ' ', 'W', 'o', 'r', 'l', 'd', '!' };
fromRange(std::begin(str), std::end(str));
#else
QSKIP("This is a Windows-only test");
#endif
}
// std::basic_string
void fromStdStringWCharT() const
{
#ifdef Q_OS_WIN
fromStdString<wchar_t>();
#else
QSKIP("This is a Windows-only test");
#endif
}
void fromStdStringChar16T() const
{
fromStdString<char16_t>();
}
void fromUShortContainers() const
{
fromContainers<ushort>();
}
void fromQCharContainers() const
{
fromContainers<QChar>();
}
void fromChar16TContainers() const
{
fromContainers<char16_t>();
}
void fromWCharTContainers() const
{
#ifdef Q_OS_WIN
fromContainers<wchar_t>();
#else
QSKIP("This is a Windows-only test");
#endif
}
void comparison();
void overloadResolution();
void tokenize_data() const;
void tokenize() const;
private:
template <typename String>
void conversion_tests(String arg) const;
template <typename Char>
void fromLiteral(const Char *arg) const;
template <typename Char>
void fromRange(const Char *first, const Char *last) const;
template <typename Char, typename Container>
void fromContainer() const;
template <typename Char>
void fromContainers() const;
template <typename Char>
void fromStdString() const { fromContainer<Char, std::basic_string<Char> >(); }
};
void tst_QStringView::constExpr() const
{
// compile-time checks
{
constexpr QStringView sv;
static_assert(sv.size() == 0);
static_assert(sv.isNull());
static_assert(sv.empty());
static_assert(sv.isEmpty());
static_assert(sv.utf16() == nullptr);
constexpr QStringView sv2(sv.utf16(), sv.utf16() + sv.size());
static_assert(sv2.isNull());
static_assert(sv2.empty());
}
{
constexpr QStringView sv = nullptr;
Q_STATIC_ASSERT(sv.size() == 0);
Q_STATIC_ASSERT(sv.isNull());
Q_STATIC_ASSERT(sv.empty());
Q_STATIC_ASSERT(sv.isEmpty());
Q_STATIC_ASSERT(sv.utf16() == nullptr);
}
{
constexpr QStringView sv = u"";
static_assert(sv.size() == 0);
static_assert(!sv.isNull());
static_assert(sv.empty());
static_assert(sv.isEmpty());
static_assert(sv.utf16() != nullptr);
constexpr QStringView sv2(sv.utf16(), sv.utf16() + sv.size());
static_assert(!sv2.isNull());
static_assert(sv2.empty());
}
{
constexpr QStringView sv = u"Hello";
static_assert(sv.size() == 5);
static_assert(!sv.empty());
static_assert(!sv.isEmpty());
static_assert(!sv.isNull());
static_assert(*sv.utf16() == 'H');
static_assert(sv[0] == QLatin1Char('H'));
static_assert(sv.at(0) == QLatin1Char('H'));
static_assert(sv.front() == QLatin1Char('H'));
static_assert(sv.first() == QLatin1Char('H'));
static_assert(sv[4] == QLatin1Char('o'));
static_assert(sv.at(4) == QLatin1Char('o'));
static_assert(sv.back() == QLatin1Char('o'));
static_assert(sv.last() == QLatin1Char('o'));
constexpr QStringView sv2(sv.utf16(), sv.utf16() + sv.size());
static_assert(!sv2.isNull());
static_assert(!sv2.empty());
static_assert(sv2.size() == 5);
}
{
static_assert(QStringView(u"Hello").size() == 5);
constexpr QStringView sv = u"Hello";
static_assert(sv.size() == 5);
static_assert(!sv.empty());
static_assert(!sv.isEmpty());
static_assert(!sv.isNull());
static_assert(*sv.utf16() == 'H');
static_assert(sv[0] == QLatin1Char('H'));
static_assert(sv.at(0) == QLatin1Char('H'));
static_assert(sv.front() == QLatin1Char('H'));
static_assert(sv.first() == QLatin1Char('H'));
static_assert(sv[4] == QLatin1Char('o'));
static_assert(sv.at(4) == QLatin1Char('o'));
static_assert(sv.back() == QLatin1Char('o'));
static_assert(sv.last() == QLatin1Char('o'));
constexpr QStringView sv2(sv.utf16(), sv.utf16() + sv.size());
static_assert(!sv2.isNull());
static_assert(!sv2.empty());
static_assert(sv2.size() == 5);
constexpr char16_t *null = nullptr;
constexpr QStringView sv3(null);
static_assert(sv3.isNull());
static_assert(sv3.isEmpty());
static_assert(sv3.size() == 0);
}
}
void tst_QStringView::basics() const
{
QStringView sv1;
// a default-constructed QStringView is null:
QVERIFY(sv1.isNull());
// which implies it's empty();
QVERIFY(sv1.isEmpty());
QStringView sv2;
QVERIFY(sv2 == sv1);
QVERIFY(!(sv2 != sv1));
}
void tst_QStringView::literals() const
{
const char16_t hello[] = u"Hello";
const char16_t longhello[] =
u"Hello World. This is a much longer message, to exercise qustrlen.";
const char16_t withnull[] = u"a\0zzz";
static_assert(sizeof(longhello) >= 16);
QCOMPARE(QStringView(hello).size(), 5);
QCOMPARE(QStringView(hello + 0).size(), 5); // forces decay to pointer
QStringView sv = hello;
QCOMPARE(sv.size(), 5);
QVERIFY(!sv.empty());
QVERIFY(!sv.isEmpty());
QVERIFY(!sv.isNull());
QCOMPARE(*sv.utf16(), 'H');
QCOMPARE(sv[0], QLatin1Char('H'));
QCOMPARE(sv.at(0), QLatin1Char('H'));
QCOMPARE(sv.front(), QLatin1Char('H'));
QCOMPARE(sv.first(), QLatin1Char('H'));
QCOMPARE(sv[4], QLatin1Char('o'));
QCOMPARE(sv.at(4), QLatin1Char('o'));
QCOMPARE(sv.back(), QLatin1Char('o'));
QCOMPARE(sv.last(), QLatin1Char('o'));
QStringView sv2(sv.utf16(), sv.utf16() + sv.size());
QVERIFY(!sv2.isNull());
QVERIFY(!sv2.empty());
QCOMPARE(sv2.size(), 5);
QStringView sv3(longhello);
QCOMPARE(size_t(sv3.size()), sizeof(longhello)/sizeof(longhello[0]) - 1);
QCOMPARE(sv3.last(), QLatin1Char('.'));
sv3 = longhello;
QCOMPARE(size_t(sv3.size()), sizeof(longhello)/sizeof(longhello[0]) - 1);
for (int i = 0; i < sv3.size(); ++i) {
QStringView sv4(longhello + i);
QCOMPARE(size_t(sv4.size()), sizeof(longhello)/sizeof(longhello[0]) - 1 - i);
QCOMPARE(sv4.last(), QLatin1Char('.'));
sv4 = longhello + i;
QCOMPARE(size_t(sv4.size()), sizeof(longhello)/sizeof(longhello[0]) - 1 - i);
}
// these are different results
QCOMPARE(size_t(QStringView(withnull).size()), size_t(1));
QCOMPARE(size_t(QStringView::fromArray(withnull).size()), sizeof(withnull)/sizeof(withnull[0]));
QCOMPARE(QStringView(withnull + 0).size(), qsizetype(1));
}
void tst_QStringView::fromArray() const
{
static constexpr char16_t hello[] = u"Hello\0abc\0\0.";
constexpr QStringView sv = QStringView::fromArray(hello);
QCOMPARE(sv.size(), 13);
QVERIFY(!sv.empty());
QVERIFY(!sv.isEmpty());
QVERIFY(!sv.isNull());
QCOMPARE(*sv.data(), 'H');
QCOMPARE(sv[0], 'H');
QCOMPARE(sv.at(0), 'H');
QCOMPARE(sv.front(), 'H');
QCOMPARE(sv.first(), 'H');
QCOMPARE(sv[4], 'o');
QCOMPARE(sv.at(4), 'o');
QCOMPARE(sv[5], '\0');
QCOMPARE(sv.at(5), '\0');
QCOMPARE(*(sv.data() + sv.size() - 2), '.');
QCOMPARE(sv.back(), '\0');
QCOMPARE(sv.last(), '\0');
const char16_t bytes[] = {u'a', u'b', u'c'};
QStringView sv2 = QStringView::fromArray(bytes);
QCOMPARE(sv2.data(), reinterpret_cast<const QChar *>(bytes + 0));
QCOMPARE(sv2.size(), 3);
QCOMPARE(sv2.first(), u'a');
QCOMPARE(sv2.last(), u'c');
}
void tst_QStringView::at() const
{
QString hello("Hello");
QStringView sv(hello);
QCOMPARE(sv.at(0), QChar('H')); QCOMPARE(sv[0], QChar('H'));
QCOMPARE(sv.at(1), QChar('e')); QCOMPARE(sv[1], QChar('e'));
QCOMPARE(sv.at(2), QChar('l')); QCOMPARE(sv[2], QChar('l'));
QCOMPARE(sv.at(3), QChar('l')); QCOMPARE(sv[3], QChar('l'));
QCOMPARE(sv.at(4), QChar('o')); QCOMPARE(sv[4], QChar('o'));
}
void tst_QStringView::arg() const
{
#define CHECK1(pattern, arg1, expected) \
do { \
auto p = QStringView(u"" pattern); \
QCOMPARE(p.arg(QLatin1String(arg1)), expected); \
QCOMPARE(p.arg(u"" arg1), expected); \
QCOMPARE(p.arg(QStringLiteral(arg1)), expected); \
QCOMPARE(p.arg(QString(QLatin1String(arg1))), expected); \
} while (false) \
/*end*/
#define CHECK2(pattern, arg1, arg2, expected) \
do { \
auto p = QStringView(u"" pattern); \
QCOMPARE(p.arg(QLatin1String(arg1), QLatin1String(arg2)), expected); \
QCOMPARE(p.arg(u"" arg1, QLatin1String(arg2)), expected); \
QCOMPARE(p.arg(QLatin1String(arg1), u"" arg2), expected); \
QCOMPARE(p.arg(u"" arg1, u"" arg2), expected); \
} while (false) \
/*end*/
CHECK1("", "World", "");
CHECK1("%1", "World", "World");
CHECK1("!%1?", "World", "!World?");
CHECK1("%1%1", "World", "WorldWorld");
CHECK1("%1%2", "World", "World%2");
CHECK1("%2%1", "World", "%2World");
CHECK2("", "Hello", "World", "");
CHECK2("%1", "Hello", "World", "Hello");
CHECK2("!%1, %2?", "Hello", "World", "!Hello, World?");
CHECK2("%1%1", "Hello", "World", "HelloHello");
CHECK2("%1%2", "Hello", "World", "HelloWorld");
CHECK2("%2%1", "Hello", "World", "WorldHello");
#undef CHECK2
#undef CHECK1
QCOMPARE(QStringView(u" %2 %2 %1 %3 ").arg(QLatin1Char('c'), QChar::CarriageReturn, u'C'), " \r \r c C ");
}
void tst_QStringView::fromQString() const
{
QString null;
QString empty = "";
QVERIFY( QStringView(null).isNull());
QVERIFY( QStringView(null).isEmpty());
QVERIFY( QStringView(empty).isEmpty());
QVERIFY(!QStringView(empty).isNull());
conversion_tests(QString("Hello World!"));
}
void tst_QStringView::tokenize_data() const
{
// copied from tst_QString
QTest::addColumn<QString>("str");
QTest::addColumn<QString>("sep");
QTest::addColumn<QStringList>("result");
QTest::newRow("1") << "a,b,c" << "," << (QStringList() << "a" << "b" << "c");
QTest::newRow("2") << QString("-rw-r--r-- 1 0 0 519240 Jul 9 2002 bigfile")
<< " "
<< (QStringList() << "-rw-r--r--" << "" << "1" << "0" << "" << "0" << ""
<< "519240" << "Jul" << "" << "9" << "" << "2002"
<< "bigfile");
QTest::newRow("one-empty") << "" << " " << (QStringList() << "");
QTest::newRow("two-empty") << " " << " " << (QStringList() << "" << "");
QTest::newRow("three-empty") << " " << " " << (QStringList() << "" << "" << "");
QTest::newRow("all-empty") << "" << "" << (QStringList() << "" << "");
QTest::newRow("sep-empty") << "abc" << "" << (QStringList() << "" << "a" << "b" << "c" << "");
}
void tst_QStringView::tokenize() const
{
QFETCH(const QString, str);
QFETCH(const QString, sep);
QFETCH(const QStringList, result);
// lvalue QString
{
auto rit = result.cbegin();
for (auto sv : QStringTokenizer{str, sep})
QCOMPARE(sv, *rit++);
}
{
auto rit = result.cbegin();
for (auto sv : QStringView{str}.tokenize(sep))
QCOMPARE(sv, *rit++);
}
// rvalue QString
{
auto rit = result.cbegin();
for (auto sv : QStringTokenizer{str, QString{sep}})
QCOMPARE(sv, *rit++);
}
{
auto rit = result.cbegin();
for (auto sv : QStringView{str}.tokenize(QString{sep}))
QCOMPARE(sv, *rit++);
}
// (rvalue) QChar
if (sep.size() == 1) {
auto rit = result.cbegin();
for (auto sv : QStringTokenizer{str, sep.front()})
QCOMPARE(sv, *rit++);
}
if (sep.size() == 1) {
auto rit = result.cbegin();
for (auto sv : QStringView{str}.tokenize(sep.front()))
QCOMPARE(sv, *rit++);
}
// (rvalue) char16_t
if (sep.size() == 1) {
auto rit = result.cbegin();
for (auto sv : QStringTokenizer{str, *qToStringViewIgnoringNull(sep).utf16()})
QCOMPARE(sv, *rit++);
}
if (sep.size() == 1) {
auto rit = result.cbegin();
for (auto sv : QStringView{str}.tokenize(*qToStringViewIgnoringNull(sep).utf16()))
QCOMPARE(sv, *rit++);
}
// char16_t literal
const auto make_literal = [](const QString &sep) {
auto literal = std::make_unique<char16_t[]>(sep.size() + 1);
const auto to_char16_t = [](QChar c) { return char16_t{c.unicode()}; };
std::transform(sep.cbegin(), sep.cend(), literal.get(), to_char16_t);
return literal;
};
const std::unique_ptr<const char16_t[]> literal = make_literal(sep);
{
auto rit = result.cbegin();
for (auto sv : QStringTokenizer{str, literal.get()})
QCOMPARE(sv, *rit++);
}
{
auto rit = result.cbegin();
for (auto sv : QStringView{str}.tokenize(literal.get()))
QCOMPARE(sv, *rit++);
}
#ifdef __cpp_lib_ranges
// lvalue QString
{
QStringList actual;
const QStringTokenizer tok{str, sep};
std::ranges::transform(tok, std::back_inserter(actual),
[](auto sv) { return sv.toString(); });
QCOMPARE(result, actual);
}
// rvalue QString
{
QStringList actual;
const QStringTokenizer tok{str, QString{sep}};
std::ranges::transform(tok, std::back_inserter(actual),
[](auto sv) { return sv.toString(); });
QCOMPARE(result, actual);
}
// (rvalue) QChar
if (sep.size() == 1) {
QStringList actual;
const QStringTokenizer tok{str, sep.front()};
std::ranges::transform(tok, std::back_inserter(actual),
[](auto sv) { return sv.toString(); });
QCOMPARE(result, actual);
}
#endif // __cpp_lib_ranges
}
template <typename Char>
void tst_QStringView::fromLiteral(const Char *arg) const
{
const Char *null = nullptr;
const Char empty[] = { Char{} };
QCOMPARE(QStringView(null).size(), qsizetype(0));
QCOMPARE(QStringView(null).data(), nullptr);
QCOMPARE(QStringView(empty).size(), qsizetype(0));
QCOMPARE(static_cast<const void*>(QStringView(empty).data()),
static_cast<const void*>(empty));
QVERIFY( QStringView(null).isNull());
QVERIFY( QStringView(null).isEmpty());
QVERIFY( QStringView(empty).isEmpty());
QVERIFY(!QStringView(empty).isNull());
conversion_tests(arg);
}
template <typename Char>
void tst_QStringView::fromRange(const Char *first, const Char *last) const
{
const Char *null = nullptr;
QCOMPARE(QStringView(null, null).size(), 0);
QCOMPARE(QStringView(null, null).data(), nullptr);
QCOMPARE(QStringView(first, first).size(), 0);
QCOMPARE(static_cast<const void*>(QStringView(first, first).data()),
static_cast<const void*>(first));
const auto sv = QStringView(first, last);
QCOMPARE(sv.size(), last - first);
QCOMPARE(static_cast<const void*>(sv.data()),
static_cast<const void*>(first));
// can't call conversion_tests() here, as it requires a single object
}
template <typename Char, typename Container>
void tst_QStringView::fromContainer() const
{
const QString s = "Hello World!";
Container c;
// unspecified whether empty containers make null QStringViews
QVERIFY(QStringView(c).isEmpty());
QCOMPARE(sizeof(Char), sizeof(QChar));
const auto *data = reinterpret_cast<const Char *>(s.utf16());
std::copy(data, data + s.size(), std::back_inserter(c));
conversion_tests(std::move(c));
}
template <typename Char>
void tst_QStringView::fromContainers() const
{
fromContainer<Char, QList<Char>>();
fromContainer<Char, QVarLengthArray<Char>>();
fromContainer<Char, std::vector<Char>>();
}
namespace help {
template <typename T>
size_t size(const T &t) { return size_t(t.size()); }
template <typename T>
size_t size(const T *t)
{
size_t result = 0;
if (t) {
while (*t++)
++result;
}
return result;
}
size_t size(const QChar *t)
{
size_t result = 0;
if (t) {
while (!t++->isNull())
++result;
}
return result;
}
template <typename T>
decltype(auto) cbegin(const T &t) { return t.begin(); }
template <typename T>
const T * cbegin(const T *t) { return t; }
template <typename T>
decltype(auto) cend(const T &t) { return t.end(); }
template <typename T>
const T * cend(const T *t) { return t + size(t); }
template <typename T>
decltype(auto) crbegin(const T &t) { return t.rbegin(); }
template <typename T>
std::reverse_iterator<const T*> crbegin(const T *t) { return std::reverse_iterator<const T*>(cend(t)); }
template <typename T>
decltype(auto) crend(const T &t) { return t.rend(); }
template <typename T>
std::reverse_iterator<const T*> crend(const T *t) { return std::reverse_iterator<const T*>(cbegin(t)); }
} // namespace help
template <typename String>
void tst_QStringView::conversion_tests(String string) const
{
// copy-construct:
{
QStringView sv = string;
QCOMPARE(help::size(sv), help::size(string));
// check iterators:
QVERIFY(std::equal(help::cbegin(string), help::cend(string),
QT_MAKE_CHECKED_ARRAY_ITERATOR(sv.cbegin(), sv.size())));
QVERIFY(std::equal(help::cbegin(string), help::cend(string),
QT_MAKE_CHECKED_ARRAY_ITERATOR(sv.begin(), sv.size())));
QVERIFY(std::equal(help::crbegin(string), help::crend(string),
sv.crbegin()));
QVERIFY(std::equal(help::crbegin(string), help::crend(string),
sv.rbegin()));
QCOMPARE(sv, string);
}
QStringView sv;
// copy-assign:
{
sv = string;
QCOMPARE(help::size(sv), help::size(string));
// check relational operators:
QCOMPARE(sv, string);
QCOMPARE(string, sv);
QVERIFY(!(sv != string));
QVERIFY(!(string != sv));
QVERIFY(!(sv < string));
QVERIFY(sv <= string);
QVERIFY(!(sv > string));
QVERIFY(sv >= string);
QVERIFY(!(string < sv));
QVERIFY(string <= sv);
QVERIFY(!(string > sv));
QVERIFY(string >= sv);
}
// copy-construct from rvalue (QStringView never assumes ownership):
{
QStringView sv2 = std::move(string);
QCOMPARE(sv2, sv);
QCOMPARE(sv2, string);
}
// copy-assign from rvalue (QStringView never assumes ownership):
{
QStringView sv2;
sv2 = std::move(string);
QCOMPARE(sv2, sv);
QCOMPARE(sv2, string);
}
}
void tst_QStringView::comparison()
{
const QStringView aa = u"aa";
const QStringView upperAa = u"AA";
const QStringView bb = u"bb";
QVERIFY(aa == aa);
QVERIFY(aa != bb);
QVERIFY(aa < bb);
QVERIFY(bb > aa);
QCOMPARE(aa.compare(aa), 0);
QVERIFY(aa.compare(upperAa) != 0);
QCOMPARE(aa.compare(upperAa, Qt::CaseInsensitive), 0);
QVERIFY(aa.compare(bb) < 0);
QVERIFY(bb.compare(aa) > 0);
}
namespace QStringViewOverloadResolution {
static void test(QString) = delete;
static void test(QStringView) {}
}
// Compile-time only test: overload resolution prefers QStringView over QString
void tst_QStringView::overloadResolution()
{
{
QChar qcharArray[42] = {};
QStringViewOverloadResolution::test(qcharArray);
QChar *qcharPointer = qcharArray;
QStringViewOverloadResolution::test(qcharPointer);
}
{
ushort ushortArray[42] = {};
QStringViewOverloadResolution::test(ushortArray);
ushort *ushortPointer = ushortArray;
QStringViewOverloadResolution::test(ushortPointer);
}
#if defined(Q_OS_WIN)
{
wchar_t wchartArray[42] = {};
QStringViewOverloadResolution::test(wchartArray);
QStringViewOverloadResolution::test(L"test");
}
#endif
{
char16_t char16Array[] = u"test";
QStringViewOverloadResolution::test(char16Array);
char16_t *char16Pointer = char16Array;
QStringViewOverloadResolution::test(char16Pointer);
}
{
std::u16string string;
QStringViewOverloadResolution::test(string);
QStringViewOverloadResolution::test(std::as_const(string));
QStringViewOverloadResolution::test(std::move(string));
}
}
QTEST_APPLESS_MAIN(tst_QStringView)
#include "tst_qstringview.moc"

View File

@ -0,0 +1,18 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qtextboundaryfinder Test:
#####################################################################
# Collect test data
file(GLOB_RECURSE test_data
RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
data/*
)
qt_internal_add_test(tst_qtextboundaryfinder
SOURCES
tst_qtextboundaryfinder.cpp
TESTDATA ${test_data}
)

View File

@ -0,0 +1,630 @@
# GraphemeBreakTest-15.0.0.txt
# Date: 2022-02-26, 00:38:37 GMT
# © 2022 Unicode®, Inc.
# Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries.
# For terms of use, see https://www.unicode.org/terms_of_use.html
#
# Unicode Character Database
# For documentation, see https://www.unicode.org/reports/tr44/
#
# Default Grapheme_Cluster_Break Test
#
# Format:
# <string> (# <comment>)?
# <string> contains hex Unicode code points, with
# ÷ wherever there is a break opportunity, and
# × wherever there is not.
# <comment> the format can change, but currently it shows:
# - the sample character name
# - (x) the Grapheme_Cluster_Break property value for the sample character
# - [x] the rule that determines whether there is a break or not,
# as listed in the Rules section of GraphemeBreakTest.html
#
# These samples may be extended or changed in the future.
#
÷ 0020 ÷ 0020 ÷ # ÷ [0.2] SPACE (Other) ÷ [999.0] SPACE (Other) ÷ [0.3]
÷ 0020 × 0308 ÷ 0020 ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3]
÷ 0020 ÷ 000D ÷ # ÷ [0.2] SPACE (Other) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
÷ 0020 × 0308 ÷ 000D ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
÷ 0020 ÷ 000A ÷ # ÷ [0.2] SPACE (Other) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
÷ 0020 × 0308 ÷ 000A ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
÷ 0020 ÷ 0001 ÷ # ÷ [0.2] SPACE (Other) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
÷ 0020 × 0308 ÷ 0001 ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
÷ 0020 × 034F ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3]
÷ 0020 × 0308 × 034F ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3]
÷ 0020 ÷ 1F1E6 ÷ # ÷ [0.2] SPACE (Other) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
÷ 0020 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
÷ 0020 ÷ 0600 ÷ # ÷ [0.2] SPACE (Other) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
÷ 0020 × 0308 ÷ 0600 ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
÷ 0020 × 0903 ÷ # ÷ [0.2] SPACE (Other) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
÷ 0020 × 0308 × 0903 ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
÷ 0020 ÷ 1100 ÷ # ÷ [0.2] SPACE (Other) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
÷ 0020 × 0308 ÷ 1100 ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
÷ 0020 ÷ 1160 ÷ # ÷ [0.2] SPACE (Other) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
÷ 0020 × 0308 ÷ 1160 ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
÷ 0020 ÷ 11A8 ÷ # ÷ [0.2] SPACE (Other) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
÷ 0020 × 0308 ÷ 11A8 ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
÷ 0020 ÷ AC00 ÷ # ÷ [0.2] SPACE (Other) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
÷ 0020 × 0308 ÷ AC00 ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
÷ 0020 ÷ AC01 ÷ # ÷ [0.2] SPACE (Other) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
÷ 0020 × 0308 ÷ AC01 ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
÷ 0020 ÷ 231A ÷ # ÷ [0.2] SPACE (Other) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
÷ 0020 × 0308 ÷ 231A ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
÷ 0020 × 0300 ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3]
÷ 0020 × 0308 × 0300 ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3]
÷ 0020 × 200D ÷ # ÷ [0.2] SPACE (Other) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3]
÷ 0020 × 0308 × 200D ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3]
÷ 0020 ÷ 0378 ÷ # ÷ [0.2] SPACE (Other) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
÷ 0020 × 0308 ÷ 0378 ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
÷ 000D ÷ 0020 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] SPACE (Other) ÷ [0.3]
÷ 000D ÷ 0308 ÷ 0020 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3]
÷ 000D ÷ 000D ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
÷ 000D ÷ 0308 ÷ 000D ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
÷ 000D × 000A ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) × [3.0] <LINE FEED (LF)> (LF) ÷ [0.3]
÷ 000D ÷ 0308 ÷ 000A ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
÷ 000D ÷ 0001 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] <START OF HEADING> (Control) ÷ [0.3]
÷ 000D ÷ 0308 ÷ 0001 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
÷ 000D ÷ 034F ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3]
÷ 000D ÷ 0308 × 034F ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3]
÷ 000D ÷ 1F1E6 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
÷ 000D ÷ 0308 ÷ 1F1E6 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
÷ 000D ÷ 0600 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
÷ 000D ÷ 0308 ÷ 0600 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
÷ 000D ÷ 0903 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
÷ 000D ÷ 0308 × 0903 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
÷ 000D ÷ 1100 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
÷ 000D ÷ 0308 ÷ 1100 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
÷ 000D ÷ 1160 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
÷ 000D ÷ 0308 ÷ 1160 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
÷ 000D ÷ 11A8 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
÷ 000D ÷ 0308 ÷ 11A8 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
÷ 000D ÷ AC00 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
÷ 000D ÷ 0308 ÷ AC00 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
÷ 000D ÷ AC01 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
÷ 000D ÷ 0308 ÷ AC01 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
÷ 000D ÷ 231A ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] WATCH (ExtPict) ÷ [0.3]
÷ 000D ÷ 0308 ÷ 231A ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
÷ 000D ÷ 0300 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3]
÷ 000D ÷ 0308 × 0300 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3]
÷ 000D ÷ 200D ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3]
÷ 000D ÷ 0308 × 200D ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3]
÷ 000D ÷ 0378 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] <reserved-0378> (Other) ÷ [0.3]
÷ 000D ÷ 0308 ÷ 0378 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
÷ 000A ÷ 0020 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] SPACE (Other) ÷ [0.3]
÷ 000A ÷ 0308 ÷ 0020 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3]
÷ 000A ÷ 000D ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
÷ 000A ÷ 0308 ÷ 000D ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
÷ 000A ÷ 000A ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] <LINE FEED (LF)> (LF) ÷ [0.3]
÷ 000A ÷ 0308 ÷ 000A ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
÷ 000A ÷ 0001 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] <START OF HEADING> (Control) ÷ [0.3]
÷ 000A ÷ 0308 ÷ 0001 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
÷ 000A ÷ 034F ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3]
÷ 000A ÷ 0308 × 034F ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3]
÷ 000A ÷ 1F1E6 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
÷ 000A ÷ 0308 ÷ 1F1E6 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
÷ 000A ÷ 0600 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
÷ 000A ÷ 0308 ÷ 0600 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
÷ 000A ÷ 0903 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
÷ 000A ÷ 0308 × 0903 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
÷ 000A ÷ 1100 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
÷ 000A ÷ 0308 ÷ 1100 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
÷ 000A ÷ 1160 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
÷ 000A ÷ 0308 ÷ 1160 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
÷ 000A ÷ 11A8 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
÷ 000A ÷ 0308 ÷ 11A8 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
÷ 000A ÷ AC00 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
÷ 000A ÷ 0308 ÷ AC00 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
÷ 000A ÷ AC01 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
÷ 000A ÷ 0308 ÷ AC01 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
÷ 000A ÷ 231A ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] WATCH (ExtPict) ÷ [0.3]
÷ 000A ÷ 0308 ÷ 231A ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
÷ 000A ÷ 0300 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3]
÷ 000A ÷ 0308 × 0300 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3]
÷ 000A ÷ 200D ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3]
÷ 000A ÷ 0308 × 200D ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3]
÷ 000A ÷ 0378 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] <reserved-0378> (Other) ÷ [0.3]
÷ 000A ÷ 0308 ÷ 0378 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
÷ 0001 ÷ 0020 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] SPACE (Other) ÷ [0.3]
÷ 0001 ÷ 0308 ÷ 0020 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3]
÷ 0001 ÷ 000D ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
÷ 0001 ÷ 0308 ÷ 000D ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
÷ 0001 ÷ 000A ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] <LINE FEED (LF)> (LF) ÷ [0.3]
÷ 0001 ÷ 0308 ÷ 000A ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
÷ 0001 ÷ 0001 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] <START OF HEADING> (Control) ÷ [0.3]
÷ 0001 ÷ 0308 ÷ 0001 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
÷ 0001 ÷ 034F ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3]
÷ 0001 ÷ 0308 × 034F ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3]
÷ 0001 ÷ 1F1E6 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
÷ 0001 ÷ 0308 ÷ 1F1E6 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
÷ 0001 ÷ 0600 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
÷ 0001 ÷ 0308 ÷ 0600 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
÷ 0001 ÷ 0903 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
÷ 0001 ÷ 0308 × 0903 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
÷ 0001 ÷ 1100 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
÷ 0001 ÷ 0308 ÷ 1100 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
÷ 0001 ÷ 1160 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
÷ 0001 ÷ 0308 ÷ 1160 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
÷ 0001 ÷ 11A8 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
÷ 0001 ÷ 0308 ÷ 11A8 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
÷ 0001 ÷ AC00 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
÷ 0001 ÷ 0308 ÷ AC00 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
÷ 0001 ÷ AC01 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
÷ 0001 ÷ 0308 ÷ AC01 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
÷ 0001 ÷ 231A ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] WATCH (ExtPict) ÷ [0.3]
÷ 0001 ÷ 0308 ÷ 231A ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
÷ 0001 ÷ 0300 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3]
÷ 0001 ÷ 0308 × 0300 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3]
÷ 0001 ÷ 200D ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3]
÷ 0001 ÷ 0308 × 200D ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3]
÷ 0001 ÷ 0378 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] <reserved-0378> (Other) ÷ [0.3]
÷ 0001 ÷ 0308 ÷ 0378 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
÷ 034F ÷ 0020 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) ÷ [999.0] SPACE (Other) ÷ [0.3]
÷ 034F × 0308 ÷ 0020 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3]
÷ 034F ÷ 000D ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
÷ 034F × 0308 ÷ 000D ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
÷ 034F ÷ 000A ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
÷ 034F × 0308 ÷ 000A ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
÷ 034F ÷ 0001 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
÷ 034F × 0308 ÷ 0001 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
÷ 034F × 034F ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3]
÷ 034F × 0308 × 034F ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3]
÷ 034F ÷ 1F1E6 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
÷ 034F × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
÷ 034F ÷ 0600 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
÷ 034F × 0308 ÷ 0600 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
÷ 034F × 0903 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
÷ 034F × 0308 × 0903 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
÷ 034F ÷ 1100 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
÷ 034F × 0308 ÷ 1100 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
÷ 034F ÷ 1160 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
÷ 034F × 0308 ÷ 1160 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
÷ 034F ÷ 11A8 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
÷ 034F × 0308 ÷ 11A8 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
÷ 034F ÷ AC00 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
÷ 034F × 0308 ÷ AC00 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
÷ 034F ÷ AC01 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
÷ 034F × 0308 ÷ AC01 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
÷ 034F ÷ 231A ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
÷ 034F × 0308 ÷ 231A ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
÷ 034F × 0300 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3]
÷ 034F × 0308 × 0300 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3]
÷ 034F × 200D ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3]
÷ 034F × 0308 × 200D ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3]
÷ 034F ÷ 0378 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
÷ 034F × 0308 ÷ 0378 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
÷ 1F1E6 ÷ 0020 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] SPACE (Other) ÷ [0.3]
÷ 1F1E6 × 0308 ÷ 0020 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3]
÷ 1F1E6 ÷ 000D ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
÷ 1F1E6 × 0308 ÷ 000D ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
÷ 1F1E6 ÷ 000A ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
÷ 1F1E6 × 0308 ÷ 000A ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
÷ 1F1E6 ÷ 0001 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
÷ 1F1E6 × 0308 ÷ 0001 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
÷ 1F1E6 × 034F ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3]
÷ 1F1E6 × 0308 × 034F ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3]
÷ 1F1E6 × 1F1E6 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [12.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
÷ 1F1E6 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
÷ 1F1E6 ÷ 0600 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
÷ 1F1E6 × 0308 ÷ 0600 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
÷ 1F1E6 × 0903 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
÷ 1F1E6 × 0308 × 0903 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
÷ 1F1E6 ÷ 1100 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
÷ 1F1E6 × 0308 ÷ 1100 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
÷ 1F1E6 ÷ 1160 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
÷ 1F1E6 × 0308 ÷ 1160 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
÷ 1F1E6 ÷ 11A8 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
÷ 1F1E6 × 0308 ÷ 11A8 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
÷ 1F1E6 ÷ AC00 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
÷ 1F1E6 × 0308 ÷ AC00 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
÷ 1F1E6 ÷ AC01 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
÷ 1F1E6 × 0308 ÷ AC01 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
÷ 1F1E6 ÷ 231A ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
÷ 1F1E6 × 0308 ÷ 231A ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
÷ 1F1E6 × 0300 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3]
÷ 1F1E6 × 0308 × 0300 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3]
÷ 1F1E6 × 200D ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3]
÷ 1F1E6 × 0308 × 200D ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3]
÷ 1F1E6 ÷ 0378 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
÷ 1F1E6 × 0308 ÷ 0378 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
÷ 0600 × 0020 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.2] SPACE (Other) ÷ [0.3]
÷ 0600 × 0308 ÷ 0020 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3]
÷ 0600 ÷ 000D ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
÷ 0600 × 0308 ÷ 000D ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
÷ 0600 ÷ 000A ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
÷ 0600 × 0308 ÷ 000A ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
÷ 0600 ÷ 0001 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
÷ 0600 × 0308 ÷ 0001 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
÷ 0600 × 034F ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3]
÷ 0600 × 0308 × 034F ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3]
÷ 0600 × 1F1E6 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
÷ 0600 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
÷ 0600 × 0600 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.2] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
÷ 0600 × 0308 ÷ 0600 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
÷ 0600 × 0903 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
÷ 0600 × 0308 × 0903 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
÷ 0600 × 1100 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.2] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
÷ 0600 × 0308 ÷ 1100 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
÷ 0600 × 1160 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.2] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
÷ 0600 × 0308 ÷ 1160 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
÷ 0600 × 11A8 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.2] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
÷ 0600 × 0308 ÷ 11A8 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
÷ 0600 × AC00 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.2] HANGUL SYLLABLE GA (LV) ÷ [0.3]
÷ 0600 × 0308 ÷ AC00 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
÷ 0600 × AC01 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.2] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
÷ 0600 × 0308 ÷ AC01 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
÷ 0600 × 231A ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.2] WATCH (ExtPict) ÷ [0.3]
÷ 0600 × 0308 ÷ 231A ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
÷ 0600 × 0300 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3]
÷ 0600 × 0308 × 0300 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3]
÷ 0600 × 200D ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3]
÷ 0600 × 0308 × 200D ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3]
÷ 0600 × 0378 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.2] <reserved-0378> (Other) ÷ [0.3]
÷ 0600 × 0308 ÷ 0378 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
÷ 0903 ÷ 0020 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [999.0] SPACE (Other) ÷ [0.3]
÷ 0903 × 0308 ÷ 0020 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3]
÷ 0903 ÷ 000D ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
÷ 0903 × 0308 ÷ 000D ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
÷ 0903 ÷ 000A ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
÷ 0903 × 0308 ÷ 000A ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
÷ 0903 ÷ 0001 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
÷ 0903 × 0308 ÷ 0001 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
÷ 0903 × 034F ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3]
÷ 0903 × 0308 × 034F ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3]
÷ 0903 ÷ 1F1E6 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
÷ 0903 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
÷ 0903 ÷ 0600 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
÷ 0903 × 0308 ÷ 0600 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
÷ 0903 × 0903 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
÷ 0903 × 0308 × 0903 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
÷ 0903 ÷ 1100 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
÷ 0903 × 0308 ÷ 1100 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
÷ 0903 ÷ 1160 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
÷ 0903 × 0308 ÷ 1160 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
÷ 0903 ÷ 11A8 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
÷ 0903 × 0308 ÷ 11A8 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
÷ 0903 ÷ AC00 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
÷ 0903 × 0308 ÷ AC00 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
÷ 0903 ÷ AC01 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
÷ 0903 × 0308 ÷ AC01 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
÷ 0903 ÷ 231A ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
÷ 0903 × 0308 ÷ 231A ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
÷ 0903 × 0300 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3]
÷ 0903 × 0308 × 0300 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3]
÷ 0903 × 200D ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3]
÷ 0903 × 0308 × 200D ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3]
÷ 0903 ÷ 0378 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
÷ 0903 × 0308 ÷ 0378 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
÷ 1100 ÷ 0020 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) ÷ [999.0] SPACE (Other) ÷ [0.3]
÷ 1100 × 0308 ÷ 0020 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3]
÷ 1100 ÷ 000D ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
÷ 1100 × 0308 ÷ 000D ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
÷ 1100 ÷ 000A ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
÷ 1100 × 0308 ÷ 000A ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
÷ 1100 ÷ 0001 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
÷ 1100 × 0308 ÷ 0001 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
÷ 1100 × 034F ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3]
÷ 1100 × 0308 × 034F ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3]
÷ 1100 ÷ 1F1E6 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
÷ 1100 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
÷ 1100 ÷ 0600 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
÷ 1100 × 0308 ÷ 0600 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
÷ 1100 × 0903 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
÷ 1100 × 0308 × 0903 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
÷ 1100 × 1100 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [6.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
÷ 1100 × 0308 ÷ 1100 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
÷ 1100 × 1160 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [6.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
÷ 1100 × 0308 ÷ 1160 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
÷ 1100 ÷ 11A8 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
÷ 1100 × 0308 ÷ 11A8 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
÷ 1100 × AC00 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [6.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
÷ 1100 × 0308 ÷ AC00 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
÷ 1100 × AC01 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [6.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
÷ 1100 × 0308 ÷ AC01 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
÷ 1100 ÷ 231A ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
÷ 1100 × 0308 ÷ 231A ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
÷ 1100 × 0300 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3]
÷ 1100 × 0308 × 0300 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3]
÷ 1100 × 200D ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3]
÷ 1100 × 0308 × 200D ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3]
÷ 1100 ÷ 0378 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
÷ 1100 × 0308 ÷ 0378 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
÷ 1160 ÷ 0020 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) ÷ [999.0] SPACE (Other) ÷ [0.3]
÷ 1160 × 0308 ÷ 0020 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3]
÷ 1160 ÷ 000D ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
÷ 1160 × 0308 ÷ 000D ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
÷ 1160 ÷ 000A ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
÷ 1160 × 0308 ÷ 000A ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
÷ 1160 ÷ 0001 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
÷ 1160 × 0308 ÷ 0001 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
÷ 1160 × 034F ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3]
÷ 1160 × 0308 × 034F ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3]
÷ 1160 ÷ 1F1E6 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
÷ 1160 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
÷ 1160 ÷ 0600 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
÷ 1160 × 0308 ÷ 0600 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
÷ 1160 × 0903 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
÷ 1160 × 0308 × 0903 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
÷ 1160 ÷ 1100 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
÷ 1160 × 0308 ÷ 1100 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
÷ 1160 × 1160 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [7.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
÷ 1160 × 0308 ÷ 1160 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
÷ 1160 × 11A8 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [7.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
÷ 1160 × 0308 ÷ 11A8 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
÷ 1160 ÷ AC00 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
÷ 1160 × 0308 ÷ AC00 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
÷ 1160 ÷ AC01 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
÷ 1160 × 0308 ÷ AC01 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
÷ 1160 ÷ 231A ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
÷ 1160 × 0308 ÷ 231A ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
÷ 1160 × 0300 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3]
÷ 1160 × 0308 × 0300 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3]
÷ 1160 × 200D ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3]
÷ 1160 × 0308 × 200D ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3]
÷ 1160 ÷ 0378 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
÷ 1160 × 0308 ÷ 0378 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
÷ 11A8 ÷ 0020 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) ÷ [999.0] SPACE (Other) ÷ [0.3]
÷ 11A8 × 0308 ÷ 0020 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3]
÷ 11A8 ÷ 000D ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
÷ 11A8 × 0308 ÷ 000D ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
÷ 11A8 ÷ 000A ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
÷ 11A8 × 0308 ÷ 000A ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
÷ 11A8 ÷ 0001 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
÷ 11A8 × 0308 ÷ 0001 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
÷ 11A8 × 034F ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3]
÷ 11A8 × 0308 × 034F ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3]
÷ 11A8 ÷ 1F1E6 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
÷ 11A8 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
÷ 11A8 ÷ 0600 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
÷ 11A8 × 0308 ÷ 0600 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
÷ 11A8 × 0903 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
÷ 11A8 × 0308 × 0903 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
÷ 11A8 ÷ 1100 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
÷ 11A8 × 0308 ÷ 1100 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
÷ 11A8 ÷ 1160 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
÷ 11A8 × 0308 ÷ 1160 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
÷ 11A8 × 11A8 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [8.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
÷ 11A8 × 0308 ÷ 11A8 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
÷ 11A8 ÷ AC00 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
÷ 11A8 × 0308 ÷ AC00 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
÷ 11A8 ÷ AC01 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
÷ 11A8 × 0308 ÷ AC01 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
÷ 11A8 ÷ 231A ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
÷ 11A8 × 0308 ÷ 231A ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
÷ 11A8 × 0300 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3]
÷ 11A8 × 0308 × 0300 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3]
÷ 11A8 × 200D ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3]
÷ 11A8 × 0308 × 200D ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3]
÷ 11A8 ÷ 0378 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
÷ 11A8 × 0308 ÷ 0378 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
÷ AC00 ÷ 0020 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) ÷ [999.0] SPACE (Other) ÷ [0.3]
÷ AC00 × 0308 ÷ 0020 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3]
÷ AC00 ÷ 000D ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
÷ AC00 × 0308 ÷ 000D ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
÷ AC00 ÷ 000A ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
÷ AC00 × 0308 ÷ 000A ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
÷ AC00 ÷ 0001 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
÷ AC00 × 0308 ÷ 0001 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
÷ AC00 × 034F ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3]
÷ AC00 × 0308 × 034F ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3]
÷ AC00 ÷ 1F1E6 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
÷ AC00 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
÷ AC00 ÷ 0600 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
÷ AC00 × 0308 ÷ 0600 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
÷ AC00 × 0903 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
÷ AC00 × 0308 × 0903 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
÷ AC00 ÷ 1100 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
÷ AC00 × 0308 ÷ 1100 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
÷ AC00 × 1160 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [7.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
÷ AC00 × 0308 ÷ 1160 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
÷ AC00 × 11A8 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [7.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
÷ AC00 × 0308 ÷ 11A8 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
÷ AC00 ÷ AC00 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
÷ AC00 × 0308 ÷ AC00 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
÷ AC00 ÷ AC01 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
÷ AC00 × 0308 ÷ AC01 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
÷ AC00 ÷ 231A ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
÷ AC00 × 0308 ÷ 231A ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
÷ AC00 × 0300 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3]
÷ AC00 × 0308 × 0300 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3]
÷ AC00 × 200D ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3]
÷ AC00 × 0308 × 200D ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3]
÷ AC00 ÷ 0378 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
÷ AC00 × 0308 ÷ 0378 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
÷ AC01 ÷ 0020 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) ÷ [999.0] SPACE (Other) ÷ [0.3]
÷ AC01 × 0308 ÷ 0020 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3]
÷ AC01 ÷ 000D ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
÷ AC01 × 0308 ÷ 000D ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
÷ AC01 ÷ 000A ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
÷ AC01 × 0308 ÷ 000A ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
÷ AC01 ÷ 0001 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
÷ AC01 × 0308 ÷ 0001 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
÷ AC01 × 034F ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3]
÷ AC01 × 0308 × 034F ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3]
÷ AC01 ÷ 1F1E6 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
÷ AC01 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
÷ AC01 ÷ 0600 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
÷ AC01 × 0308 ÷ 0600 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
÷ AC01 × 0903 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
÷ AC01 × 0308 × 0903 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
÷ AC01 ÷ 1100 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
÷ AC01 × 0308 ÷ 1100 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
÷ AC01 ÷ 1160 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
÷ AC01 × 0308 ÷ 1160 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
÷ AC01 × 11A8 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [8.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
÷ AC01 × 0308 ÷ 11A8 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
÷ AC01 ÷ AC00 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
÷ AC01 × 0308 ÷ AC00 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
÷ AC01 ÷ AC01 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
÷ AC01 × 0308 ÷ AC01 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
÷ AC01 ÷ 231A ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
÷ AC01 × 0308 ÷ 231A ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
÷ AC01 × 0300 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3]
÷ AC01 × 0308 × 0300 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3]
÷ AC01 × 200D ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3]
÷ AC01 × 0308 × 200D ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3]
÷ AC01 ÷ 0378 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
÷ AC01 × 0308 ÷ 0378 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
÷ 231A ÷ 0020 ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [999.0] SPACE (Other) ÷ [0.3]
÷ 231A × 0308 ÷ 0020 ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3]
÷ 231A ÷ 000D ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
÷ 231A × 0308 ÷ 000D ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
÷ 231A ÷ 000A ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
÷ 231A × 0308 ÷ 000A ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
÷ 231A ÷ 0001 ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
÷ 231A × 0308 ÷ 0001 ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
÷ 231A × 034F ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3]
÷ 231A × 0308 × 034F ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3]
÷ 231A ÷ 1F1E6 ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
÷ 231A × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
÷ 231A ÷ 0600 ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
÷ 231A × 0308 ÷ 0600 ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
÷ 231A × 0903 ÷ # ÷ [0.2] WATCH (ExtPict) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
÷ 231A × 0308 × 0903 ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
÷ 231A ÷ 1100 ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
÷ 231A × 0308 ÷ 1100 ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
÷ 231A ÷ 1160 ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
÷ 231A × 0308 ÷ 1160 ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
÷ 231A ÷ 11A8 ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
÷ 231A × 0308 ÷ 11A8 ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
÷ 231A ÷ AC00 ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
÷ 231A × 0308 ÷ AC00 ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
÷ 231A ÷ AC01 ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
÷ 231A × 0308 ÷ AC01 ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
÷ 231A ÷ 231A ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
÷ 231A × 0308 ÷ 231A ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
÷ 231A × 0300 ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3]
÷ 231A × 0308 × 0300 ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3]
÷ 231A × 200D ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3]
÷ 231A × 0308 × 200D ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3]
÷ 231A ÷ 0378 ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
÷ 231A × 0308 ÷ 0378 ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
÷ 0300 ÷ 0020 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3]
÷ 0300 × 0308 ÷ 0020 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3]
÷ 0300 ÷ 000D ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
÷ 0300 × 0308 ÷ 000D ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
÷ 0300 ÷ 000A ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
÷ 0300 × 0308 ÷ 000A ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
÷ 0300 ÷ 0001 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
÷ 0300 × 0308 ÷ 0001 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
÷ 0300 × 034F ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3]
÷ 0300 × 0308 × 034F ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3]
÷ 0300 ÷ 1F1E6 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
÷ 0300 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
÷ 0300 ÷ 0600 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
÷ 0300 × 0308 ÷ 0600 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
÷ 0300 × 0903 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
÷ 0300 × 0308 × 0903 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
÷ 0300 ÷ 1100 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
÷ 0300 × 0308 ÷ 1100 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
÷ 0300 ÷ 1160 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
÷ 0300 × 0308 ÷ 1160 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
÷ 0300 ÷ 11A8 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
÷ 0300 × 0308 ÷ 11A8 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
÷ 0300 ÷ AC00 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
÷ 0300 × 0308 ÷ AC00 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
÷ 0300 ÷ AC01 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
÷ 0300 × 0308 ÷ AC01 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
÷ 0300 ÷ 231A ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
÷ 0300 × 0308 ÷ 231A ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
÷ 0300 × 0300 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3]
÷ 0300 × 0308 × 0300 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3]
÷ 0300 × 200D ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3]
÷ 0300 × 0308 × 200D ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3]
÷ 0300 ÷ 0378 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
÷ 0300 × 0308 ÷ 0378 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
÷ 200D ÷ 0020 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3]
÷ 200D × 0308 ÷ 0020 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3]
÷ 200D ÷ 000D ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
÷ 200D × 0308 ÷ 000D ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
÷ 200D ÷ 000A ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
÷ 200D × 0308 ÷ 000A ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
÷ 200D ÷ 0001 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
÷ 200D × 0308 ÷ 0001 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
÷ 200D × 034F ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3]
÷ 200D × 0308 × 034F ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3]
÷ 200D ÷ 1F1E6 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
÷ 200D × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
÷ 200D ÷ 0600 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
÷ 200D × 0308 ÷ 0600 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
÷ 200D × 0903 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
÷ 200D × 0308 × 0903 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
÷ 200D ÷ 1100 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
÷ 200D × 0308 ÷ 1100 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
÷ 200D ÷ 1160 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
÷ 200D × 0308 ÷ 1160 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
÷ 200D ÷ 11A8 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
÷ 200D × 0308 ÷ 11A8 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
÷ 200D ÷ AC00 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
÷ 200D × 0308 ÷ AC00 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
÷ 200D ÷ AC01 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
÷ 200D × 0308 ÷ AC01 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
÷ 200D ÷ 231A ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
÷ 200D × 0308 ÷ 231A ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
÷ 200D × 0300 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3]
÷ 200D × 0308 × 0300 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3]
÷ 200D × 200D ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3]
÷ 200D × 0308 × 200D ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3]
÷ 200D ÷ 0378 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
÷ 200D × 0308 ÷ 0378 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
÷ 0378 ÷ 0020 ÷ # ÷ [0.2] <reserved-0378> (Other) ÷ [999.0] SPACE (Other) ÷ [0.3]
÷ 0378 × 0308 ÷ 0020 ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3]
÷ 0378 ÷ 000D ÷ # ÷ [0.2] <reserved-0378> (Other) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
÷ 0378 × 0308 ÷ 000D ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
÷ 0378 ÷ 000A ÷ # ÷ [0.2] <reserved-0378> (Other) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
÷ 0378 × 0308 ÷ 000A ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
÷ 0378 ÷ 0001 ÷ # ÷ [0.2] <reserved-0378> (Other) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
÷ 0378 × 0308 ÷ 0001 ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
÷ 0378 × 034F ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3]
÷ 0378 × 0308 × 034F ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3]
÷ 0378 ÷ 1F1E6 ÷ # ÷ [0.2] <reserved-0378> (Other) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
÷ 0378 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
÷ 0378 ÷ 0600 ÷ # ÷ [0.2] <reserved-0378> (Other) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
÷ 0378 × 0308 ÷ 0600 ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
÷ 0378 × 0903 ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
÷ 0378 × 0308 × 0903 ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
÷ 0378 ÷ 1100 ÷ # ÷ [0.2] <reserved-0378> (Other) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
÷ 0378 × 0308 ÷ 1100 ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
÷ 0378 ÷ 1160 ÷ # ÷ [0.2] <reserved-0378> (Other) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
÷ 0378 × 0308 ÷ 1160 ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
÷ 0378 ÷ 11A8 ÷ # ÷ [0.2] <reserved-0378> (Other) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
÷ 0378 × 0308 ÷ 11A8 ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
÷ 0378 ÷ AC00 ÷ # ÷ [0.2] <reserved-0378> (Other) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
÷ 0378 × 0308 ÷ AC00 ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
÷ 0378 ÷ AC01 ÷ # ÷ [0.2] <reserved-0378> (Other) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
÷ 0378 × 0308 ÷ AC01 ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
÷ 0378 ÷ 231A ÷ # ÷ [0.2] <reserved-0378> (Other) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
÷ 0378 × 0308 ÷ 231A ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
÷ 0378 × 0300 ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3]
÷ 0378 × 0308 × 0300 ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3]
÷ 0378 × 200D ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3]
÷ 0378 × 0308 × 200D ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3]
÷ 0378 ÷ 0378 ÷ # ÷ [0.2] <reserved-0378> (Other) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
÷ 0378 × 0308 ÷ 0378 ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
÷ 000D × 000A ÷ 0061 ÷ 000A ÷ 0308 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) × [3.0] <LINE FEED (LF)> (LF) ÷ [4.0] LATIN SMALL LETTER A (Other) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [0.3]
÷ 0061 × 0308 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [0.3]
÷ 0020 × 200D ÷ 0646 ÷ # ÷ [0.2] SPACE (Other) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [999.0] ARABIC LETTER NOON (Other) ÷ [0.3]
÷ 0646 × 200D ÷ 0020 ÷ # ÷ [0.2] ARABIC LETTER NOON (Other) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3]
÷ 1100 × 1100 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [6.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
÷ AC00 × 11A8 ÷ 1100 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [7.0] HANGUL JONGSEONG KIYEOK (T) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
÷ AC01 × 11A8 ÷ 1100 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [8.0] HANGUL JONGSEONG KIYEOK (T) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
÷ 1F1E6 × 1F1E7 ÷ 1F1E8 ÷ 0062 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [12.0] REGIONAL INDICATOR SYMBOL LETTER B (RI) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER C (RI) ÷ [999.0] LATIN SMALL LETTER B (Other) ÷ [0.3]
÷ 0061 ÷ 1F1E6 × 1F1E7 ÷ 1F1E8 ÷ 0062 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Other) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [13.0] REGIONAL INDICATOR SYMBOL LETTER B (RI) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER C (RI) ÷ [999.0] LATIN SMALL LETTER B (Other) ÷ [0.3]
÷ 0061 ÷ 1F1E6 × 1F1E7 × 200D ÷ 1F1E8 ÷ 0062 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Other) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [13.0] REGIONAL INDICATOR SYMBOL LETTER B (RI) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER C (RI) ÷ [999.0] LATIN SMALL LETTER B (Other) ÷ [0.3]
÷ 0061 ÷ 1F1E6 × 200D ÷ 1F1E7 × 1F1E8 ÷ 0062 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Other) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER B (RI) × [13.0] REGIONAL INDICATOR SYMBOL LETTER C (RI) ÷ [999.0] LATIN SMALL LETTER B (Other) ÷ [0.3]
÷ 0061 ÷ 1F1E6 × 1F1E7 ÷ 1F1E8 × 1F1E9 ÷ 0062 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Other) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [13.0] REGIONAL INDICATOR SYMBOL LETTER B (RI) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER C (RI) × [13.0] REGIONAL INDICATOR SYMBOL LETTER D (RI) ÷ [999.0] LATIN SMALL LETTER B (Other) ÷ [0.3]
÷ 0061 × 200D ÷ # ÷ [0.2] LATIN SMALL LETTER A (Other) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3]
÷ 0061 × 0308 ÷ 0062 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] LATIN SMALL LETTER B (Other) ÷ [0.3]
÷ 0061 × 0903 ÷ 0062 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Other) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [999.0] LATIN SMALL LETTER B (Other) ÷ [0.3]
÷ 0061 ÷ 0600 × 0062 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Other) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) × [9.2] LATIN SMALL LETTER B (Other) ÷ [0.3]
÷ 1F476 × 1F3FF ÷ 1F476 ÷ # ÷ [0.2] BABY (ExtPict) × [9.0] EMOJI MODIFIER FITZPATRICK TYPE-6 (Extend) ÷ [999.0] BABY (ExtPict) ÷ [0.3]
÷ 0061 × 1F3FF ÷ 1F476 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Other) × [9.0] EMOJI MODIFIER FITZPATRICK TYPE-6 (Extend) ÷ [999.0] BABY (ExtPict) ÷ [0.3]
÷ 0061 × 1F3FF ÷ 1F476 × 200D × 1F6D1 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Other) × [9.0] EMOJI MODIFIER FITZPATRICK TYPE-6 (Extend) ÷ [999.0] BABY (ExtPict) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [11.0] OCTAGONAL SIGN (ExtPict) ÷ [0.3]
÷ 1F476 × 1F3FF × 0308 × 200D × 1F476 × 1F3FF ÷ # ÷ [0.2] BABY (ExtPict) × [9.0] EMOJI MODIFIER FITZPATRICK TYPE-6 (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [11.0] BABY (ExtPict) × [9.0] EMOJI MODIFIER FITZPATRICK TYPE-6 (Extend) ÷ [0.3]
÷ 1F6D1 × 200D × 1F6D1 ÷ # ÷ [0.2] OCTAGONAL SIGN (ExtPict) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [11.0] OCTAGONAL SIGN (ExtPict) ÷ [0.3]
÷ 0061 × 200D ÷ 1F6D1 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Other) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [999.0] OCTAGONAL SIGN (ExtPict) ÷ [0.3]
÷ 2701 × 200D × 2701 ÷ # ÷ [0.2] UPPER BLADE SCISSORS (Other) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [11.0] UPPER BLADE SCISSORS (Other) ÷ [0.3]
÷ 0061 × 200D ÷ 2701 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Other) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [999.0] UPPER BLADE SCISSORS (Other) ÷ [0.3]
#
# Lines: 602
#
# EOF

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,530 @@
# SentenceBreakTest-15.0.0.txt
# Date: 2022-02-26, 00:39:00 GMT
# © 2022 Unicode®, Inc.
# Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries.
# For terms of use, see https://www.unicode.org/terms_of_use.html
#
# Unicode Character Database
# For documentation, see https://www.unicode.org/reports/tr44/
#
# Default Sentence_Break Test
#
# Format:
# <string> (# <comment>)?
# <string> contains hex Unicode code points, with
# ÷ wherever there is a break opportunity, and
# × wherever there is not.
# <comment> the format can change, but currently it shows:
# - the sample character name
# - (x) the Sentence_Break property value for the sample character
# - [x] the rule that determines whether there is a break or not,
# as listed in the Rules section of SentenceBreakTest.html
#
# These samples may be extended or changed in the future.
#
÷ 0001 × 0001 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [998.0] <START OF HEADING> (Other) ÷ [0.3]
÷ 0001 × 0308 × 0001 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <START OF HEADING> (Other) ÷ [0.3]
÷ 0001 × 000D ÷ # ÷ [0.2] <START OF HEADING> (Other) × [998.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
÷ 0001 × 0308 × 000D ÷ # ÷ [0.2] <START OF HEADING> (Other) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
÷ 0001 × 000A ÷ # ÷ [0.2] <START OF HEADING> (Other) × [998.0] <LINE FEED (LF)> (LF) ÷ [0.3]
÷ 0001 × 0308 × 000A ÷ # ÷ [0.2] <START OF HEADING> (Other) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <LINE FEED (LF)> (LF) ÷ [0.3]
÷ 0001 × 0085 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [998.0] <NEXT LINE (NEL)> (Sep) ÷ [0.3]
÷ 0001 × 0308 × 0085 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <NEXT LINE (NEL)> (Sep) ÷ [0.3]
÷ 0001 × 0009 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [998.0] <CHARACTER TABULATION> (Sp) ÷ [0.3]
÷ 0001 × 0308 × 0009 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <CHARACTER TABULATION> (Sp) ÷ [0.3]
÷ 0001 × 0061 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
÷ 0001 × 0308 × 0061 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
÷ 0001 × 0041 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
÷ 0001 × 0308 × 0041 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
÷ 0001 × 01BB ÷ # ÷ [0.2] <START OF HEADING> (Other) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3]
÷ 0001 × 0308 × 01BB ÷ # ÷ [0.2] <START OF HEADING> (Other) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3]
÷ 0001 × 0030 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3]
÷ 0001 × 0308 × 0030 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3]
÷ 0001 × 002E ÷ # ÷ [0.2] <START OF HEADING> (Other) × [998.0] FULL STOP (ATerm) ÷ [0.3]
÷ 0001 × 0308 × 002E ÷ # ÷ [0.2] <START OF HEADING> (Other) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] FULL STOP (ATerm) ÷ [0.3]
÷ 0001 × 0021 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3]
÷ 0001 × 0308 × 0021 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3]
÷ 0001 × 0022 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [998.0] QUOTATION MARK (Close) ÷ [0.3]
÷ 0001 × 0308 × 0022 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] QUOTATION MARK (Close) ÷ [0.3]
÷ 0001 × 002C ÷ # ÷ [0.2] <START OF HEADING> (Other) × [998.0] COMMA (SContinue) ÷ [0.3]
÷ 0001 × 0308 × 002C ÷ # ÷ [0.2] <START OF HEADING> (Other) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] COMMA (SContinue) ÷ [0.3]
÷ 0001 × 00AD ÷ # ÷ [0.2] <START OF HEADING> (Other) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
÷ 0001 × 0308 × 00AD ÷ # ÷ [0.2] <START OF HEADING> (Other) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
÷ 0001 × 0300 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
÷ 0001 × 0308 × 0300 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
÷ 000D ÷ 0001 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] <START OF HEADING> (Other) ÷ [0.3]
÷ 000D ÷ 0308 × 0001 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <START OF HEADING> (Other) ÷ [0.3]
÷ 000D ÷ 000D ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
÷ 000D ÷ 0308 × 000D ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
÷ 000D × 000A ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) × [3.0] <LINE FEED (LF)> (LF) ÷ [0.3]
÷ 000D ÷ 0308 × 000A ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <LINE FEED (LF)> (LF) ÷ [0.3]
÷ 000D ÷ 0085 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] <NEXT LINE (NEL)> (Sep) ÷ [0.3]
÷ 000D ÷ 0308 × 0085 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <NEXT LINE (NEL)> (Sep) ÷ [0.3]
÷ 000D ÷ 0009 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] <CHARACTER TABULATION> (Sp) ÷ [0.3]
÷ 000D ÷ 0308 × 0009 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <CHARACTER TABULATION> (Sp) ÷ [0.3]
÷ 000D ÷ 0061 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
÷ 000D ÷ 0308 × 0061 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
÷ 000D ÷ 0041 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
÷ 000D ÷ 0308 × 0041 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
÷ 000D ÷ 01BB ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3]
÷ 000D ÷ 0308 × 01BB ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3]
÷ 000D ÷ 0030 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] DIGIT ZERO (Numeric) ÷ [0.3]
÷ 000D ÷ 0308 × 0030 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3]
÷ 000D ÷ 002E ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] FULL STOP (ATerm) ÷ [0.3]
÷ 000D ÷ 0308 × 002E ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] FULL STOP (ATerm) ÷ [0.3]
÷ 000D ÷ 0021 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] EXCLAMATION MARK (STerm) ÷ [0.3]
÷ 000D ÷ 0308 × 0021 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3]
÷ 000D ÷ 0022 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] QUOTATION MARK (Close) ÷ [0.3]
÷ 000D ÷ 0308 × 0022 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] QUOTATION MARK (Close) ÷ [0.3]
÷ 000D ÷ 002C ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMMA (SContinue) ÷ [0.3]
÷ 000D ÷ 0308 × 002C ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] COMMA (SContinue) ÷ [0.3]
÷ 000D ÷ 00AD ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
÷ 000D ÷ 0308 × 00AD ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
÷ 000D ÷ 0300 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
÷ 000D ÷ 0308 × 0300 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
÷ 000A ÷ 0001 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] <START OF HEADING> (Other) ÷ [0.3]
÷ 000A ÷ 0308 × 0001 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <START OF HEADING> (Other) ÷ [0.3]
÷ 000A ÷ 000D ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
÷ 000A ÷ 0308 × 000D ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
÷ 000A ÷ 000A ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] <LINE FEED (LF)> (LF) ÷ [0.3]
÷ 000A ÷ 0308 × 000A ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <LINE FEED (LF)> (LF) ÷ [0.3]
÷ 000A ÷ 0085 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] <NEXT LINE (NEL)> (Sep) ÷ [0.3]
÷ 000A ÷ 0308 × 0085 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <NEXT LINE (NEL)> (Sep) ÷ [0.3]
÷ 000A ÷ 0009 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] <CHARACTER TABULATION> (Sp) ÷ [0.3]
÷ 000A ÷ 0308 × 0009 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <CHARACTER TABULATION> (Sp) ÷ [0.3]
÷ 000A ÷ 0061 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
÷ 000A ÷ 0308 × 0061 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
÷ 000A ÷ 0041 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
÷ 000A ÷ 0308 × 0041 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
÷ 000A ÷ 01BB ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3]
÷ 000A ÷ 0308 × 01BB ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3]
÷ 000A ÷ 0030 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] DIGIT ZERO (Numeric) ÷ [0.3]
÷ 000A ÷ 0308 × 0030 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3]
÷ 000A ÷ 002E ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] FULL STOP (ATerm) ÷ [0.3]
÷ 000A ÷ 0308 × 002E ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] FULL STOP (ATerm) ÷ [0.3]
÷ 000A ÷ 0021 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] EXCLAMATION MARK (STerm) ÷ [0.3]
÷ 000A ÷ 0308 × 0021 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3]
÷ 000A ÷ 0022 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] QUOTATION MARK (Close) ÷ [0.3]
÷ 000A ÷ 0308 × 0022 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] QUOTATION MARK (Close) ÷ [0.3]
÷ 000A ÷ 002C ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMMA (SContinue) ÷ [0.3]
÷ 000A ÷ 0308 × 002C ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] COMMA (SContinue) ÷ [0.3]
÷ 000A ÷ 00AD ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
÷ 000A ÷ 0308 × 00AD ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
÷ 000A ÷ 0300 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
÷ 000A ÷ 0308 × 0300 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
÷ 0085 ÷ 0001 ÷ # ÷ [0.2] <NEXT LINE (NEL)> (Sep) ÷ [4.0] <START OF HEADING> (Other) ÷ [0.3]
÷ 0085 ÷ 0308 × 0001 ÷ # ÷ [0.2] <NEXT LINE (NEL)> (Sep) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <START OF HEADING> (Other) ÷ [0.3]
÷ 0085 ÷ 000D ÷ # ÷ [0.2] <NEXT LINE (NEL)> (Sep) ÷ [4.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
÷ 0085 ÷ 0308 × 000D ÷ # ÷ [0.2] <NEXT LINE (NEL)> (Sep) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
÷ 0085 ÷ 000A ÷ # ÷ [0.2] <NEXT LINE (NEL)> (Sep) ÷ [4.0] <LINE FEED (LF)> (LF) ÷ [0.3]
÷ 0085 ÷ 0308 × 000A ÷ # ÷ [0.2] <NEXT LINE (NEL)> (Sep) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <LINE FEED (LF)> (LF) ÷ [0.3]
÷ 0085 ÷ 0085 ÷ # ÷ [0.2] <NEXT LINE (NEL)> (Sep) ÷ [4.0] <NEXT LINE (NEL)> (Sep) ÷ [0.3]
÷ 0085 ÷ 0308 × 0085 ÷ # ÷ [0.2] <NEXT LINE (NEL)> (Sep) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <NEXT LINE (NEL)> (Sep) ÷ [0.3]
÷ 0085 ÷ 0009 ÷ # ÷ [0.2] <NEXT LINE (NEL)> (Sep) ÷ [4.0] <CHARACTER TABULATION> (Sp) ÷ [0.3]
÷ 0085 ÷ 0308 × 0009 ÷ # ÷ [0.2] <NEXT LINE (NEL)> (Sep) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <CHARACTER TABULATION> (Sp) ÷ [0.3]
÷ 0085 ÷ 0061 ÷ # ÷ [0.2] <NEXT LINE (NEL)> (Sep) ÷ [4.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
÷ 0085 ÷ 0308 × 0061 ÷ # ÷ [0.2] <NEXT LINE (NEL)> (Sep) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
÷ 0085 ÷ 0041 ÷ # ÷ [0.2] <NEXT LINE (NEL)> (Sep) ÷ [4.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
÷ 0085 ÷ 0308 × 0041 ÷ # ÷ [0.2] <NEXT LINE (NEL)> (Sep) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
÷ 0085 ÷ 01BB ÷ # ÷ [0.2] <NEXT LINE (NEL)> (Sep) ÷ [4.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3]
÷ 0085 ÷ 0308 × 01BB ÷ # ÷ [0.2] <NEXT LINE (NEL)> (Sep) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3]
÷ 0085 ÷ 0030 ÷ # ÷ [0.2] <NEXT LINE (NEL)> (Sep) ÷ [4.0] DIGIT ZERO (Numeric) ÷ [0.3]
÷ 0085 ÷ 0308 × 0030 ÷ # ÷ [0.2] <NEXT LINE (NEL)> (Sep) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3]
÷ 0085 ÷ 002E ÷ # ÷ [0.2] <NEXT LINE (NEL)> (Sep) ÷ [4.0] FULL STOP (ATerm) ÷ [0.3]
÷ 0085 ÷ 0308 × 002E ÷ # ÷ [0.2] <NEXT LINE (NEL)> (Sep) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] FULL STOP (ATerm) ÷ [0.3]
÷ 0085 ÷ 0021 ÷ # ÷ [0.2] <NEXT LINE (NEL)> (Sep) ÷ [4.0] EXCLAMATION MARK (STerm) ÷ [0.3]
÷ 0085 ÷ 0308 × 0021 ÷ # ÷ [0.2] <NEXT LINE (NEL)> (Sep) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3]
÷ 0085 ÷ 0022 ÷ # ÷ [0.2] <NEXT LINE (NEL)> (Sep) ÷ [4.0] QUOTATION MARK (Close) ÷ [0.3]
÷ 0085 ÷ 0308 × 0022 ÷ # ÷ [0.2] <NEXT LINE (NEL)> (Sep) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] QUOTATION MARK (Close) ÷ [0.3]
÷ 0085 ÷ 002C ÷ # ÷ [0.2] <NEXT LINE (NEL)> (Sep) ÷ [4.0] COMMA (SContinue) ÷ [0.3]
÷ 0085 ÷ 0308 × 002C ÷ # ÷ [0.2] <NEXT LINE (NEL)> (Sep) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] COMMA (SContinue) ÷ [0.3]
÷ 0085 ÷ 00AD ÷ # ÷ [0.2] <NEXT LINE (NEL)> (Sep) ÷ [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
÷ 0085 ÷ 0308 × 00AD ÷ # ÷ [0.2] <NEXT LINE (NEL)> (Sep) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
÷ 0085 ÷ 0300 ÷ # ÷ [0.2] <NEXT LINE (NEL)> (Sep) ÷ [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
÷ 0085 ÷ 0308 × 0300 ÷ # ÷ [0.2] <NEXT LINE (NEL)> (Sep) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
÷ 0009 × 0001 ÷ # ÷ [0.2] <CHARACTER TABULATION> (Sp) × [998.0] <START OF HEADING> (Other) ÷ [0.3]
÷ 0009 × 0308 × 0001 ÷ # ÷ [0.2] <CHARACTER TABULATION> (Sp) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <START OF HEADING> (Other) ÷ [0.3]
÷ 0009 × 000D ÷ # ÷ [0.2] <CHARACTER TABULATION> (Sp) × [998.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
÷ 0009 × 0308 × 000D ÷ # ÷ [0.2] <CHARACTER TABULATION> (Sp) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
÷ 0009 × 000A ÷ # ÷ [0.2] <CHARACTER TABULATION> (Sp) × [998.0] <LINE FEED (LF)> (LF) ÷ [0.3]
÷ 0009 × 0308 × 000A ÷ # ÷ [0.2] <CHARACTER TABULATION> (Sp) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <LINE FEED (LF)> (LF) ÷ [0.3]
÷ 0009 × 0085 ÷ # ÷ [0.2] <CHARACTER TABULATION> (Sp) × [998.0] <NEXT LINE (NEL)> (Sep) ÷ [0.3]
÷ 0009 × 0308 × 0085 ÷ # ÷ [0.2] <CHARACTER TABULATION> (Sp) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <NEXT LINE (NEL)> (Sep) ÷ [0.3]
÷ 0009 × 0009 ÷ # ÷ [0.2] <CHARACTER TABULATION> (Sp) × [998.0] <CHARACTER TABULATION> (Sp) ÷ [0.3]
÷ 0009 × 0308 × 0009 ÷ # ÷ [0.2] <CHARACTER TABULATION> (Sp) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <CHARACTER TABULATION> (Sp) ÷ [0.3]
÷ 0009 × 0061 ÷ # ÷ [0.2] <CHARACTER TABULATION> (Sp) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
÷ 0009 × 0308 × 0061 ÷ # ÷ [0.2] <CHARACTER TABULATION> (Sp) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
÷ 0009 × 0041 ÷ # ÷ [0.2] <CHARACTER TABULATION> (Sp) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
÷ 0009 × 0308 × 0041 ÷ # ÷ [0.2] <CHARACTER TABULATION> (Sp) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
÷ 0009 × 01BB ÷ # ÷ [0.2] <CHARACTER TABULATION> (Sp) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3]
÷ 0009 × 0308 × 01BB ÷ # ÷ [0.2] <CHARACTER TABULATION> (Sp) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3]
÷ 0009 × 0030 ÷ # ÷ [0.2] <CHARACTER TABULATION> (Sp) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3]
÷ 0009 × 0308 × 0030 ÷ # ÷ [0.2] <CHARACTER TABULATION> (Sp) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3]
÷ 0009 × 002E ÷ # ÷ [0.2] <CHARACTER TABULATION> (Sp) × [998.0] FULL STOP (ATerm) ÷ [0.3]
÷ 0009 × 0308 × 002E ÷ # ÷ [0.2] <CHARACTER TABULATION> (Sp) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] FULL STOP (ATerm) ÷ [0.3]
÷ 0009 × 0021 ÷ # ÷ [0.2] <CHARACTER TABULATION> (Sp) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3]
÷ 0009 × 0308 × 0021 ÷ # ÷ [0.2] <CHARACTER TABULATION> (Sp) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3]
÷ 0009 × 0022 ÷ # ÷ [0.2] <CHARACTER TABULATION> (Sp) × [998.0] QUOTATION MARK (Close) ÷ [0.3]
÷ 0009 × 0308 × 0022 ÷ # ÷ [0.2] <CHARACTER TABULATION> (Sp) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] QUOTATION MARK (Close) ÷ [0.3]
÷ 0009 × 002C ÷ # ÷ [0.2] <CHARACTER TABULATION> (Sp) × [998.0] COMMA (SContinue) ÷ [0.3]
÷ 0009 × 0308 × 002C ÷ # ÷ [0.2] <CHARACTER TABULATION> (Sp) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] COMMA (SContinue) ÷ [0.3]
÷ 0009 × 00AD ÷ # ÷ [0.2] <CHARACTER TABULATION> (Sp) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
÷ 0009 × 0308 × 00AD ÷ # ÷ [0.2] <CHARACTER TABULATION> (Sp) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
÷ 0009 × 0300 ÷ # ÷ [0.2] <CHARACTER TABULATION> (Sp) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
÷ 0009 × 0308 × 0300 ÷ # ÷ [0.2] <CHARACTER TABULATION> (Sp) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
÷ 0061 × 0001 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [998.0] <START OF HEADING> (Other) ÷ [0.3]
÷ 0061 × 0308 × 0001 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <START OF HEADING> (Other) ÷ [0.3]
÷ 0061 × 000D ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [998.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
÷ 0061 × 0308 × 000D ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
÷ 0061 × 000A ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [998.0] <LINE FEED (LF)> (LF) ÷ [0.3]
÷ 0061 × 0308 × 000A ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <LINE FEED (LF)> (LF) ÷ [0.3]
÷ 0061 × 0085 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [998.0] <NEXT LINE (NEL)> (Sep) ÷ [0.3]
÷ 0061 × 0308 × 0085 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <NEXT LINE (NEL)> (Sep) ÷ [0.3]
÷ 0061 × 0009 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [998.0] <CHARACTER TABULATION> (Sp) ÷ [0.3]
÷ 0061 × 0308 × 0009 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <CHARACTER TABULATION> (Sp) ÷ [0.3]
÷ 0061 × 0061 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
÷ 0061 × 0308 × 0061 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
÷ 0061 × 0041 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
÷ 0061 × 0308 × 0041 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
÷ 0061 × 01BB ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3]
÷ 0061 × 0308 × 01BB ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3]
÷ 0061 × 0030 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3]
÷ 0061 × 0308 × 0030 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3]
÷ 0061 × 002E ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [998.0] FULL STOP (ATerm) ÷ [0.3]
÷ 0061 × 0308 × 002E ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] FULL STOP (ATerm) ÷ [0.3]
÷ 0061 × 0021 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3]
÷ 0061 × 0308 × 0021 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3]
÷ 0061 × 0022 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [998.0] QUOTATION MARK (Close) ÷ [0.3]
÷ 0061 × 0308 × 0022 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] QUOTATION MARK (Close) ÷ [0.3]
÷ 0061 × 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [998.0] COMMA (SContinue) ÷ [0.3]
÷ 0061 × 0308 × 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] COMMA (SContinue) ÷ [0.3]
÷ 0061 × 00AD ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
÷ 0061 × 0308 × 00AD ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
÷ 0061 × 0300 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
÷ 0061 × 0308 × 0300 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
÷ 0041 × 0001 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [998.0] <START OF HEADING> (Other) ÷ [0.3]
÷ 0041 × 0308 × 0001 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <START OF HEADING> (Other) ÷ [0.3]
÷ 0041 × 000D ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [998.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
÷ 0041 × 0308 × 000D ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
÷ 0041 × 000A ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [998.0] <LINE FEED (LF)> (LF) ÷ [0.3]
÷ 0041 × 0308 × 000A ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <LINE FEED (LF)> (LF) ÷ [0.3]
÷ 0041 × 0085 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [998.0] <NEXT LINE (NEL)> (Sep) ÷ [0.3]
÷ 0041 × 0308 × 0085 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <NEXT LINE (NEL)> (Sep) ÷ [0.3]
÷ 0041 × 0009 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [998.0] <CHARACTER TABULATION> (Sp) ÷ [0.3]
÷ 0041 × 0308 × 0009 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <CHARACTER TABULATION> (Sp) ÷ [0.3]
÷ 0041 × 0061 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
÷ 0041 × 0308 × 0061 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
÷ 0041 × 0041 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
÷ 0041 × 0308 × 0041 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
÷ 0041 × 01BB ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3]
÷ 0041 × 0308 × 01BB ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3]
÷ 0041 × 0030 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3]
÷ 0041 × 0308 × 0030 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3]
÷ 0041 × 002E ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [998.0] FULL STOP (ATerm) ÷ [0.3]
÷ 0041 × 0308 × 002E ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] FULL STOP (ATerm) ÷ [0.3]
÷ 0041 × 0021 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3]
÷ 0041 × 0308 × 0021 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3]
÷ 0041 × 0022 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [998.0] QUOTATION MARK (Close) ÷ [0.3]
÷ 0041 × 0308 × 0022 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] QUOTATION MARK (Close) ÷ [0.3]
÷ 0041 × 002C ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [998.0] COMMA (SContinue) ÷ [0.3]
÷ 0041 × 0308 × 002C ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] COMMA (SContinue) ÷ [0.3]
÷ 0041 × 00AD ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
÷ 0041 × 0308 × 00AD ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
÷ 0041 × 0300 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
÷ 0041 × 0308 × 0300 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
÷ 01BB × 0001 ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [998.0] <START OF HEADING> (Other) ÷ [0.3]
÷ 01BB × 0308 × 0001 ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <START OF HEADING> (Other) ÷ [0.3]
÷ 01BB × 000D ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [998.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
÷ 01BB × 0308 × 000D ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
÷ 01BB × 000A ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [998.0] <LINE FEED (LF)> (LF) ÷ [0.3]
÷ 01BB × 0308 × 000A ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <LINE FEED (LF)> (LF) ÷ [0.3]
÷ 01BB × 0085 ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [998.0] <NEXT LINE (NEL)> (Sep) ÷ [0.3]
÷ 01BB × 0308 × 0085 ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <NEXT LINE (NEL)> (Sep) ÷ [0.3]
÷ 01BB × 0009 ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [998.0] <CHARACTER TABULATION> (Sp) ÷ [0.3]
÷ 01BB × 0308 × 0009 ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <CHARACTER TABULATION> (Sp) ÷ [0.3]
÷ 01BB × 0061 ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
÷ 01BB × 0308 × 0061 ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
÷ 01BB × 0041 ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
÷ 01BB × 0308 × 0041 ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
÷ 01BB × 01BB ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3]
÷ 01BB × 0308 × 01BB ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3]
÷ 01BB × 0030 ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3]
÷ 01BB × 0308 × 0030 ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3]
÷ 01BB × 002E ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [998.0] FULL STOP (ATerm) ÷ [0.3]
÷ 01BB × 0308 × 002E ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] FULL STOP (ATerm) ÷ [0.3]
÷ 01BB × 0021 ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3]
÷ 01BB × 0308 × 0021 ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3]
÷ 01BB × 0022 ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [998.0] QUOTATION MARK (Close) ÷ [0.3]
÷ 01BB × 0308 × 0022 ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] QUOTATION MARK (Close) ÷ [0.3]
÷ 01BB × 002C ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [998.0] COMMA (SContinue) ÷ [0.3]
÷ 01BB × 0308 × 002C ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] COMMA (SContinue) ÷ [0.3]
÷ 01BB × 00AD ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
÷ 01BB × 0308 × 00AD ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
÷ 01BB × 0300 ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
÷ 01BB × 0308 × 0300 ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
÷ 0030 × 0001 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [998.0] <START OF HEADING> (Other) ÷ [0.3]
÷ 0030 × 0308 × 0001 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <START OF HEADING> (Other) ÷ [0.3]
÷ 0030 × 000D ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [998.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
÷ 0030 × 0308 × 000D ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
÷ 0030 × 000A ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [998.0] <LINE FEED (LF)> (LF) ÷ [0.3]
÷ 0030 × 0308 × 000A ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <LINE FEED (LF)> (LF) ÷ [0.3]
÷ 0030 × 0085 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [998.0] <NEXT LINE (NEL)> (Sep) ÷ [0.3]
÷ 0030 × 0308 × 0085 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <NEXT LINE (NEL)> (Sep) ÷ [0.3]
÷ 0030 × 0009 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [998.0] <CHARACTER TABULATION> (Sp) ÷ [0.3]
÷ 0030 × 0308 × 0009 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <CHARACTER TABULATION> (Sp) ÷ [0.3]
÷ 0030 × 0061 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
÷ 0030 × 0308 × 0061 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
÷ 0030 × 0041 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
÷ 0030 × 0308 × 0041 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
÷ 0030 × 01BB ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3]
÷ 0030 × 0308 × 01BB ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3]
÷ 0030 × 0030 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3]
÷ 0030 × 0308 × 0030 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3]
÷ 0030 × 002E ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [998.0] FULL STOP (ATerm) ÷ [0.3]
÷ 0030 × 0308 × 002E ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] FULL STOP (ATerm) ÷ [0.3]
÷ 0030 × 0021 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3]
÷ 0030 × 0308 × 0021 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3]
÷ 0030 × 0022 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [998.0] QUOTATION MARK (Close) ÷ [0.3]
÷ 0030 × 0308 × 0022 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] QUOTATION MARK (Close) ÷ [0.3]
÷ 0030 × 002C ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [998.0] COMMA (SContinue) ÷ [0.3]
÷ 0030 × 0308 × 002C ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] COMMA (SContinue) ÷ [0.3]
÷ 0030 × 00AD ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
÷ 0030 × 0308 × 00AD ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
÷ 0030 × 0300 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
÷ 0030 × 0308 × 0300 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
÷ 002E ÷ 0001 ÷ # ÷ [0.2] FULL STOP (ATerm) ÷ [11.0] <START OF HEADING> (Other) ÷ [0.3]
÷ 002E × 0308 ÷ 0001 ÷ # ÷ [0.2] FULL STOP (ATerm) × [5.0] COMBINING DIAERESIS (Extend_FE) ÷ [11.0] <START OF HEADING> (Other) ÷ [0.3]
÷ 002E × 000D ÷ # ÷ [0.2] FULL STOP (ATerm) × [9.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
÷ 002E × 0308 × 000D ÷ # ÷ [0.2] FULL STOP (ATerm) × [5.0] COMBINING DIAERESIS (Extend_FE) × [9.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
÷ 002E × 000A ÷ # ÷ [0.2] FULL STOP (ATerm) × [9.0] <LINE FEED (LF)> (LF) ÷ [0.3]
÷ 002E × 0308 × 000A ÷ # ÷ [0.2] FULL STOP (ATerm) × [5.0] COMBINING DIAERESIS (Extend_FE) × [9.0] <LINE FEED (LF)> (LF) ÷ [0.3]
÷ 002E × 0085 ÷ # ÷ [0.2] FULL STOP (ATerm) × [9.0] <NEXT LINE (NEL)> (Sep) ÷ [0.3]
÷ 002E × 0308 × 0085 ÷ # ÷ [0.2] FULL STOP (ATerm) × [5.0] COMBINING DIAERESIS (Extend_FE) × [9.0] <NEXT LINE (NEL)> (Sep) ÷ [0.3]
÷ 002E × 0009 ÷ # ÷ [0.2] FULL STOP (ATerm) × [9.0] <CHARACTER TABULATION> (Sp) ÷ [0.3]
÷ 002E × 0308 × 0009 ÷ # ÷ [0.2] FULL STOP (ATerm) × [5.0] COMBINING DIAERESIS (Extend_FE) × [9.0] <CHARACTER TABULATION> (Sp) ÷ [0.3]
÷ 002E × 0061 ÷ # ÷ [0.2] FULL STOP (ATerm) × [8.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
÷ 002E × 0308 × 0061 ÷ # ÷ [0.2] FULL STOP (ATerm) × [5.0] COMBINING DIAERESIS (Extend_FE) × [8.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
÷ 002E ÷ 0041 ÷ # ÷ [0.2] FULL STOP (ATerm) ÷ [11.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
÷ 002E × 0308 ÷ 0041 ÷ # ÷ [0.2] FULL STOP (ATerm) × [5.0] COMBINING DIAERESIS (Extend_FE) ÷ [11.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
÷ 002E ÷ 01BB ÷ # ÷ [0.2] FULL STOP (ATerm) ÷ [11.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3]
÷ 002E × 0308 ÷ 01BB ÷ # ÷ [0.2] FULL STOP (ATerm) × [5.0] COMBINING DIAERESIS (Extend_FE) ÷ [11.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3]
÷ 002E × 0030 ÷ # ÷ [0.2] FULL STOP (ATerm) × [6.0] DIGIT ZERO (Numeric) ÷ [0.3]
÷ 002E × 0308 × 0030 ÷ # ÷ [0.2] FULL STOP (ATerm) × [5.0] COMBINING DIAERESIS (Extend_FE) × [6.0] DIGIT ZERO (Numeric) ÷ [0.3]
÷ 002E × 002E ÷ # ÷ [0.2] FULL STOP (ATerm) × [8.1] FULL STOP (ATerm) ÷ [0.3]
÷ 002E × 0308 × 002E ÷ # ÷ [0.2] FULL STOP (ATerm) × [5.0] COMBINING DIAERESIS (Extend_FE) × [8.1] FULL STOP (ATerm) ÷ [0.3]
÷ 002E × 0021 ÷ # ÷ [0.2] FULL STOP (ATerm) × [8.1] EXCLAMATION MARK (STerm) ÷ [0.3]
÷ 002E × 0308 × 0021 ÷ # ÷ [0.2] FULL STOP (ATerm) × [5.0] COMBINING DIAERESIS (Extend_FE) × [8.1] EXCLAMATION MARK (STerm) ÷ [0.3]
÷ 002E × 0022 ÷ # ÷ [0.2] FULL STOP (ATerm) × [9.0] QUOTATION MARK (Close) ÷ [0.3]
÷ 002E × 0308 × 0022 ÷ # ÷ [0.2] FULL STOP (ATerm) × [5.0] COMBINING DIAERESIS (Extend_FE) × [9.0] QUOTATION MARK (Close) ÷ [0.3]
÷ 002E × 002C ÷ # ÷ [0.2] FULL STOP (ATerm) × [8.1] COMMA (SContinue) ÷ [0.3]
÷ 002E × 0308 × 002C ÷ # ÷ [0.2] FULL STOP (ATerm) × [5.0] COMBINING DIAERESIS (Extend_FE) × [8.1] COMMA (SContinue) ÷ [0.3]
÷ 002E × 00AD ÷ # ÷ [0.2] FULL STOP (ATerm) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
÷ 002E × 0308 × 00AD ÷ # ÷ [0.2] FULL STOP (ATerm) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
÷ 002E × 0300 ÷ # ÷ [0.2] FULL STOP (ATerm) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
÷ 002E × 0308 × 0300 ÷ # ÷ [0.2] FULL STOP (ATerm) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
÷ 0021 ÷ 0001 ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) ÷ [11.0] <START OF HEADING> (Other) ÷ [0.3]
÷ 0021 × 0308 ÷ 0001 ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [5.0] COMBINING DIAERESIS (Extend_FE) ÷ [11.0] <START OF HEADING> (Other) ÷ [0.3]
÷ 0021 × 000D ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [9.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
÷ 0021 × 0308 × 000D ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [5.0] COMBINING DIAERESIS (Extend_FE) × [9.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
÷ 0021 × 000A ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [9.0] <LINE FEED (LF)> (LF) ÷ [0.3]
÷ 0021 × 0308 × 000A ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [5.0] COMBINING DIAERESIS (Extend_FE) × [9.0] <LINE FEED (LF)> (LF) ÷ [0.3]
÷ 0021 × 0085 ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [9.0] <NEXT LINE (NEL)> (Sep) ÷ [0.3]
÷ 0021 × 0308 × 0085 ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [5.0] COMBINING DIAERESIS (Extend_FE) × [9.0] <NEXT LINE (NEL)> (Sep) ÷ [0.3]
÷ 0021 × 0009 ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [9.0] <CHARACTER TABULATION> (Sp) ÷ [0.3]
÷ 0021 × 0308 × 0009 ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [5.0] COMBINING DIAERESIS (Extend_FE) × [9.0] <CHARACTER TABULATION> (Sp) ÷ [0.3]
÷ 0021 ÷ 0061 ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) ÷ [11.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
÷ 0021 × 0308 ÷ 0061 ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [5.0] COMBINING DIAERESIS (Extend_FE) ÷ [11.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
÷ 0021 ÷ 0041 ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) ÷ [11.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
÷ 0021 × 0308 ÷ 0041 ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [5.0] COMBINING DIAERESIS (Extend_FE) ÷ [11.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
÷ 0021 ÷ 01BB ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) ÷ [11.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3]
÷ 0021 × 0308 ÷ 01BB ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [5.0] COMBINING DIAERESIS (Extend_FE) ÷ [11.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3]
÷ 0021 ÷ 0030 ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) ÷ [11.0] DIGIT ZERO (Numeric) ÷ [0.3]
÷ 0021 × 0308 ÷ 0030 ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [5.0] COMBINING DIAERESIS (Extend_FE) ÷ [11.0] DIGIT ZERO (Numeric) ÷ [0.3]
÷ 0021 × 002E ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [8.1] FULL STOP (ATerm) ÷ [0.3]
÷ 0021 × 0308 × 002E ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [5.0] COMBINING DIAERESIS (Extend_FE) × [8.1] FULL STOP (ATerm) ÷ [0.3]
÷ 0021 × 0021 ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [8.1] EXCLAMATION MARK (STerm) ÷ [0.3]
÷ 0021 × 0308 × 0021 ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [5.0] COMBINING DIAERESIS (Extend_FE) × [8.1] EXCLAMATION MARK (STerm) ÷ [0.3]
÷ 0021 × 0022 ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [9.0] QUOTATION MARK (Close) ÷ [0.3]
÷ 0021 × 0308 × 0022 ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [5.0] COMBINING DIAERESIS (Extend_FE) × [9.0] QUOTATION MARK (Close) ÷ [0.3]
÷ 0021 × 002C ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [8.1] COMMA (SContinue) ÷ [0.3]
÷ 0021 × 0308 × 002C ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [5.0] COMBINING DIAERESIS (Extend_FE) × [8.1] COMMA (SContinue) ÷ [0.3]
÷ 0021 × 00AD ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
÷ 0021 × 0308 × 00AD ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
÷ 0021 × 0300 ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
÷ 0021 × 0308 × 0300 ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
÷ 0022 × 0001 ÷ # ÷ [0.2] QUOTATION MARK (Close) × [998.0] <START OF HEADING> (Other) ÷ [0.3]
÷ 0022 × 0308 × 0001 ÷ # ÷ [0.2] QUOTATION MARK (Close) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <START OF HEADING> (Other) ÷ [0.3]
÷ 0022 × 000D ÷ # ÷ [0.2] QUOTATION MARK (Close) × [998.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
÷ 0022 × 0308 × 000D ÷ # ÷ [0.2] QUOTATION MARK (Close) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
÷ 0022 × 000A ÷ # ÷ [0.2] QUOTATION MARK (Close) × [998.0] <LINE FEED (LF)> (LF) ÷ [0.3]
÷ 0022 × 0308 × 000A ÷ # ÷ [0.2] QUOTATION MARK (Close) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <LINE FEED (LF)> (LF) ÷ [0.3]
÷ 0022 × 0085 ÷ # ÷ [0.2] QUOTATION MARK (Close) × [998.0] <NEXT LINE (NEL)> (Sep) ÷ [0.3]
÷ 0022 × 0308 × 0085 ÷ # ÷ [0.2] QUOTATION MARK (Close) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <NEXT LINE (NEL)> (Sep) ÷ [0.3]
÷ 0022 × 0009 ÷ # ÷ [0.2] QUOTATION MARK (Close) × [998.0] <CHARACTER TABULATION> (Sp) ÷ [0.3]
÷ 0022 × 0308 × 0009 ÷ # ÷ [0.2] QUOTATION MARK (Close) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <CHARACTER TABULATION> (Sp) ÷ [0.3]
÷ 0022 × 0061 ÷ # ÷ [0.2] QUOTATION MARK (Close) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
÷ 0022 × 0308 × 0061 ÷ # ÷ [0.2] QUOTATION MARK (Close) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
÷ 0022 × 0041 ÷ # ÷ [0.2] QUOTATION MARK (Close) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
÷ 0022 × 0308 × 0041 ÷ # ÷ [0.2] QUOTATION MARK (Close) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
÷ 0022 × 01BB ÷ # ÷ [0.2] QUOTATION MARK (Close) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3]
÷ 0022 × 0308 × 01BB ÷ # ÷ [0.2] QUOTATION MARK (Close) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3]
÷ 0022 × 0030 ÷ # ÷ [0.2] QUOTATION MARK (Close) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3]
÷ 0022 × 0308 × 0030 ÷ # ÷ [0.2] QUOTATION MARK (Close) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3]
÷ 0022 × 002E ÷ # ÷ [0.2] QUOTATION MARK (Close) × [998.0] FULL STOP (ATerm) ÷ [0.3]
÷ 0022 × 0308 × 002E ÷ # ÷ [0.2] QUOTATION MARK (Close) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] FULL STOP (ATerm) ÷ [0.3]
÷ 0022 × 0021 ÷ # ÷ [0.2] QUOTATION MARK (Close) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3]
÷ 0022 × 0308 × 0021 ÷ # ÷ [0.2] QUOTATION MARK (Close) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3]
÷ 0022 × 0022 ÷ # ÷ [0.2] QUOTATION MARK (Close) × [998.0] QUOTATION MARK (Close) ÷ [0.3]
÷ 0022 × 0308 × 0022 ÷ # ÷ [0.2] QUOTATION MARK (Close) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] QUOTATION MARK (Close) ÷ [0.3]
÷ 0022 × 002C ÷ # ÷ [0.2] QUOTATION MARK (Close) × [998.0] COMMA (SContinue) ÷ [0.3]
÷ 0022 × 0308 × 002C ÷ # ÷ [0.2] QUOTATION MARK (Close) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] COMMA (SContinue) ÷ [0.3]
÷ 0022 × 00AD ÷ # ÷ [0.2] QUOTATION MARK (Close) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
÷ 0022 × 0308 × 00AD ÷ # ÷ [0.2] QUOTATION MARK (Close) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
÷ 0022 × 0300 ÷ # ÷ [0.2] QUOTATION MARK (Close) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
÷ 0022 × 0308 × 0300 ÷ # ÷ [0.2] QUOTATION MARK (Close) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
÷ 002C × 0001 ÷ # ÷ [0.2] COMMA (SContinue) × [998.0] <START OF HEADING> (Other) ÷ [0.3]
÷ 002C × 0308 × 0001 ÷ # ÷ [0.2] COMMA (SContinue) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <START OF HEADING> (Other) ÷ [0.3]
÷ 002C × 000D ÷ # ÷ [0.2] COMMA (SContinue) × [998.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
÷ 002C × 0308 × 000D ÷ # ÷ [0.2] COMMA (SContinue) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
÷ 002C × 000A ÷ # ÷ [0.2] COMMA (SContinue) × [998.0] <LINE FEED (LF)> (LF) ÷ [0.3]
÷ 002C × 0308 × 000A ÷ # ÷ [0.2] COMMA (SContinue) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <LINE FEED (LF)> (LF) ÷ [0.3]
÷ 002C × 0085 ÷ # ÷ [0.2] COMMA (SContinue) × [998.0] <NEXT LINE (NEL)> (Sep) ÷ [0.3]
÷ 002C × 0308 × 0085 ÷ # ÷ [0.2] COMMA (SContinue) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <NEXT LINE (NEL)> (Sep) ÷ [0.3]
÷ 002C × 0009 ÷ # ÷ [0.2] COMMA (SContinue) × [998.0] <CHARACTER TABULATION> (Sp) ÷ [0.3]
÷ 002C × 0308 × 0009 ÷ # ÷ [0.2] COMMA (SContinue) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <CHARACTER TABULATION> (Sp) ÷ [0.3]
÷ 002C × 0061 ÷ # ÷ [0.2] COMMA (SContinue) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
÷ 002C × 0308 × 0061 ÷ # ÷ [0.2] COMMA (SContinue) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
÷ 002C × 0041 ÷ # ÷ [0.2] COMMA (SContinue) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
÷ 002C × 0308 × 0041 ÷ # ÷ [0.2] COMMA (SContinue) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
÷ 002C × 01BB ÷ # ÷ [0.2] COMMA (SContinue) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3]
÷ 002C × 0308 × 01BB ÷ # ÷ [0.2] COMMA (SContinue) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3]
÷ 002C × 0030 ÷ # ÷ [0.2] COMMA (SContinue) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3]
÷ 002C × 0308 × 0030 ÷ # ÷ [0.2] COMMA (SContinue) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3]
÷ 002C × 002E ÷ # ÷ [0.2] COMMA (SContinue) × [998.0] FULL STOP (ATerm) ÷ [0.3]
÷ 002C × 0308 × 002E ÷ # ÷ [0.2] COMMA (SContinue) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] FULL STOP (ATerm) ÷ [0.3]
÷ 002C × 0021 ÷ # ÷ [0.2] COMMA (SContinue) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3]
÷ 002C × 0308 × 0021 ÷ # ÷ [0.2] COMMA (SContinue) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3]
÷ 002C × 0022 ÷ # ÷ [0.2] COMMA (SContinue) × [998.0] QUOTATION MARK (Close) ÷ [0.3]
÷ 002C × 0308 × 0022 ÷ # ÷ [0.2] COMMA (SContinue) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] QUOTATION MARK (Close) ÷ [0.3]
÷ 002C × 002C ÷ # ÷ [0.2] COMMA (SContinue) × [998.0] COMMA (SContinue) ÷ [0.3]
÷ 002C × 0308 × 002C ÷ # ÷ [0.2] COMMA (SContinue) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] COMMA (SContinue) ÷ [0.3]
÷ 002C × 00AD ÷ # ÷ [0.2] COMMA (SContinue) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
÷ 002C × 0308 × 00AD ÷ # ÷ [0.2] COMMA (SContinue) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
÷ 002C × 0300 ÷ # ÷ [0.2] COMMA (SContinue) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
÷ 002C × 0308 × 0300 ÷ # ÷ [0.2] COMMA (SContinue) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
÷ 00AD × 0001 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [998.0] <START OF HEADING> (Other) ÷ [0.3]
÷ 00AD × 0308 × 0001 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <START OF HEADING> (Other) ÷ [0.3]
÷ 00AD × 000D ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [998.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
÷ 00AD × 0308 × 000D ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
÷ 00AD × 000A ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [998.0] <LINE FEED (LF)> (LF) ÷ [0.3]
÷ 00AD × 0308 × 000A ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <LINE FEED (LF)> (LF) ÷ [0.3]
÷ 00AD × 0085 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [998.0] <NEXT LINE (NEL)> (Sep) ÷ [0.3]
÷ 00AD × 0308 × 0085 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <NEXT LINE (NEL)> (Sep) ÷ [0.3]
÷ 00AD × 0009 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [998.0] <CHARACTER TABULATION> (Sp) ÷ [0.3]
÷ 00AD × 0308 × 0009 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <CHARACTER TABULATION> (Sp) ÷ [0.3]
÷ 00AD × 0061 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
÷ 00AD × 0308 × 0061 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
÷ 00AD × 0041 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
÷ 00AD × 0308 × 0041 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
÷ 00AD × 01BB ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3]
÷ 00AD × 0308 × 01BB ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3]
÷ 00AD × 0030 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3]
÷ 00AD × 0308 × 0030 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3]
÷ 00AD × 002E ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [998.0] FULL STOP (ATerm) ÷ [0.3]
÷ 00AD × 0308 × 002E ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] FULL STOP (ATerm) ÷ [0.3]
÷ 00AD × 0021 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3]
÷ 00AD × 0308 × 0021 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3]
÷ 00AD × 0022 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [998.0] QUOTATION MARK (Close) ÷ [0.3]
÷ 00AD × 0308 × 0022 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] QUOTATION MARK (Close) ÷ [0.3]
÷ 00AD × 002C ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [998.0] COMMA (SContinue) ÷ [0.3]
÷ 00AD × 0308 × 002C ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] COMMA (SContinue) ÷ [0.3]
÷ 00AD × 00AD ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
÷ 00AD × 0308 × 00AD ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
÷ 00AD × 0300 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
÷ 00AD × 0308 × 0300 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
÷ 0300 × 0001 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [998.0] <START OF HEADING> (Other) ÷ [0.3]
÷ 0300 × 0308 × 0001 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <START OF HEADING> (Other) ÷ [0.3]
÷ 0300 × 000D ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [998.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
÷ 0300 × 0308 × 000D ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
÷ 0300 × 000A ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [998.0] <LINE FEED (LF)> (LF) ÷ [0.3]
÷ 0300 × 0308 × 000A ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <LINE FEED (LF)> (LF) ÷ [0.3]
÷ 0300 × 0085 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [998.0] <NEXT LINE (NEL)> (Sep) ÷ [0.3]
÷ 0300 × 0308 × 0085 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <NEXT LINE (NEL)> (Sep) ÷ [0.3]
÷ 0300 × 0009 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [998.0] <CHARACTER TABULATION> (Sp) ÷ [0.3]
÷ 0300 × 0308 × 0009 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <CHARACTER TABULATION> (Sp) ÷ [0.3]
÷ 0300 × 0061 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
÷ 0300 × 0308 × 0061 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
÷ 0300 × 0041 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
÷ 0300 × 0308 × 0041 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
÷ 0300 × 01BB ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3]
÷ 0300 × 0308 × 01BB ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3]
÷ 0300 × 0030 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3]
÷ 0300 × 0308 × 0030 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3]
÷ 0300 × 002E ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [998.0] FULL STOP (ATerm) ÷ [0.3]
÷ 0300 × 0308 × 002E ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] FULL STOP (ATerm) ÷ [0.3]
÷ 0300 × 0021 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3]
÷ 0300 × 0308 × 0021 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3]
÷ 0300 × 0022 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [998.0] QUOTATION MARK (Close) ÷ [0.3]
÷ 0300 × 0308 × 0022 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] QUOTATION MARK (Close) ÷ [0.3]
÷ 0300 × 002C ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [998.0] COMMA (SContinue) ÷ [0.3]
÷ 0300 × 0308 × 002C ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] COMMA (SContinue) ÷ [0.3]
÷ 0300 × 00AD ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
÷ 0300 × 0308 × 00AD ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
÷ 0300 × 0300 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
÷ 0300 × 0308 × 0300 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
÷ 000D × 000A ÷ 0061 × 000A ÷ 0308 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) × [3.0] <LINE FEED (LF)> (LF) ÷ [4.0] LATIN SMALL LETTER A (Lower) × [998.0] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [0.3]
÷ 0061 × 0308 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [5.0] COMBINING DIAERESIS (Extend_FE) ÷ [0.3]
÷ 0020 × 200D × 0646 ÷ # ÷ [0.2] SPACE (Sp) × [5.0] ZERO WIDTH JOINER (Extend_FE) × [998.0] ARABIC LETTER NOON (OLetter) ÷ [0.3]
÷ 0646 × 200D × 0020 ÷ # ÷ [0.2] ARABIC LETTER NOON (OLetter) × [5.0] ZERO WIDTH JOINER (Extend_FE) × [998.0] SPACE (Sp) ÷ [0.3]
÷ 0028 × 0022 × 0047 × 006F × 002E × 0022 × 0029 × 0020 ÷ 0028 × 0048 × 0065 × 0020 × 0064 × 0069 × 0064 × 002E × 0029 ÷ # ÷ [0.2] LEFT PARENTHESIS (Close) × [998.0] QUOTATION MARK (Close) × [998.0] LATIN CAPITAL LETTER G (Upper) × [998.0] LATIN SMALL LETTER O (Lower) × [998.0] FULL STOP (ATerm) × [9.0] QUOTATION MARK (Close) × [9.0] RIGHT PARENTHESIS (Close) × [9.0] SPACE (Sp) ÷ [11.0] LEFT PARENTHESIS (Close) × [998.0] LATIN CAPITAL LETTER H (Upper) × [998.0] LATIN SMALL LETTER E (Lower) × [998.0] SPACE (Sp) × [998.0] LATIN SMALL LETTER D (Lower) × [998.0] LATIN SMALL LETTER I (Lower) × [998.0] LATIN SMALL LETTER D (Lower) × [998.0] FULL STOP (ATerm) × [9.0] RIGHT PARENTHESIS (Close) ÷ [0.3]
÷ 0028 × 201C × 0047 × 006F × 003F × 201D × 0029 × 0020 ÷ 0028 × 0048 × 0065 × 0020 × 0064 × 0069 × 0064 × 002E × 0029 ÷ # ÷ [0.2] LEFT PARENTHESIS (Close) × [998.0] LEFT DOUBLE QUOTATION MARK (Close) × [998.0] LATIN CAPITAL LETTER G (Upper) × [998.0] LATIN SMALL LETTER O (Lower) × [998.0] QUESTION MARK (STerm) × [9.0] RIGHT DOUBLE QUOTATION MARK (Close) × [9.0] RIGHT PARENTHESIS (Close) × [9.0] SPACE (Sp) ÷ [11.0] LEFT PARENTHESIS (Close) × [998.0] LATIN CAPITAL LETTER H (Upper) × [998.0] LATIN SMALL LETTER E (Lower) × [998.0] SPACE (Sp) × [998.0] LATIN SMALL LETTER D (Lower) × [998.0] LATIN SMALL LETTER I (Lower) × [998.0] LATIN SMALL LETTER D (Lower) × [998.0] FULL STOP (ATerm) × [9.0] RIGHT PARENTHESIS (Close) ÷ [0.3]
÷ 0055 × 002E × 0053 × 002E × 0041 × 0300 × 002E × 0020 × 0069 × 0073 ÷ # ÷ [0.2] LATIN CAPITAL LETTER U (Upper) × [998.0] FULL STOP (ATerm) × [7.0] LATIN CAPITAL LETTER S (Upper) × [998.0] FULL STOP (ATerm) × [7.0] LATIN CAPITAL LETTER A (Upper) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) × [998.0] FULL STOP (ATerm) × [8.0] SPACE (Sp) × [8.0] LATIN SMALL LETTER I (Lower) × [998.0] LATIN SMALL LETTER S (Lower) ÷ [0.3]
÷ 0055 × 002E × 0053 × 002E × 0041 × 0300 × 003F × 0020 ÷ 0048 × 0065 ÷ # ÷ [0.2] LATIN CAPITAL LETTER U (Upper) × [998.0] FULL STOP (ATerm) × [7.0] LATIN CAPITAL LETTER S (Upper) × [998.0] FULL STOP (ATerm) × [7.0] LATIN CAPITAL LETTER A (Upper) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) × [998.0] QUESTION MARK (STerm) × [9.0] SPACE (Sp) ÷ [11.0] LATIN CAPITAL LETTER H (Upper) × [998.0] LATIN SMALL LETTER E (Lower) ÷ [0.3]
÷ 0055 × 002E × 0053 × 002E × 0041 × 0300 × 002E ÷ # ÷ [0.2] LATIN CAPITAL LETTER U (Upper) × [998.0] FULL STOP (ATerm) × [7.0] LATIN CAPITAL LETTER S (Upper) × [998.0] FULL STOP (ATerm) × [7.0] LATIN CAPITAL LETTER A (Upper) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) × [998.0] FULL STOP (ATerm) ÷ [0.3]
÷ 0033 × 002E × 0034 ÷ # ÷ [0.2] DIGIT THREE (Numeric) × [998.0] FULL STOP (ATerm) × [6.0] DIGIT FOUR (Numeric) ÷ [0.3]
÷ 0063 × 002E × 0064 ÷ # ÷ [0.2] LATIN SMALL LETTER C (Lower) × [998.0] FULL STOP (ATerm) × [8.0] LATIN SMALL LETTER D (Lower) ÷ [0.3]
÷ 0043 × 002E × 0064 ÷ # ÷ [0.2] LATIN CAPITAL LETTER C (Upper) × [998.0] FULL STOP (ATerm) × [8.0] LATIN SMALL LETTER D (Lower) ÷ [0.3]
÷ 0063 × 002E × 0044 ÷ # ÷ [0.2] LATIN SMALL LETTER C (Lower) × [998.0] FULL STOP (ATerm) × [7.0] LATIN CAPITAL LETTER D (Upper) ÷ [0.3]
÷ 0043 × 002E × 0044 ÷ # ÷ [0.2] LATIN CAPITAL LETTER C (Upper) × [998.0] FULL STOP (ATerm) × [7.0] LATIN CAPITAL LETTER D (Upper) ÷ [0.3]
÷ 0065 × 0074 × 0063 × 002E × 0029 × 2019 × 00A0 × 0074 × 0068 × 0065 ÷ # ÷ [0.2] LATIN SMALL LETTER E (Lower) × [998.0] LATIN SMALL LETTER T (Lower) × [998.0] LATIN SMALL LETTER C (Lower) × [998.0] FULL STOP (ATerm) × [8.0] RIGHT PARENTHESIS (Close) × [8.0] RIGHT SINGLE QUOTATION MARK (Close) × [8.0] NO-BREAK SPACE (Sp) × [8.0] LATIN SMALL LETTER T (Lower) × [998.0] LATIN SMALL LETTER H (Lower) × [998.0] LATIN SMALL LETTER E (Lower) ÷ [0.3]
÷ 0065 × 0074 × 0063 × 002E × 0029 × 2019 × 00A0 ÷ 0054 × 0068 × 0065 ÷ # ÷ [0.2] LATIN SMALL LETTER E (Lower) × [998.0] LATIN SMALL LETTER T (Lower) × [998.0] LATIN SMALL LETTER C (Lower) × [998.0] FULL STOP (ATerm) × [9.0] RIGHT PARENTHESIS (Close) × [9.0] RIGHT SINGLE QUOTATION MARK (Close) × [9.0] NO-BREAK SPACE (Sp) ÷ [11.0] LATIN CAPITAL LETTER T (Upper) × [998.0] LATIN SMALL LETTER H (Lower) × [998.0] LATIN SMALL LETTER E (Lower) ÷ [0.3]
÷ 0065 × 0074 × 0063 × 002E × 0029 × 2019 × 00A0 × 2018 × 0028 × 0074 × 0068 × 0065 ÷ # ÷ [0.2] LATIN SMALL LETTER E (Lower) × [998.0] LATIN SMALL LETTER T (Lower) × [998.0] LATIN SMALL LETTER C (Lower) × [998.0] FULL STOP (ATerm) × [8.0] RIGHT PARENTHESIS (Close) × [8.0] RIGHT SINGLE QUOTATION MARK (Close) × [8.0] NO-BREAK SPACE (Sp) × [8.0] LEFT SINGLE QUOTATION MARK (Close) × [998.0] LEFT PARENTHESIS (Close) × [998.0] LATIN SMALL LETTER T (Lower) × [998.0] LATIN SMALL LETTER H (Lower) × [998.0] LATIN SMALL LETTER E (Lower) ÷ [0.3]
÷ 0065 × 0074 × 0063 × 002E × 0029 × 2019 × 00A0 ÷ 2018 × 0028 × 0054 × 0068 × 0065 ÷ # ÷ [0.2] LATIN SMALL LETTER E (Lower) × [998.0] LATIN SMALL LETTER T (Lower) × [998.0] LATIN SMALL LETTER C (Lower) × [998.0] FULL STOP (ATerm) × [9.0] RIGHT PARENTHESIS (Close) × [9.0] RIGHT SINGLE QUOTATION MARK (Close) × [9.0] NO-BREAK SPACE (Sp) ÷ [11.0] LEFT SINGLE QUOTATION MARK (Close) × [998.0] LEFT PARENTHESIS (Close) × [998.0] LATIN CAPITAL LETTER T (Upper) × [998.0] LATIN SMALL LETTER H (Lower) × [998.0] LATIN SMALL LETTER E (Lower) ÷ [0.3]
÷ 0065 × 0074 × 0063 × 002E × 0029 × 2019 × 00A0 × 0308 × 0074 × 0068 × 0065 ÷ # ÷ [0.2] LATIN SMALL LETTER E (Lower) × [998.0] LATIN SMALL LETTER T (Lower) × [998.0] LATIN SMALL LETTER C (Lower) × [998.0] FULL STOP (ATerm) × [8.0] RIGHT PARENTHESIS (Close) × [8.0] RIGHT SINGLE QUOTATION MARK (Close) × [8.0] NO-BREAK SPACE (Sp) × [5.0] COMBINING DIAERESIS (Extend_FE) × [8.0] LATIN SMALL LETTER T (Lower) × [998.0] LATIN SMALL LETTER H (Lower) × [998.0] LATIN SMALL LETTER E (Lower) ÷ [0.3]
÷ 0065 × 0074 × 0063 × 002E × 0029 × 2019 × 00A0 × 0308 ÷ 0054 × 0068 × 0065 ÷ # ÷ [0.2] LATIN SMALL LETTER E (Lower) × [998.0] LATIN SMALL LETTER T (Lower) × [998.0] LATIN SMALL LETTER C (Lower) × [998.0] FULL STOP (ATerm) × [9.0] RIGHT PARENTHESIS (Close) × [9.0] RIGHT SINGLE QUOTATION MARK (Close) × [9.0] NO-BREAK SPACE (Sp) × [5.0] COMBINING DIAERESIS (Extend_FE) ÷ [11.0] LATIN CAPITAL LETTER T (Upper) × [998.0] LATIN SMALL LETTER H (Lower) × [998.0] LATIN SMALL LETTER E (Lower) ÷ [0.3]
÷ 0065 × 0074 × 0063 × 002E × 0029 × 2019 × 0308 ÷ 0054 × 0068 × 0065 ÷ # ÷ [0.2] LATIN SMALL LETTER E (Lower) × [998.0] LATIN SMALL LETTER T (Lower) × [998.0] LATIN SMALL LETTER C (Lower) × [998.0] FULL STOP (ATerm) × [9.0] RIGHT PARENTHESIS (Close) × [9.0] RIGHT SINGLE QUOTATION MARK (Close) × [5.0] COMBINING DIAERESIS (Extend_FE) ÷ [11.0] LATIN CAPITAL LETTER T (Upper) × [998.0] LATIN SMALL LETTER H (Lower) × [998.0] LATIN SMALL LETTER E (Lower) ÷ [0.3]
÷ 0065 × 0074 × 0063 × 002E × 0029 × 000A ÷ 0308 × 0054 × 0068 × 0065 ÷ # ÷ [0.2] LATIN SMALL LETTER E (Lower) × [998.0] LATIN SMALL LETTER T (Lower) × [998.0] LATIN SMALL LETTER C (Lower) × [998.0] FULL STOP (ATerm) × [9.0] RIGHT PARENTHESIS (Close) × [9.0] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN CAPITAL LETTER T (Upper) × [998.0] LATIN SMALL LETTER H (Lower) × [998.0] LATIN SMALL LETTER E (Lower) ÷ [0.3]
÷ 0074 × 0068 × 0065 × 0020 × 0072 × 0065 × 0073 × 0070 × 002E × 0020 × 006C × 0065 × 0061 × 0064 × 0065 × 0072 × 0073 × 0020 × 0061 × 0072 × 0065 ÷ # ÷ [0.2] LATIN SMALL LETTER T (Lower) × [998.0] LATIN SMALL LETTER H (Lower) × [998.0] LATIN SMALL LETTER E (Lower) × [998.0] SPACE (Sp) × [998.0] LATIN SMALL LETTER R (Lower) × [998.0] LATIN SMALL LETTER E (Lower) × [998.0] LATIN SMALL LETTER S (Lower) × [998.0] LATIN SMALL LETTER P (Lower) × [998.0] FULL STOP (ATerm) × [8.0] SPACE (Sp) × [8.0] LATIN SMALL LETTER L (Lower) × [998.0] LATIN SMALL LETTER E (Lower) × [998.0] LATIN SMALL LETTER A (Lower) × [998.0] LATIN SMALL LETTER D (Lower) × [998.0] LATIN SMALL LETTER E (Lower) × [998.0] LATIN SMALL LETTER R (Lower) × [998.0] LATIN SMALL LETTER S (Lower) × [998.0] SPACE (Sp) × [998.0] LATIN SMALL LETTER A (Lower) × [998.0] LATIN SMALL LETTER R (Lower) × [998.0] LATIN SMALL LETTER E (Lower) ÷ [0.3]
÷ 5B57 × 002E ÷ 5B57 ÷ # ÷ [0.2] CJK UNIFIED IDEOGRAPH-5B57 (OLetter) × [998.0] FULL STOP (ATerm) ÷ [11.0] CJK UNIFIED IDEOGRAPH-5B57 (OLetter) ÷ [0.3]
÷ 0065 × 0074 × 0063 × 002E ÷ 5B83 ÷ # ÷ [0.2] LATIN SMALL LETTER E (Lower) × [998.0] LATIN SMALL LETTER T (Lower) × [998.0] LATIN SMALL LETTER C (Lower) × [998.0] FULL STOP (ATerm) ÷ [11.0] CJK UNIFIED IDEOGRAPH-5B83 (OLetter) ÷ [0.3]
÷ 0065 × 0074 × 0063 × 002E × 3002 ÷ # ÷ [0.2] LATIN SMALL LETTER E (Lower) × [998.0] LATIN SMALL LETTER T (Lower) × [998.0] LATIN SMALL LETTER C (Lower) × [998.0] FULL STOP (ATerm) × [8.1] IDEOGRAPHIC FULL STOP (STerm) ÷ [0.3]
÷ 5B57 × 3002 ÷ 5B83 ÷ # ÷ [0.2] CJK UNIFIED IDEOGRAPH-5B57 (OLetter) × [998.0] IDEOGRAPHIC FULL STOP (STerm) ÷ [11.0] CJK UNIFIED IDEOGRAPH-5B83 (OLetter) ÷ [0.3]
÷ 0021 × 0020 × 0020 ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [9.0] SPACE (Sp) × [10.0] SPACE (Sp) ÷ [0.3]
÷ 2060 × 0028 × 2060 × 0022 × 2060 × 0047 × 2060 × 006F × 2060 × 002E × 2060 × 0022 × 2060 × 0029 × 2060 × 0020 × 2060 ÷ 0028 × 2060 × 0048 × 2060 × 0065 × 2060 × 0020 × 2060 × 0064 × 2060 × 0069 × 2060 × 0064 × 2060 × 002E × 2060 × 0029 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] LEFT PARENTHESIS (Close) × [5.0] WORD JOINER (Format_FE) × [998.0] QUOTATION MARK (Close) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN CAPITAL LETTER G (Upper) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER O (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [9.0] QUOTATION MARK (Close) × [5.0] WORD JOINER (Format_FE) × [9.0] RIGHT PARENTHESIS (Close) × [5.0] WORD JOINER (Format_FE) × [9.0] SPACE (Sp) × [5.0] WORD JOINER (Format_FE) ÷ [11.0] LEFT PARENTHESIS (Close) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN CAPITAL LETTER H (Upper) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] SPACE (Sp) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER D (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER I (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER D (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [9.0] RIGHT PARENTHESIS (Close) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3]
÷ 2060 × 0028 × 2060 × 201C × 2060 × 0047 × 2060 × 006F × 2060 × 003F × 2060 × 201D × 2060 × 0029 × 2060 × 0020 × 2060 ÷ 0028 × 2060 × 0048 × 2060 × 0065 × 2060 × 0020 × 2060 × 0064 × 2060 × 0069 × 2060 × 0064 × 2060 × 002E × 2060 × 0029 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] LEFT PARENTHESIS (Close) × [5.0] WORD JOINER (Format_FE) × [998.0] LEFT DOUBLE QUOTATION MARK (Close) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN CAPITAL LETTER G (Upper) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER O (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] QUESTION MARK (STerm) × [5.0] WORD JOINER (Format_FE) × [9.0] RIGHT DOUBLE QUOTATION MARK (Close) × [5.0] WORD JOINER (Format_FE) × [9.0] RIGHT PARENTHESIS (Close) × [5.0] WORD JOINER (Format_FE) × [9.0] SPACE (Sp) × [5.0] WORD JOINER (Format_FE) ÷ [11.0] LEFT PARENTHESIS (Close) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN CAPITAL LETTER H (Upper) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] SPACE (Sp) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER D (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER I (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER D (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [9.0] RIGHT PARENTHESIS (Close) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3]
÷ 2060 × 0055 × 2060 × 002E × 2060 × 0053 × 2060 × 002E × 2060 × 0041 × 2060 × 0300 × 002E × 2060 × 0020 × 2060 × 0069 × 2060 × 0073 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] LATIN CAPITAL LETTER U (Upper) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [7.0] LATIN CAPITAL LETTER S (Upper) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [7.0] LATIN CAPITAL LETTER A (Upper) × [5.0] WORD JOINER (Format_FE) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [8.0] SPACE (Sp) × [5.0] WORD JOINER (Format_FE) × [8.0] LATIN SMALL LETTER I (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER S (Lower) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3]
÷ 2060 × 0055 × 2060 × 002E × 2060 × 0053 × 2060 × 002E × 2060 × 0041 × 2060 × 0300 × 003F × 2060 × 0020 × 2060 ÷ 0048 × 2060 × 0065 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] LATIN CAPITAL LETTER U (Upper) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [7.0] LATIN CAPITAL LETTER S (Upper) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [7.0] LATIN CAPITAL LETTER A (Upper) × [5.0] WORD JOINER (Format_FE) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) × [998.0] QUESTION MARK (STerm) × [5.0] WORD JOINER (Format_FE) × [9.0] SPACE (Sp) × [5.0] WORD JOINER (Format_FE) ÷ [11.0] LATIN CAPITAL LETTER H (Upper) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3]
÷ 2060 × 0055 × 2060 × 002E × 2060 × 0053 × 2060 × 002E × 2060 × 0041 × 2060 × 0300 × 002E × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] LATIN CAPITAL LETTER U (Upper) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [7.0] LATIN CAPITAL LETTER S (Upper) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [7.0] LATIN CAPITAL LETTER A (Upper) × [5.0] WORD JOINER (Format_FE) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3]
÷ 2060 × 0033 × 2060 × 002E × 2060 × 0034 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] DIGIT THREE (Numeric) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [6.0] DIGIT FOUR (Numeric) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3]
÷ 2060 × 0063 × 2060 × 002E × 2060 × 0064 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER C (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [8.0] LATIN SMALL LETTER D (Lower) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3]
÷ 2060 × 0043 × 2060 × 002E × 2060 × 0064 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] LATIN CAPITAL LETTER C (Upper) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [8.0] LATIN SMALL LETTER D (Lower) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3]
÷ 2060 × 0063 × 2060 × 002E × 2060 × 0044 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER C (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [7.0] LATIN CAPITAL LETTER D (Upper) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3]
÷ 2060 × 0043 × 2060 × 002E × 2060 × 0044 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] LATIN CAPITAL LETTER C (Upper) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [7.0] LATIN CAPITAL LETTER D (Upper) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3]
÷ 2060 × 0065 × 2060 × 0074 × 2060 × 0063 × 2060 × 002E × 2060 × 0029 × 2060 × 2019 × 2060 × 00A0 × 2060 × 0074 × 2060 × 0068 × 2060 × 0065 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER T (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER C (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [8.0] RIGHT PARENTHESIS (Close) × [5.0] WORD JOINER (Format_FE) × [8.0] RIGHT SINGLE QUOTATION MARK (Close) × [5.0] WORD JOINER (Format_FE) × [8.0] NO-BREAK SPACE (Sp) × [5.0] WORD JOINER (Format_FE) × [8.0] LATIN SMALL LETTER T (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER H (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3]
÷ 2060 × 0065 × 2060 × 0074 × 2060 × 0063 × 2060 × 002E × 2060 × 0029 × 2060 × 2019 × 2060 × 00A0 × 2060 ÷ 0054 × 2060 × 0068 × 2060 × 0065 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER T (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER C (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [9.0] RIGHT PARENTHESIS (Close) × [5.0] WORD JOINER (Format_FE) × [9.0] RIGHT SINGLE QUOTATION MARK (Close) × [5.0] WORD JOINER (Format_FE) × [9.0] NO-BREAK SPACE (Sp) × [5.0] WORD JOINER (Format_FE) ÷ [11.0] LATIN CAPITAL LETTER T (Upper) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER H (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3]
÷ 2060 × 0065 × 2060 × 0074 × 2060 × 0063 × 2060 × 002E × 2060 × 0029 × 2060 × 2019 × 2060 × 00A0 × 2060 × 2018 × 2060 × 0028 × 2060 × 0074 × 2060 × 0068 × 2060 × 0065 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER T (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER C (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [8.0] RIGHT PARENTHESIS (Close) × [5.0] WORD JOINER (Format_FE) × [8.0] RIGHT SINGLE QUOTATION MARK (Close) × [5.0] WORD JOINER (Format_FE) × [8.0] NO-BREAK SPACE (Sp) × [5.0] WORD JOINER (Format_FE) × [8.0] LEFT SINGLE QUOTATION MARK (Close) × [5.0] WORD JOINER (Format_FE) × [998.0] LEFT PARENTHESIS (Close) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER T (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER H (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3]
÷ 2060 × 0065 × 2060 × 0074 × 2060 × 0063 × 2060 × 002E × 2060 × 0029 × 2060 × 2019 × 2060 × 00A0 × 2060 ÷ 2018 × 2060 × 0028 × 2060 × 0054 × 2060 × 0068 × 2060 × 0065 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER T (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER C (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [9.0] RIGHT PARENTHESIS (Close) × [5.0] WORD JOINER (Format_FE) × [9.0] RIGHT SINGLE QUOTATION MARK (Close) × [5.0] WORD JOINER (Format_FE) × [9.0] NO-BREAK SPACE (Sp) × [5.0] WORD JOINER (Format_FE) ÷ [11.0] LEFT SINGLE QUOTATION MARK (Close) × [5.0] WORD JOINER (Format_FE) × [998.0] LEFT PARENTHESIS (Close) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN CAPITAL LETTER T (Upper) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER H (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3]
÷ 2060 × 0065 × 2060 × 0074 × 2060 × 0063 × 2060 × 002E × 2060 × 0029 × 2060 × 2019 × 2060 × 00A0 × 2060 × 0308 × 0074 × 2060 × 0068 × 2060 × 0065 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER T (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER C (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [8.0] RIGHT PARENTHESIS (Close) × [5.0] WORD JOINER (Format_FE) × [8.0] RIGHT SINGLE QUOTATION MARK (Close) × [5.0] WORD JOINER (Format_FE) × [8.0] NO-BREAK SPACE (Sp) × [5.0] WORD JOINER (Format_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [8.0] LATIN SMALL LETTER T (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER H (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3]
÷ 2060 × 0065 × 2060 × 0074 × 2060 × 0063 × 2060 × 002E × 2060 × 0029 × 2060 × 2019 × 2060 × 00A0 × 2060 × 0308 ÷ 0054 × 2060 × 0068 × 2060 × 0065 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER T (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER C (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [9.0] RIGHT PARENTHESIS (Close) × [5.0] WORD JOINER (Format_FE) × [9.0] RIGHT SINGLE QUOTATION MARK (Close) × [5.0] WORD JOINER (Format_FE) × [9.0] NO-BREAK SPACE (Sp) × [5.0] WORD JOINER (Format_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) ÷ [11.0] LATIN CAPITAL LETTER T (Upper) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER H (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3]
÷ 2060 × 0065 × 2060 × 0074 × 2060 × 0063 × 2060 × 002E × 2060 × 0029 × 2060 × 2019 × 2060 × 0308 ÷ 0054 × 2060 × 0068 × 2060 × 0065 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER T (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER C (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [9.0] RIGHT PARENTHESIS (Close) × [5.0] WORD JOINER (Format_FE) × [9.0] RIGHT SINGLE QUOTATION MARK (Close) × [5.0] WORD JOINER (Format_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) ÷ [11.0] LATIN CAPITAL LETTER T (Upper) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER H (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3]
÷ 2060 × 0065 × 2060 × 0074 × 2060 × 0063 × 2060 × 002E × 2060 × 0029 × 2060 × 000A ÷ 2060 × 0308 × 2060 × 0054 × 2060 × 0068 × 2060 × 0065 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER T (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER C (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [9.0] RIGHT PARENTHESIS (Close) × [5.0] WORD JOINER (Format_FE) × [9.0] <LINE FEED (LF)> (LF) ÷ [4.0] WORD JOINER (Format_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN CAPITAL LETTER T (Upper) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER H (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3]
÷ 2060 × 0074 × 2060 × 0068 × 2060 × 0065 × 2060 × 0020 × 2060 × 0072 × 2060 × 0065 × 2060 × 0073 × 2060 × 0070 × 2060 × 002E × 2060 × 0020 × 2060 × 006C × 2060 × 0065 × 2060 × 0061 × 2060 × 0064 × 2060 × 0065 × 2060 × 0072 × 2060 × 0073 × 2060 × 0020 × 2060 × 0061 × 2060 × 0072 × 2060 × 0065 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER T (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER H (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] SPACE (Sp) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER R (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER S (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER P (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [8.0] SPACE (Sp) × [5.0] WORD JOINER (Format_FE) × [8.0] LATIN SMALL LETTER L (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER A (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER D (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER R (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER S (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] SPACE (Sp) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER A (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER R (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3]
÷ 2060 × 5B57 × 2060 × 002E × 2060 ÷ 5B57 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] CJK UNIFIED IDEOGRAPH-5B57 (OLetter) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) ÷ [11.0] CJK UNIFIED IDEOGRAPH-5B57 (OLetter) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3]
÷ 2060 × 0065 × 2060 × 0074 × 2060 × 0063 × 2060 × 002E × 2060 ÷ 5B83 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER T (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER C (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) ÷ [11.0] CJK UNIFIED IDEOGRAPH-5B83 (OLetter) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3]
÷ 2060 × 0065 × 2060 × 0074 × 2060 × 0063 × 2060 × 002E × 2060 × 3002 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER T (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER C (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [8.1] IDEOGRAPHIC FULL STOP (STerm) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3]
÷ 2060 × 5B57 × 2060 × 3002 × 2060 ÷ 5B83 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] CJK UNIFIED IDEOGRAPH-5B57 (OLetter) × [5.0] WORD JOINER (Format_FE) × [998.0] IDEOGRAPHIC FULL STOP (STerm) × [5.0] WORD JOINER (Format_FE) ÷ [11.0] CJK UNIFIED IDEOGRAPH-5B83 (OLetter) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3]
÷ 2060 × 0021 × 2060 × 0020 × 2060 × 0020 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] EXCLAMATION MARK (STerm) × [5.0] WORD JOINER (Format_FE) × [9.0] SPACE (Sp) × [5.0] WORD JOINER (Format_FE) × [10.0] SPACE (Sp) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3]
#
# Lines: 502
#
# EOF

View File

@ -0,0 +1,239 @@
<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01 Transitional//EN' 'http://www.w3.org/TR/html4/loose.dtd'>
<html><head><meta http-equiv='Content-Type' content='text/html; charset=utf-8'>
<title>Word Break Chart</title>
<style type='text/css'>
td, th { vertical-align: top }
</style></head>
<body bgcolor='#FFFFFF'>
<h2>Word_Break Chart</h2>
<p><b>Unicode Version:</b> 15.0.0</p>
<p><b>Date:</b> 2021-11-24, 21:43:58 GMT</p>
<p>This page illustrates the application of the Word_Break specification. The material here is informative, not normative.</p> <p>The first chart shows where breaks would appear between different sample characters or strings. The sample characters are chosen mechanically to represent the different properties used by the specification.</p><p>Each cell shows the break-status for the position between the character(s) in its row header and the character(s) in its column header. The × symbol indicates no break, while the ÷ symbol indicated a break. The cells with × are also shaded to make it easier to scan the table. For example, in the cell at the intersection of the row headed by “CR” and the column headed by “LF”, there is a × symbol, indicating that there is no break between CR and LF.</p>
<p>After the heavy blue line in the table are additional rows, either with different sample characters or for sequences, such as “ALetter MidLetter”. Some column headers may be composed, reflecting “treat as” or “ignore” rules.</p>
<p>If your browser handles titles (tooltips), then hovering the mouse over the row header will show a sample character of that type. Hovering over a column header will show the sample character, plus its abbreviated general category and script. Hovering over the intersected cells shows the rule number that produces the break-status. For example, hovering over the cell at the intersection of ExtendNumLet and ALetter shows ×, with the rule 13.2. Checking below the table, rule 13.2 is “ExtendNumLet × (AHLetter | Numeric | Katakana)”, which is the one that applies to that case. Note that a rule is invoked only when no lower-numbered rules have applied.</p>
<h3><a href='#table' name='table'>Table</a></h3>
<table border='1' cellspacing='0' width='100%'><tr><th width='4%'></th><th width='4%' class='lbclass' title='U+0001 <START OF HEADING>, gc=Cc, sc=Zyyy'>Other</th><th width='4%' class='lbclass' title='U+000D <CARRIAGE RETURN (CR)>, gc=Cc, sc=Zyyy'>CR</th><th width='4%' class='lbclass' title='U+000A <LINE FEED (LF)>, gc=Cc, sc=Zyyy'>LF</th><th width='4%' class='lbclass' title='U+000B <LINE TABULATION>, gc=Cc, sc=Zyyy'>Newline</th><th width='4%' class='lbclass' title='U+3031 VERTICAL KANA REPEAT MARK, gc=Lm, sc=Zyyy'>Katakana</th><th width='4%' class='lbclass' title='U+0041 LATIN CAPITAL LETTER A, gc=Lu, sc=Latn'>ALetter</th><th width='4%' class='lbclass' title='U+003A COLON, gc=Po, sc=Zyyy'>MidLetter</th><th width='4%' class='lbclass' title='U+002C COMMA, gc=Po, sc=Zyyy'>MidNum</th><th width='4%' class='lbclass' title='U+002E FULL STOP, gc=Po, sc=Zyyy'>MidNumLet</th><th width='4%' class='lbclass' title='U+0030 DIGIT ZERO, gc=Nd, sc=Zyyy'>Numeric</th><th width='4%' class='lbclass' title='U+005F LOW LINE, gc=Pc, sc=Zyyy'>ExtendNumLet</th><th width='4%' class='lbclass' title='U+1F1E6 REGIONAL INDICATOR SYMBOL LETTER A, gc=So, sc=Zyyy'>RI</th><th width='4%' class='lbclass' title='U+05D0 HEBREW LETTER ALEF, gc=Lo, sc=Hebr'>Hebrew_Letter</th><th width='4%' class='lbclass' title='U+0022 QUOTATION MARK, gc=Po, sc=Zyyy'>Double_Quote</th><th width='4%' class='lbclass' title='U+0027 APOSTROPHE, gc=Po, sc=Zyyy'>Single_Quote</th><th width='4%' class='lbclass' title='U+231A WATCH, gc=So, sc=Zyyy'>ExtPict</th><th width='4%' class='lbclass' title='U+0020 SPACE, gc=Zs, sc=Zyyy'>WSegSpace</th><th width='4%' class='lbclass' title='U+00AD SOFT HYPHEN, gc=Cf, sc=Zyyy'>Format_FE</th><th width='4%' class='lbclass' title='U+0300 COMBINING GRAVE ACCENT, gc=Mn, sc=Zinh'>Extend_FE</th><th width='4%' class='lbclass' title='U+200D ZERO WIDTH JOINER, gc=Cf, sc=Zinh'>ZWJ_FE</th></tr>
<tr><th class='lbclass' title='U+0001 <START OF HEADING>'>Other</th><th title='999.0' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th></tr>
<tr><th class='lbclass' title='U+000D <CARRIAGE RETURN (CR)>'>CR</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th></tr>
<tr><th class='lbclass' title='U+000A <LINE FEED (LF)>'>LF</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th></tr>
<tr><th class='lbclass' title='U+000B <LINE TABULATION>'>Newline</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th></tr>
<tr><th class='lbclass' title='U+3031 VERTICAL KANA REPEAT MARK'>Katakana</th><th title='999.0' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='13.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='13.1' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th></tr>
<tr><th class='lbclass' title='U+0041 LATIN CAPITAL LETTER A'>ALetter</th><th title='999.0' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='5.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='9.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='13.1' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='999.0' class='pairItem'>÷</th><th title='5.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th></tr>
<tr><th class='lbclass' title='U+003A COLON'>MidLetter</th><th title='999.0' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th></tr>
<tr><th class='lbclass' title='U+002C COMMA'>MidNum</th><th title='999.0' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th></tr>
<tr><th class='lbclass' title='U+002E FULL STOP'>MidNumLet</th><th title='999.0' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th></tr>
<tr><th class='lbclass' title='U+0030 DIGIT ZERO'>Numeric</th><th title='999.0' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='10.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='8.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='13.1' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='999.0' class='pairItem'>÷</th><th title='10.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th></tr>
<tr><th class='lbclass' title='U+005F LOW LINE'>ExtendNumLet</th><th title='999.0' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='13.2' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='13.2' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='13.2' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='13.1' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='999.0' class='pairItem'>÷</th><th title='13.2' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th></tr>
<tr><th class='lbclass' title='U+1F1E6 REGIONAL INDICATOR SYMBOL LETTER A'>RI</th><th title='999.0' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='15.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th></tr>
<tr><th class='lbclass' title='U+05D0 HEBREW LETTER ALEF'>Hebrew_Letter</th><th title='999.0' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='5.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='9.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='13.1' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='999.0' class='pairItem'>÷</th><th title='5.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='999.0' class='pairItem'>÷</th><th title='7.1' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th></tr>
<tr><th class='lbclass' title='U+0022 QUOTATION MARK'>Double_Quote</th><th title='999.0' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th></tr>
<tr><th class='lbclass' title='U+0027 APOSTROPHE'>Single_Quote</th><th title='999.0' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th></tr>
<tr><th class='lbclass' title='U+231A WATCH'>ExtPict</th><th title='999.0' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th></tr>
<tr><th class='lbclass' title='U+0020 SPACE'>WSegSpace</th><th title='999.0' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='3.4' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th></tr>
<tr><th class='lbclass' title='U+00AD SOFT HYPHEN'>Format_FE</th><th title='999.0' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th></tr>
<tr><th class='lbclass' title='U+0300 COMBINING GRAVE ACCENT'>Extend_FE</th><th title='999.0' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th></tr>
<tr><th class='lbclass' title='U+200D ZERO WIDTH JOINER'>ZWJ_FE</th><th title='999.0' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='3.3' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='999.0' class='pairItem'>÷</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th></tr>
<tr><td bgcolor='#0000FF' colSpan='21' style='font-size: 1px'>&nbsp;</td></tr>
<tr><th class='lbclass' title='U+0061 LATIN SMALL LETTER A, U+2060 WORD JOINER'>ALetter Format_FE</th><th title='999.0' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='5.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='9.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='13.1' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='999.0' class='pairItem'>÷</th><th title='5.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th></tr>
<tr><th class='lbclass' title='U+0061 LATIN SMALL LETTER A, U+003A COLON'>ALetter MidLetter</th><th title='999.0' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='7.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='7.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th></tr>
<tr><th class='lbclass' title='U+0061 LATIN SMALL LETTER A, U+0027 APOSTROPHE'>ALetter Single_Quote</th><th title='999.0' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='7.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='7.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th></tr>
<tr><th class='lbclass' title='U+0061 LATIN SMALL LETTER A, U+0027 APOSTROPHE, U+2060 WORD JOINER'>ALetter Single_Quote Format_FE</th><th title='999.0' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='7.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='7.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th></tr>
<tr><th class='lbclass' title='U+0061 LATIN SMALL LETTER A, U+002C COMMA'>ALetter MidNum</th><th title='999.0' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th></tr>
<tr><th class='lbclass' title='U+0031 DIGIT ONE, U+003A COLON'>Numeric MidLetter</th><th title='999.0' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th></tr>
<tr><th class='lbclass' title='U+0031 DIGIT ONE, U+0027 APOSTROPHE'>Numeric Single_Quote</th><th title='999.0' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='11.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th></tr>
<tr><th class='lbclass' title='U+0031 DIGIT ONE, U+002C COMMA'>Numeric MidNum</th><th title='999.0' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='11.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th></tr>
<tr><th class='lbclass' title='U+0031 DIGIT ONE, U+002E FULL STOP, U+2060 WORD JOINER'>Numeric MidNumLet Format_FE</th><th title='999.0' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='11.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th></tr>
</table>
<h3><a href='#rules' name='rules'>Rules</a></h3>
<p>This section shows the rules. They are mechanically modified for programmatic generation of the tables and test code, and thus do not match the UAX rules precisely. In particular:</p><ol><li>The rules are cast into a form that is more like regular expressions.</li><li>The rules “sot ÷”, “÷ eot”, and “÷ Any” are added mechanically, and have artificial numbers.</li><li>The rules are given decimal numbers using tenths, and are written without prefix. For example, rule WB13a is given the number 13.1.</li><li>Any “treat as” or “ignore” rules are handled as discussed in UAX #29, and thus reflected in a transformation of the rules usually not visible here. In addition, final rules like “Any ÷ Any” may be recast as the equivalent expression “÷ Any”.</li><li>In some cases, the numbering and form of a rule is changed due to “treat as” rules.</li></ol><p>For the original rules and the macro values they use, see UAX #29.</p>
<table>
<tr><th style='text-align:right'><a href='#r0.2' name='r0.2'>0.2</a></th><td style='text-align:right'>sot </td><td>÷</td><td></td></tr>
<tr><th style='text-align:right'><a href='#r0.3' name='r0.3'>0.3</a></th><td style='text-align:right'></td><td>÷</td><td> eot</td></tr>
<tr><th style='text-align:right'><a href='#r3.0' name='r3.0'>3.0</a></th><td style='text-align:right'>CR </td><td>×</td><td> LF</td></tr>
<tr><th style='text-align:right'><a href='#r3.1' name='r3.1'>3.1</a></th><td style='text-align:right'>(Newline | CR | LF) </td><td>÷</td><td></td></tr>
<tr><th style='text-align:right'><a href='#r3.2' name='r3.2'>3.2</a></th><td style='text-align:right'></td><td>÷</td><td> (Newline | CR | LF)</td></tr>
<tr><th style='text-align:right'><a href='#r3.3' name='r3.3'>3.3</a></th><td style='text-align:right'>ZWJ </td><td>×</td><td> ExtPict</td></tr>
<tr><th style='text-align:right'><a href='#r3.4' name='r3.4'>3.4</a></th><td style='text-align:right'>WSegSpace </td><td>×</td><td> WSegSpace</td></tr>
<tr><th style='text-align:right'><a href='#r4.0' name='r4.0'>4.0</a></th><td style='text-align:right'>[^ Newline CR LF ] </td><td>×</td><td> [Format Extend ZWJ]</td></tr>
<tr><th style='text-align:right'><a href='#r5.0' name='r5.0'>5.0</a></th><td style='text-align:right'>AHLetter </td><td>×</td><td> AHLetter</td></tr>
<tr><th style='text-align:right'><a href='#r6.0' name='r6.0'>6.0</a></th><td style='text-align:right'>AHLetter </td><td>×</td><td> (MidLetter | MidNumLetQ) AHLetter</td></tr>
<tr><th style='text-align:right'><a href='#r7.0' name='r7.0'>7.0</a></th><td style='text-align:right'>AHLetter (MidLetter | MidNumLetQ) </td><td>×</td><td> AHLetter</td></tr>
<tr><th style='text-align:right'><a href='#r7.1' name='r7.1'>7.1</a></th><td style='text-align:right'>Hebrew_Letter </td><td>×</td><td> Single_Quote</td></tr>
<tr><th style='text-align:right'><a href='#r7.2' name='r7.2'>7.2</a></th><td style='text-align:right'>Hebrew_Letter </td><td>×</td><td> Double_Quote Hebrew_Letter</td></tr>
<tr><th style='text-align:right'><a href='#r7.3' name='r7.3'>7.3</a></th><td style='text-align:right'>Hebrew_Letter Double_Quote </td><td>×</td><td> Hebrew_Letter</td></tr>
<tr><th style='text-align:right'><a href='#r8.0' name='r8.0'>8.0</a></th><td style='text-align:right'>Numeric </td><td>×</td><td> Numeric</td></tr>
<tr><th style='text-align:right'><a href='#r9.0' name='r9.0'>9.0</a></th><td style='text-align:right'>AHLetter </td><td>×</td><td> Numeric</td></tr>
<tr><th style='text-align:right'><a href='#r10.0' name='r10.0'>10.0</a></th><td style='text-align:right'>Numeric </td><td>×</td><td> AHLetter</td></tr>
<tr><th style='text-align:right'><a href='#r11.0' name='r11.0'>11.0</a></th><td style='text-align:right'>Numeric (MidNum | MidNumLetQ) </td><td>×</td><td> Numeric</td></tr>
<tr><th style='text-align:right'><a href='#r12.0' name='r12.0'>12.0</a></th><td style='text-align:right'>Numeric </td><td>×</td><td> (MidNum | MidNumLetQ) Numeric</td></tr>
<tr><th style='text-align:right'><a href='#r13.0' name='r13.0'>13.0</a></th><td style='text-align:right'>Katakana </td><td>×</td><td> Katakana</td></tr>
<tr><th style='text-align:right'><a href='#r13.1' name='r13.1'>13.1</a></th><td style='text-align:right'>(AHLetter | Numeric | Katakana | ExtendNumLet) </td><td>×</td><td> ExtendNumLet</td></tr>
<tr><th style='text-align:right'><a href='#r13.2' name='r13.2'>13.2</a></th><td style='text-align:right'>ExtendNumLet </td><td>×</td><td> (AHLetter | Numeric | Katakana)</td></tr>
<tr><th style='text-align:right'><a href='#r15.0' name='r15.0'>15.0</a></th><td style='text-align:right'>^ (RI RI)* RI </td><td>×</td><td> RI</td></tr>
<tr><th style='text-align:right'><a href='#r16.0' name='r16.0'>16.0</a></th><td style='text-align:right'>[^RI] (RI RI)* RI </td><td>×</td><td> RI</td></tr>
<tr><th style='text-align:right'><a href='#r999.0' name='r999.0'>999.0</a></th><td style='text-align:right'></td><td>÷</td><td> Any</td></tr>
</table>
<h3><a href='#samples' name='samples'>Sample Strings</a></h3>
<p>The following samples illustrate the application of the rules. The blue lines indicate possible break points. If your browser supports titles (tooltips), then positioning the mouse over each character will show its name, while positioning between characters shows the number of the rule responsible for the break-status.</p>
<table>
<tr><th style='text-align:right'><a href='#s1' name='s1'>1</a></th><td><font size='5'>
<span title='0.2'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+000D &lt;CARRIAGE RETURN (CR)&gt; (CR)'>&#x25A1;</span><span title='3.0'><span>&nbsp;</span>&nbsp;</span><span title='U+000A &lt;LINE FEED (LF)&gt; (LF)'>&#x25A1;</span><span title='3.1'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+0061 LATIN SMALL LETTER A (ALetter)'>a</span><span title='3.2'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+000A &lt;LINE FEED (LF)&gt; (LF)'>&#x25A1;</span><span title='3.1'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+0308 COMBINING DIAERESIS (Extend_FE)'>&#x25CC;&#x308;</span><span title='0.3'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span>
</font></td></tr>
<tr><th style='text-align:right'><a href='#s2' name='s2'>2</a></th><td><font size='5'>
<span title='0.2'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+0061 LATIN SMALL LETTER A (ALetter)'>a</span><span title='4.0'><span>&nbsp;</span>&nbsp;</span><span title='U+0308 COMBINING DIAERESIS (Extend_FE)'>&#x25CC;&#x308;</span><span title='0.3'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span>
</font></td></tr>
<tr><th style='text-align:right'><a href='#s3' name='s3'>3</a></th><td><font size='5'>
<span title='0.2'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+0020 SPACE (WSegSpace)'> </span><span title='4.0'><span>&nbsp;</span>&nbsp;</span><span title='U+200D ZERO WIDTH JOINER (ZWJ_FE)'>&#x25A1;</span><span title='999.0'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+0646 ARABIC LETTER NOON (ALetter)'>&#x646;</span><span title='0.3'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span>
</font></td></tr>
<tr><th style='text-align:right'><a href='#s4' name='s4'>4</a></th><td><font size='5'>
<span title='0.2'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+0646 ARABIC LETTER NOON (ALetter)'>&#x646;</span><span title='4.0'><span>&nbsp;</span>&nbsp;</span><span title='U+200D ZERO WIDTH JOINER (ZWJ_FE)'>&#x25A1;</span><span title='999.0'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+0020 SPACE (WSegSpace)'> </span><span title='0.3'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span>
</font></td></tr>
<tr><th style='text-align:right'><a href='#s5' name='s5'>5</a></th><td><font size='5'>
<span title='0.2'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+0041 LATIN CAPITAL LETTER A (ALetter)'>A</span><span title='5.0'><span>&nbsp;</span>&nbsp;</span><span title='U+0041 LATIN CAPITAL LETTER A (ALetter)'>A</span><span title='5.0'><span>&nbsp;</span>&nbsp;</span><span title='U+0041 LATIN CAPITAL LETTER A (ALetter)'>A</span><span title='0.3'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span>
</font></td></tr>
<tr><th style='text-align:right'><a href='#s6' name='s6'>6</a></th><td><font size='5'>
<span title='0.2'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+0041 LATIN CAPITAL LETTER A (ALetter)'>A</span><span title='6.0'><span>&nbsp;</span>&nbsp;</span><span title='U+003A COLON (MidLetter)'>:</span><span title='7.0'><span>&nbsp;</span>&nbsp;</span><span title='U+0041 LATIN CAPITAL LETTER A (ALetter)'>A</span><span title='0.3'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span>
</font></td></tr>
<tr><th style='text-align:right'><a href='#s7' name='s7'>7</a></th><td><font size='5'>
<span title='0.2'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+0041 LATIN CAPITAL LETTER A (ALetter)'>A</span><span title='999.0'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+003A COLON (MidLetter)'>:</span><span title='999.0'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+003A COLON (MidLetter)'>:</span><span title='999.0'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+0041 LATIN CAPITAL LETTER A (ALetter)'>A</span><span title='0.3'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span>
</font></td></tr>
<tr><th style='text-align:right'><a href='#s8' name='s8'>8</a></th><td><font size='5'>
<span title='0.2'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+05D0 HEBREW LETTER ALEF (Hebrew_Letter)'>&#x5D0;</span><span title='7.1'><span>&nbsp;</span>&nbsp;</span><span title='U+0027 APOSTROPHE (Single_Quote)'>'</span><span title='0.3'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span>
</font></td></tr>
<tr><th style='text-align:right'><a href='#s9' name='s9'>9</a></th><td><font size='5'>
<span title='0.2'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+05D0 HEBREW LETTER ALEF (Hebrew_Letter)'>&#x5D0;</span><span title='7.2'><span>&nbsp;</span>&nbsp;</span><span title='U+0022 QUOTATION MARK (Double_Quote)'>&quot;</span><span title='7.3'><span>&nbsp;</span>&nbsp;</span><span title='U+05D0 HEBREW LETTER ALEF (Hebrew_Letter)'>&#x5D0;</span><span title='0.3'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span>
</font></td></tr>
<tr><th style='text-align:right'><a href='#s10' name='s10'>10</a></th><td><font size='5'>
<span title='0.2'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+0041 LATIN CAPITAL LETTER A (ALetter)'>A</span><span title='9.0'><span>&nbsp;</span>&nbsp;</span><span title='U+0030 DIGIT ZERO (Numeric)'>0</span><span title='8.0'><span>&nbsp;</span>&nbsp;</span><span title='U+0030 DIGIT ZERO (Numeric)'>0</span><span title='10.0'><span>&nbsp;</span>&nbsp;</span><span title='U+0041 LATIN CAPITAL LETTER A (ALetter)'>A</span><span title='0.3'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span>
</font></td></tr>
<tr><th style='text-align:right'><a href='#s11' name='s11'>11</a></th><td><font size='5'>
<span title='0.2'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+0030 DIGIT ZERO (Numeric)'>0</span><span title='12.0'><span>&nbsp;</span>&nbsp;</span><span title='U+002C COMMA (MidNum)'>,</span><span title='11.0'><span>&nbsp;</span>&nbsp;</span><span title='U+0030 DIGIT ZERO (Numeric)'>0</span><span title='0.3'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span>
</font></td></tr>
<tr><th style='text-align:right'><a href='#s12' name='s12'>12</a></th><td><font size='5'>
<span title='0.2'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+0030 DIGIT ZERO (Numeric)'>0</span><span title='999.0'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+002C COMMA (MidNum)'>,</span><span title='999.0'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+002C COMMA (MidNum)'>,</span><span title='999.0'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+0030 DIGIT ZERO (Numeric)'>0</span><span title='0.3'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span>
</font></td></tr>
<tr><th style='text-align:right'><a href='#s13' name='s13'>13</a></th><td><font size='5'>
<span title='0.2'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+3031 VERTICAL KANA REPEAT MARK (Katakana)'>&#x3031;</span><span title='13.0'><span>&nbsp;</span>&nbsp;</span><span title='U+3031 VERTICAL KANA REPEAT MARK (Katakana)'>&#x3031;</span><span title='0.3'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span>
</font></td></tr>
<tr><th style='text-align:right'><a href='#s14' name='s14'>14</a></th><td><font size='5'>
<span title='0.2'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+0041 LATIN CAPITAL LETTER A (ALetter)'>A</span><span title='13.1'><span>&nbsp;</span>&nbsp;</span><span title='U+005F LOW LINE (ExtendNumLet)'>_</span><span title='13.2'><span>&nbsp;</span>&nbsp;</span><span title='U+0030 DIGIT ZERO (Numeric)'>0</span><span title='13.1'><span>&nbsp;</span>&nbsp;</span><span title='U+005F LOW LINE (ExtendNumLet)'>_</span><span title='13.2'><span>&nbsp;</span>&nbsp;</span><span title='U+3031 VERTICAL KANA REPEAT MARK (Katakana)'>&#x3031;</span><span title='13.1'><span>&nbsp;</span>&nbsp;</span><span title='U+005F LOW LINE (ExtendNumLet)'>_</span><span title='0.3'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span>
</font></td></tr>
<tr><th style='text-align:right'><a href='#s15' name='s15'>15</a></th><td><font size='5'>
<span title='0.2'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+0041 LATIN CAPITAL LETTER A (ALetter)'>A</span><span title='13.1'><span>&nbsp;</span>&nbsp;</span><span title='U+005F LOW LINE (ExtendNumLet)'>_</span><span title='13.1'><span>&nbsp;</span>&nbsp;</span><span title='U+005F LOW LINE (ExtendNumLet)'>_</span><span title='13.2'><span>&nbsp;</span>&nbsp;</span><span title='U+0041 LATIN CAPITAL LETTER A (ALetter)'>A</span><span title='0.3'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span>
</font></td></tr>
<tr><th style='text-align:right'><a href='#s16' name='s16'>16</a></th><td><font size='5'>
<span title='0.2'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+1F1E6 REGIONAL INDICATOR SYMBOL LETTER A (RI)'>&#x1F1E6;</span><span title='15.0'><span>&nbsp;</span>&nbsp;</span><span title='U+1F1E7 REGIONAL INDICATOR SYMBOL LETTER B (RI)'>&#x1F1E7;</span><span title='999.0'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+1F1E8 REGIONAL INDICATOR SYMBOL LETTER C (RI)'>&#x1F1E8;</span><span title='999.0'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+0062 LATIN SMALL LETTER B (ALetter)'>b</span><span title='0.3'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span>
</font></td></tr>
<tr><th style='text-align:right'><a href='#s17' name='s17'>17</a></th><td><font size='5'>
<span title='0.2'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+0061 LATIN SMALL LETTER A (ALetter)'>a</span><span title='999.0'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+1F1E6 REGIONAL INDICATOR SYMBOL LETTER A (RI)'>&#x1F1E6;</span><span title='16.0'><span>&nbsp;</span>&nbsp;</span><span title='U+1F1E7 REGIONAL INDICATOR SYMBOL LETTER B (RI)'>&#x1F1E7;</span><span title='999.0'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+1F1E8 REGIONAL INDICATOR SYMBOL LETTER C (RI)'>&#x1F1E8;</span><span title='999.0'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+0062 LATIN SMALL LETTER B (ALetter)'>b</span><span title='0.3'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span>
</font></td></tr>
<tr><th style='text-align:right'><a href='#s18' name='s18'>18</a></th><td><font size='5'>
<span title='0.2'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+0061 LATIN SMALL LETTER A (ALetter)'>a</span><span title='999.0'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+1F1E6 REGIONAL INDICATOR SYMBOL LETTER A (RI)'>&#x1F1E6;</span><span title='16.0'><span>&nbsp;</span>&nbsp;</span><span title='U+1F1E7 REGIONAL INDICATOR SYMBOL LETTER B (RI)'>&#x1F1E7;</span><span title='4.0'><span>&nbsp;</span>&nbsp;</span><span title='U+200D ZERO WIDTH JOINER (ZWJ_FE)'>&#x25A1;</span><span title='999.0'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+1F1E8 REGIONAL INDICATOR SYMBOL LETTER C (RI)'>&#x1F1E8;</span><span title='999.0'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+0062 LATIN SMALL LETTER B (ALetter)'>b</span><span title='0.3'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span>
</font></td></tr>
<tr><th style='text-align:right'><a href='#s19' name='s19'>19</a></th><td><font size='5'>
<span title='0.2'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+0061 LATIN SMALL LETTER A (ALetter)'>a</span><span title='999.0'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+1F1E6 REGIONAL INDICATOR SYMBOL LETTER A (RI)'>&#x1F1E6;</span><span title='4.0'><span>&nbsp;</span>&nbsp;</span><span title='U+200D ZERO WIDTH JOINER (ZWJ_FE)'>&#x25A1;</span><span title='16.0'><span>&nbsp;</span>&nbsp;</span><span title='U+1F1E7 REGIONAL INDICATOR SYMBOL LETTER B (RI)'>&#x1F1E7;</span><span title='999.0'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+1F1E8 REGIONAL INDICATOR SYMBOL LETTER C (RI)'>&#x1F1E8;</span><span title='999.0'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+0062 LATIN SMALL LETTER B (ALetter)'>b</span><span title='0.3'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span>
</font></td></tr>
<tr><th style='text-align:right'><a href='#s20' name='s20'>20</a></th><td><font size='5'>
<span title='0.2'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+0061 LATIN SMALL LETTER A (ALetter)'>a</span><span title='999.0'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+1F1E6 REGIONAL INDICATOR SYMBOL LETTER A (RI)'>&#x1F1E6;</span><span title='16.0'><span>&nbsp;</span>&nbsp;</span><span title='U+1F1E7 REGIONAL INDICATOR SYMBOL LETTER B (RI)'>&#x1F1E7;</span><span title='999.0'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+1F1E8 REGIONAL INDICATOR SYMBOL LETTER C (RI)'>&#x1F1E8;</span><span title='16.0'><span>&nbsp;</span>&nbsp;</span><span title='U+1F1E9 REGIONAL INDICATOR SYMBOL LETTER D (RI)'>&#x1F1E9;</span><span title='999.0'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+0062 LATIN SMALL LETTER B (ALetter)'>b</span><span title='0.3'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span>
</font></td></tr>
<tr><th style='text-align:right'><a href='#s21' name='s21'>21</a></th><td><font size='5'>
<span title='0.2'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+1F476 BABY (ExtPict)'>&#x1F476;</span><span title='4.0'><span>&nbsp;</span>&nbsp;</span><span title='U+1F3FF EMOJI MODIFIER FITZPATRICK TYPE-6 (Extend_FE)'>&#x1F3FF;</span><span title='999.0'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+1F476 BABY (ExtPict)'>&#x1F476;</span><span title='0.3'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span>
</font></td></tr>
<tr><th style='text-align:right'><a href='#s22' name='s22'>22</a></th><td><font size='5'>
<span title='0.2'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+1F6D1 OCTAGONAL SIGN (ExtPict)'>&#x1F6D1;</span><span title='4.0'><span>&nbsp;</span>&nbsp;</span><span title='U+200D ZERO WIDTH JOINER (ZWJ_FE)'>&#x25A1;</span><span title='3.3'><span>&nbsp;</span>&nbsp;</span><span title='U+1F6D1 OCTAGONAL SIGN (ExtPict)'>&#x1F6D1;</span><span title='0.3'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span>
</font></td></tr>
<tr><th style='text-align:right'><a href='#s23' name='s23'>23</a></th><td><font size='5'>
<span title='0.2'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+0061 LATIN SMALL LETTER A (ALetter)'>a</span><span title='4.0'><span>&nbsp;</span>&nbsp;</span><span title='U+200D ZERO WIDTH JOINER (ZWJ_FE)'>&#x25A1;</span><span title='3.3'><span>&nbsp;</span>&nbsp;</span><span title='U+1F6D1 OCTAGONAL SIGN (ExtPict)'>&#x1F6D1;</span><span title='0.3'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span>
</font></td></tr>
<tr><th style='text-align:right'><a href='#s24' name='s24'>24</a></th><td><font size='5'>
<span title='0.2'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+2701 UPPER BLADE SCISSORS (Other)'>&#x2701;</span><span title='4.0'><span>&nbsp;</span>&nbsp;</span><span title='U+200D ZERO WIDTH JOINER (ZWJ_FE)'>&#x25A1;</span><span title='3.3'><span>&nbsp;</span>&nbsp;</span><span title='U+2701 UPPER BLADE SCISSORS (Other)'>&#x2701;</span><span title='0.3'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span>
</font></td></tr>
<tr><th style='text-align:right'><a href='#s25' name='s25'>25</a></th><td><font size='5'>
<span title='0.2'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+0061 LATIN SMALL LETTER A (ALetter)'>a</span><span title='4.0'><span>&nbsp;</span>&nbsp;</span><span title='U+200D ZERO WIDTH JOINER (ZWJ_FE)'>&#x25A1;</span><span title='3.3'><span>&nbsp;</span>&nbsp;</span><span title='U+2701 UPPER BLADE SCISSORS (Other)'>&#x2701;</span><span title='0.3'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span>
</font></td></tr>
<tr><th style='text-align:right'><a href='#s26' name='s26'>26</a></th><td><font size='5'>
<span title='0.2'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+1F476 BABY (ExtPict)'>&#x1F476;</span><span title='4.0'><span>&nbsp;</span>&nbsp;</span><span title='U+1F3FF EMOJI MODIFIER FITZPATRICK TYPE-6 (Extend_FE)'>&#x1F3FF;</span><span title='4.0'><span>&nbsp;</span>&nbsp;</span><span title='U+0308 COMBINING DIAERESIS (Extend_FE)'>&#x25CC;&#x308;</span><span title='4.0'><span>&nbsp;</span>&nbsp;</span><span title='U+200D ZERO WIDTH JOINER (ZWJ_FE)'>&#x25A1;</span><span title='3.3'><span>&nbsp;</span>&nbsp;</span><span title='U+1F476 BABY (ExtPict)'>&#x1F476;</span><span title='4.0'><span>&nbsp;</span>&nbsp;</span><span title='U+1F3FF EMOJI MODIFIER FITZPATRICK TYPE-6 (Extend_FE)'>&#x1F3FF;</span><span title='0.3'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span>
</font></td></tr>
<tr><th style='text-align:right'><a href='#s27' name='s27'>27</a></th><td><font size='5'>
<span title='0.2'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+1F6D1 OCTAGONAL SIGN (ExtPict)'>&#x1F6D1;</span><span title='4.0'><span>&nbsp;</span>&nbsp;</span><span title='U+1F3FF EMOJI MODIFIER FITZPATRICK TYPE-6 (Extend_FE)'>&#x1F3FF;</span><span title='0.3'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span>
</font></td></tr>
<tr><th style='text-align:right'><a href='#s28' name='s28'>28</a></th><td><font size='5'>
<span title='0.2'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+200D ZERO WIDTH JOINER (ZWJ_FE)'>&#x25A1;</span><span title='3.3'><span>&nbsp;</span>&nbsp;</span><span title='U+1F6D1 OCTAGONAL SIGN (ExtPict)'>&#x1F6D1;</span><span title='4.0'><span>&nbsp;</span>&nbsp;</span><span title='U+1F3FF EMOJI MODIFIER FITZPATRICK TYPE-6 (Extend_FE)'>&#x1F3FF;</span><span title='0.3'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span>
</font></td></tr>
<tr><th style='text-align:right'><a href='#s29' name='s29'>29</a></th><td><font size='5'>
<span title='0.2'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+200D ZERO WIDTH JOINER (ZWJ_FE)'>&#x25A1;</span><span title='3.3'><span>&nbsp;</span>&nbsp;</span><span title='U+1F6D1 OCTAGONAL SIGN (ExtPict)'>&#x1F6D1;</span><span title='0.3'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span>
</font></td></tr>
<tr><th style='text-align:right'><a href='#s30' name='s30'>30</a></th><td><font size='5'>
<span title='0.2'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+200D ZERO WIDTH JOINER (ZWJ_FE)'>&#x25A1;</span><span title='3.3'><span>&nbsp;</span>&nbsp;</span><span title='U+1F6D1 OCTAGONAL SIGN (ExtPict)'>&#x1F6D1;</span><span title='0.3'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span>
</font></td></tr>
<tr><th style='text-align:right'><a href='#s31' name='s31'>31</a></th><td><font size='5'>
<span title='0.2'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+1F6D1 OCTAGONAL SIGN (ExtPict)'>&#x1F6D1;</span><span title='999.0'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+1F6D1 OCTAGONAL SIGN (ExtPict)'>&#x1F6D1;</span><span title='0.3'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span>
</font></td></tr>
<tr><th style='text-align:right'><a href='#s32' name='s32'>32</a></th><td><font size='5'>
<span title='0.2'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+0061 LATIN SMALL LETTER A (ALetter)'>a</span><span title='4.0'><span>&nbsp;</span>&nbsp;</span><span title='U+0308 COMBINING DIAERESIS (Extend_FE)'>&#x25CC;&#x308;</span><span title='4.0'><span>&nbsp;</span>&nbsp;</span><span title='U+200D ZERO WIDTH JOINER (ZWJ_FE)'>&#x25A1;</span><span title='4.0'><span>&nbsp;</span>&nbsp;</span><span title='U+0308 COMBINING DIAERESIS (Extend_FE)'>&#x25CC;&#x308;</span><span title='5.0'><span>&nbsp;</span>&nbsp;</span><span title='U+0062 LATIN SMALL LETTER B (ALetter)'>b</span><span title='0.3'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span>
</font></td></tr>
<tr><th style='text-align:right'><a href='#s33' name='s33'>33</a></th><td><font size='5'>
<span title='0.2'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+0061 LATIN SMALL LETTER A (ALetter)'>a</span><span title='999.0'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+0020 SPACE (WSegSpace)'> </span><span title='3.4'><span>&nbsp;</span>&nbsp;</span><span title='U+0020 SPACE (WSegSpace)'> </span><span title='999.0'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+0062 LATIN SMALL LETTER B (ALetter)'>b</span><span title='0.3'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span>
</font></td></tr>
</table>
<hr width='50%'>
<div align='center'>
<center>
<table cellspacing='0' cellpadding='0' border='0'>
<tr>
<td><a href='https://www.unicode.org/copyright.html'>
<img src='https://www.unicode.org/img/hb_notice.gif' border='0' alt='Access to Copyright and terms of use' width='216' height='50'></a></td>
</tr>
</table>
</center>
</div>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,936 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include <QTest>
#include <QScopedValueRollback>
#include <qtextboundaryfinder.h>
#include <qfile.h>
#include <qdebug.h>
#include <qlist.h>
#include <algorithm>
class tst_QTextBoundaryFinder : public QObject
{
Q_OBJECT
private slots:
#ifdef QT_BUILD_INTERNAL
void graphemeBoundariesDefault_data();
void graphemeBoundariesDefault();
void wordBoundariesDefault_data();
void wordBoundariesDefault();
void sentenceBoundariesDefault_data();
void sentenceBoundariesDefault();
void lineBoundariesDefault_data();
void lineBoundariesDefault();
#endif
void graphemeBoundaries_manual_data();
void graphemeBoundaries_manual();
void wordBoundaries_manual_data();
void wordBoundaries_manual();
void sentenceBoundaries_manual_data();
void sentenceBoundaries_manual();
void lineBoundaries_manual_data();
void lineBoundaries_manual();
void emptyText_data();
void emptyText();
void fastConstructor();
void assignmentOperator();
void isAtSoftHyphen_data();
void isAtSoftHyphen();
void thaiLineBreak();
};
QT_BEGIN_NAMESPACE
namespace QTest {
template<>
inline char *toString(const QTextBoundaryFinder::BoundaryReasons &flags)
{
return qstrdup(QByteArray::number(int(flags)).constData());
}
template<>
inline char *toString(const QList<int> &list)
{
QByteArray s;
for (QList<int>::const_iterator it = list.constBegin(); it != list.constEnd(); ++it) {
if (!s.isEmpty())
s += ", ";
s += QByteArray::number(*it);
}
s = "{ " + s + " }";
return qstrdup(s.constData());
}
} // namespace QTest
QT_END_NAMESPACE
#ifdef QT_BUILD_INTERNAL
static void generateDataFromFile(const QString &fname)
{
QTest::addColumn<QString>("testString");
QTest::addColumn<QList<int> >("expectedBreakPositions");
QString testFile = QFINDTESTDATA(fname);
QVERIFY2(!testFile.isEmpty(), (fname.toLatin1() + QByteArray(" not found!")));
QFile f(testFile);
QVERIFY(f.exists());
f.open(QIODevice::ReadOnly);
int linenum = 0;
while (!f.atEnd()) {
linenum++;
QByteArray line = f.readLine();
if (line.startsWith('#'))
continue;
QString test = QString::fromUtf8(line);
QString comments;
int hash = test.indexOf('#');
if (hash > 0) {
comments = test.mid(hash + 1).simplified();
test = test.left(hash);
}
QString testString;
QList<int> expectedBreakPositions;
foreach (const QString &part, test.simplified().split(QLatin1Char(' '), Qt::SkipEmptyParts)) {
if (part.size() == 1) {
if (part.at(0).unicode() == 0xf7)
expectedBreakPositions.append(testString.size());
else
QVERIFY(part.at(0).unicode() == 0xd7);
continue;
}
bool ok = true;
uint ucs4 = part.toInt(&ok, 16);
QVERIFY(ok && ucs4 > 0);
if (QChar::requiresSurrogates(ucs4)) {
testString.append(QChar::highSurrogate(ucs4));
testString.append(QChar::lowSurrogate(ucs4));
} else {
testString.append(QChar(ucs4));
}
}
QVERIFY(!testString.isEmpty());
QVERIFY(!expectedBreakPositions.isEmpty());
if (!comments.isEmpty()) {
const QStringList lst = comments.simplified().split(QLatin1Char(' '), Qt::SkipEmptyParts);
comments.clear();
foreach (const QString &part, lst) {
if (part.size() == 1) {
if (part.at(0).unicode() == 0xf7)
comments += QLatin1Char('+');
else if (part.at(0).unicode() == 0xd7)
comments += QLatin1Char('x');
continue;
}
if (part.startsWith(QLatin1Char('(')) && part.endsWith(QLatin1Char(')')))
comments += part;
}
}
const QByteArray nm = "line #" + QByteArray::number(linenum) + ": " + comments.toLatin1();
QTest::newRow(nm.constData()) << testString << expectedBreakPositions;
}
}
#endif
static void doTestData(const QString &testString, const QList<int> &expectedBreakPositions,
QTextBoundaryFinder::BoundaryType type,
QTextBoundaryFinder::BoundaryReasons reasons = QTextBoundaryFinder::BreakOpportunity)
{
QVERIFY(!testString.isEmpty());
QTextBoundaryFinder boundaryFinder(type, testString);
// test toNextBoundary()
{
QList<int> actualBreakPositions;
do {
QVERIFY(boundaryFinder.isAtBoundary());
if (boundaryFinder.boundaryReasons() & reasons)
actualBreakPositions.append(boundaryFinder.position());
} while (boundaryFinder.toNextBoundary() != -1);
QCOMPARE(actualBreakPositions, expectedBreakPositions);
}
QCOMPARE(boundaryFinder.position(), -1);
QVERIFY(!boundaryFinder.isAtBoundary());
QVERIFY(boundaryFinder.boundaryReasons() == QTextBoundaryFinder::NotAtBoundary);
// test toPreviousBoundary()
{
QList<int> expectedBreakPositionsRev = expectedBreakPositions;
std::sort(expectedBreakPositionsRev.begin(), expectedBreakPositionsRev.end(), std::greater<int>());
QList<int> actualBreakPositions;
boundaryFinder.toEnd();
do {
QVERIFY(boundaryFinder.isAtBoundary());
if (boundaryFinder.boundaryReasons() & reasons)
actualBreakPositions.append(boundaryFinder.position());
} while (boundaryFinder.toPreviousBoundary() != -1);
QCOMPARE(actualBreakPositions, expectedBreakPositionsRev);
}
QCOMPARE(boundaryFinder.position(), -1);
QVERIFY(!boundaryFinder.isAtBoundary());
QVERIFY(boundaryFinder.boundaryReasons() == QTextBoundaryFinder::NotAtBoundary);
// test boundaryReasons()
for (int i = 0; i <= testString.size(); ++i) {
boundaryFinder.setPosition(i);
QCOMPARE(!!(boundaryFinder.boundaryReasons() & reasons), expectedBreakPositions.contains(i));
}
}
#ifdef QT_BUILD_INTERNAL
QT_BEGIN_NAMESPACE
extern Q_AUTOTEST_EXPORT int qt_initcharattributes_default_algorithm_only;
QT_END_NAMESPACE
void tst_QTextBoundaryFinder::graphemeBoundariesDefault_data()
{
generateDataFromFile("data/GraphemeBreakTest.txt");
}
void tst_QTextBoundaryFinder::graphemeBoundariesDefault()
{
QFETCH(QString, testString);
QFETCH(QList<int>, expectedBreakPositions);
QScopedValueRollback<int> default_algorithm(qt_initcharattributes_default_algorithm_only);
qt_initcharattributes_default_algorithm_only++;
doTestData(testString, expectedBreakPositions, QTextBoundaryFinder::Grapheme);
}
void tst_QTextBoundaryFinder::wordBoundariesDefault_data()
{
generateDataFromFile("data/WordBreakTest.txt");
}
void tst_QTextBoundaryFinder::wordBoundariesDefault()
{
QFETCH(QString, testString);
QFETCH(QList<int>, expectedBreakPositions);
QScopedValueRollback<int> default_algorithm(qt_initcharattributes_default_algorithm_only);
qt_initcharattributes_default_algorithm_only++;
doTestData(testString, expectedBreakPositions, QTextBoundaryFinder::Word);
}
void tst_QTextBoundaryFinder::sentenceBoundariesDefault_data()
{
generateDataFromFile("data/SentenceBreakTest.txt");
}
void tst_QTextBoundaryFinder::sentenceBoundariesDefault()
{
QFETCH(QString, testString);
QFETCH(QList<int>, expectedBreakPositions);
QScopedValueRollback<int> default_algorithm(qt_initcharattributes_default_algorithm_only);
qt_initcharattributes_default_algorithm_only++;
doTestData(testString, expectedBreakPositions, QTextBoundaryFinder::Sentence);
}
void tst_QTextBoundaryFinder::lineBoundariesDefault_data()
{
generateDataFromFile("data/LineBreakTest.txt");
}
void tst_QTextBoundaryFinder::lineBoundariesDefault()
{
QFETCH(QString, testString);
QFETCH(QList<int>, expectedBreakPositions);
QScopedValueRollback<int> default_algorithm(qt_initcharattributes_default_algorithm_only);
qt_initcharattributes_default_algorithm_only++;
expectedBreakPositions.prepend(0); // ### QTBF generates a boundary at start of text
doTestData(testString, expectedBreakPositions, QTextBoundaryFinder::Line);
}
#endif // QT_BUILD_INTERNAL
void tst_QTextBoundaryFinder::graphemeBoundaries_manual_data()
{
QTest::addColumn<QString>("testString");
QTest::addColumn<QList<int>>("expectedBreakPositions");
{
// QTBUG-94951
QChar s[] = { QChar(0x2764), // U+2764 HEAVY BLACK HEART
QChar(0xFE0F), // U+FE0F VARIATION SELECTOR-16
QChar(0xD83D), QChar(0xDCF2), // U+1F4F2 MOBILE PHONE WITH RIGHTWARDS ARROW AT LEFT
QChar(0xD83D), QChar(0xDCE9), // U+1F4E9 ENVELOPE WITH DOWNWARDS ARROW ABOVE
};
QString testString(s, sizeof(s)/sizeof(s[0]));
QList<int> expectedBreakPositions{0, 2, 4, 6};
QTest::newRow("+EXTPICxEXT+EXTPIC+EXTPIC+") << testString << expectedBreakPositions;
}
{
QChar s[] = { QChar(0x2764), // U+2764 HEAVY BLACK HEART
QChar(0xFE0F), // U+FE0F VARIATION SELECTOR-16
QChar(0x2764), // U+2764 HEAVY BLACK HEART
QChar(0xFE0F), // U+FE0F VARIATION SELECTOR-16
};
QString testString(s, sizeof(s)/sizeof(s[0]));
QList<int> expectedBreakPositions{0, 2, 4};
QTest::newRow("+EXTPICxEXT+EXTPICxEXT+") << testString << expectedBreakPositions;
}
{
QChar s[] = { QChar(0x2764), // U+2764 HEAVY BLACK HEART
QChar(0xFE0F), // U+FE0F VARIATION SELECTOR-16
QChar(0xFE0F), // U+FE0F VARIATION SELECTOR-16
QChar(0xFE0F), // U+FE0F VARIATION SELECTOR-16
QChar(0x2764), // U+2764 HEAVY BLACK HEART
QChar(0xFE0F), // U+FE0F VARIATION SELECTOR-16
QChar(0xFE0F), // U+FE0F VARIATION SELECTOR-16
};
QString testString(s, sizeof(s)/sizeof(s[0]));
QList<int> expectedBreakPositions{0, 4, 7};
QTest::newRow("+EXTPICxEXTxEXTxEXT+EXTPICxEXTxEXT+") << testString << expectedBreakPositions;
}
{
QChar s[] = { QChar(0x2764), // U+2764 HEAVY BLACK HEART
QChar(0xFE0F), // U+FE0F VARIATION SELECTOR-16
QChar(0xFE0F), // U+FE0F VARIATION SELECTOR-16
QChar(0x200D), // U+200D ZERO WIDTH JOINER
QChar(0xD83D), QChar(0xDCF2), // U+1F4F2 MOBILE PHONE WITH RIGHTWARDS ARROW AT LEFT
QChar(0xFE0F), // U+FE0F VARIATION SELECTOR-16
};
QString testString(s, sizeof(s)/sizeof(s[0]));
QList<int> expectedBreakPositions{0, 7};
QTest::newRow("+EXTPICxEXTxEXTxZWJxEXTPICxEXTxEXT+") << testString << expectedBreakPositions;
}
{
QChar s[] = { QChar(0x2764), // U+2764 HEAVY BLACK HEART
QChar(0xFE0F), // U+FE0F VARIATION SELECTOR-16
QChar(0xFE0F), // U+FE0F VARIATION SELECTOR-16
QChar(0x200D), // U+200D ZERO WIDTH JOINER
QChar(0x0041), // U+0041 LATIN CAPITAL LETTER A
QChar(0xD83D), QChar(0xDCF2), // U+1F4F2 MOBILE PHONE WITH RIGHTWARDS ARROW AT LEFT
};
QString testString(s, sizeof(s)/sizeof(s[0]));
QList<int> expectedBreakPositions{0, 4, 5, 7};
QTest::newRow("+EXTPICxEXTxEXTxZWJ+Any+EXTPIC+") << testString << expectedBreakPositions;
}
{
QChar s[] = { QChar(0x2764), // U+2764 HEAVY BLACK HEART
QChar(0xFE0F), // U+FE0F VARIATION SELECTOR-16
QChar(0xD83C), QChar(0xDDEA), // U+1F1EA REGIONAL INDICATOR SYMBOL LETTER E
QChar(0xD83C), QChar(0xDDFA), // U+1F1FA REGIONAL INDICATOR SYMBOL LETTER U
QChar(0xD83C), QChar(0xDDEA), // U+1F1EA REGIONAL INDICATOR SYMBOL LETTER E
QChar(0xD83C), QChar(0xDDFA), // U+1F1FA REGIONAL INDICATOR SYMBOL LETTER U
QChar(0xD83C), QChar(0xDDEA), // U+1F1EA REGIONAL INDICATOR SYMBOL LETTER E
QChar(0x0041), // U+0041 LATIN CAPITAL LETTER A
};
QString testString(s, sizeof(s)/sizeof(s[0]));
QList<int> expectedBreakPositions{0, 2, 6, 10, 12, 13};
QTest::newRow("+EXTPICxEXT+RIxRI+RIxRI+RI+ANY+") << testString << expectedBreakPositions;
}
}
void tst_QTextBoundaryFinder::graphemeBoundaries_manual()
{
QFETCH(QString, testString);
QFETCH(QList<int>, expectedBreakPositions);
doTestData(testString, expectedBreakPositions, QTextBoundaryFinder::Grapheme);
}
void tst_QTextBoundaryFinder::wordBoundaries_manual_data()
{
QTest::addColumn<QString>("testString");
QTest::addColumn<QList<int> >("expectedBreakPositions");
QTest::addColumn<QList<int> >("expectedStartPositions");
QTest::addColumn<QList<int> >("expectedEndPositions");
{
QChar s[] = { QChar(0x000D), QChar(0x000A), QChar(0x000A) };
QString testString(s, sizeof(s)/sizeof(s[0]));
QList<int> expectedBreakPositions, expectedStartPositions, expectedEndPositions;
expectedBreakPositions << 0 << 2 << 3;
QTest::newRow("+CRxLF+LF+") << testString << expectedBreakPositions
<< expectedStartPositions << expectedEndPositions;
}
{
QChar s[] = { QChar(0x000D), QChar(0x0308), QChar(0x000A), QChar(0x000A) };
QString testString(s, sizeof(s)/sizeof(s[0]));
QList<int> expectedBreakPositions, expectedStartPositions, expectedEndPositions;
expectedBreakPositions << 0 << 1 << 2 << 3 << 4;
QTest::newRow("+CR+FE+LF+LF+") << testString << expectedBreakPositions
<< expectedStartPositions << expectedEndPositions;
}
{
QString testString(QString::fromUtf8("Aaa bbb ccc.\r\nDdd eee fff."));
QList<int> expectedBreakPositions, expectedStartPositions, expectedEndPositions;
expectedBreakPositions << 0 << 3 << 4 << 7 << 8 << 11 << 12 << 14 << 17 << 18 << 21 << 22 << 25 << 26;
expectedStartPositions << 0 << 4 << 8 << 14 << 18 << 22;
expectedEndPositions << 3 << 7 << 11 << 17 << 21 << 25;
QTest::newRow("words1") << testString << expectedBreakPositions
<< expectedStartPositions << expectedEndPositions;
}
{
QString testString(QString::fromUtf8("Hello (sad) world !"));
QList<int> expectedBreakPositions, expectedStartPositions, expectedEndPositions;
expectedBreakPositions << 0 << 5 << 6 << 7 << 10 << 11 << 12 << 17 << 18 << 19;
expectedStartPositions << 0 << 7 << 12;
expectedEndPositions << 5 << 10 << 17;
QTest::newRow("words2") << testString << expectedBreakPositions
<< expectedStartPositions << expectedEndPositions;
}
{
QString testString(QString::fromUtf8("mr.Hamster"));
QList<int> expectedBreakPositions, expectedStartPositions, expectedEndPositions;
expectedBreakPositions << 0 << 2 << 3 << 10;
expectedStartPositions << 0 << 3;
expectedEndPositions << 2 << 10;
QTest::newRow("words3") << testString << expectedBreakPositions
<< expectedStartPositions << expectedEndPositions;
}
{
QString testString(QString::fromUtf8("This is a sample buffer.Please test me . He's don't Le'Clerk."));
QList<int> expectedBreakPositions, expectedStartPositions, expectedEndPositions;
expectedBreakPositions << 0 << 4 << 5 << 7 << 12 << 13 << 14 << 20 << 21 << 27 << 28 << 34
<< 35 << 39 << 40 << 42 << 43 << 44 << 49 << 53 << 54 << 59 << 60
<< 68 << 69;
expectedStartPositions << 0 << 5 << 12 << 14 << 21 << 28 << 35 << 40 << 49 << 54 << 60;
expectedEndPositions << 4 << 7 << 13 << 20 << 27 << 34 << 39 << 42 << 53 << 59 << 68;
QTest::newRow("words4") << testString << expectedBreakPositions
<< expectedStartPositions << expectedEndPositions;
}
{
// text with trailing space
QString testString(QString::fromUtf8("Please test me. Finish "));
QList<int> expectedBreakPositions, expectedStartPositions, expectedEndPositions;
expectedBreakPositions << 0 << 6 << 7 << 11 << 12 << 14 << 15 << 16 << 22 << 23;
expectedStartPositions << 0 << 7 << 12 << 16;
expectedEndPositions << 6 << 11 << 14 << 22;
QTest::newRow("qtbug6498") << testString << expectedBreakPositions
<< expectedStartPositions << expectedEndPositions;
}
// Sample Strings from WordBreakTest.html
{
QChar s[] = { QChar(0x0063), QChar(0x0061), QChar(0x006E), QChar(0x0027), QChar(0x0074) };
QString testString(s, sizeof(s)/sizeof(s[0]));
QList<int> expectedBreakPositions, expectedStartPositions, expectedEndPositions;
expectedBreakPositions << 0 << 5;
expectedStartPositions << 0;
expectedEndPositions << 5;
QTest::newRow("ts 1") << testString << expectedBreakPositions
<< expectedStartPositions << expectedEndPositions;
}
{
QChar s[] = { QChar(0x0063), QChar(0x0061), QChar(0x006E), QChar(0x2019), QChar(0x0074) };
QString testString(s, sizeof(s)/sizeof(s[0]));
QList<int> expectedBreakPositions, expectedStartPositions, expectedEndPositions;
expectedBreakPositions << 0 << 5;
expectedStartPositions << 0;
expectedEndPositions << 5;
QTest::newRow("ts 2") << testString << expectedBreakPositions
<< expectedStartPositions << expectedEndPositions;
}
{
QChar s[] = { QChar(0x0061), QChar(0x0062), QChar(0x00AD), QChar(0x0062), QChar(0x0061) };
QString testString(s, sizeof(s)/sizeof(s[0]));
QList<int> expectedBreakPositions, expectedStartPositions, expectedEndPositions;
expectedBreakPositions << 0 << 5;
expectedStartPositions << 0;
expectedEndPositions << 5;
QTest::newRow("ts 3") << testString << expectedBreakPositions
<< expectedStartPositions << expectedEndPositions;
}
{
QChar s[] = { QChar(0x0061), QChar(0x0024), QChar(0x002D), QChar(0x0033),
QChar(0x0034), QChar(0x002C), QChar(0x0035), QChar(0x0036),
QChar(0x0037), QChar(0x002E), QChar(0x0031), QChar(0x0034),
QChar(0x0025), QChar(0x0062) };
QString testString(s, sizeof(s)/sizeof(s[0]));
QList<int> expectedBreakPositions, expectedStartPositions, expectedEndPositions;
expectedBreakPositions << 0 << 1 << 2 << 3 << 12 << 13 << 14;
expectedStartPositions << 0 << 3 << 13;
expectedEndPositions << 1 << 12 << 14;
QTest::newRow("ts 4") << testString << expectedBreakPositions
<< expectedStartPositions << expectedEndPositions;
}
{
QChar s[] = { QChar(0x0033), QChar(0x0061) };
QString testString(s, sizeof(s)/sizeof(s[0]));
QList<int> expectedBreakPositions, expectedStartPositions, expectedEndPositions;
expectedBreakPositions << 0 << 2;
expectedStartPositions << 0;
expectedEndPositions << 2;
QTest::newRow("ts 5") << testString << expectedBreakPositions
<< expectedStartPositions << expectedEndPositions;
}
{
QChar s[] = { QChar(0x2060), QChar(0x0063), QChar(0x2060), QChar(0x0061),
QChar(0x2060), QChar(0x006E), QChar(0x2060), QChar(0x0027),
QChar(0x2060), QChar(0x0074), QChar(0x2060), QChar(0x2060) };
QString testString(s, sizeof(s)/sizeof(s[0]));
QList<int> expectedBreakPositions, expectedStartPositions, expectedEndPositions;
expectedBreakPositions << 0 << 1 << 12;
expectedStartPositions << 1;
expectedEndPositions << 12;
QTest::newRow("ts 1e") << testString << expectedBreakPositions
<< expectedStartPositions << expectedEndPositions;
}
{
QChar s[] = { QChar(0x2060), QChar(0x0063), QChar(0x2060), QChar(0x0061),
QChar(0x2060), QChar(0x006E), QChar(0x2060), QChar(0x2019),
QChar(0x2060), QChar(0x0074), QChar(0x2060), QChar(0x2060) };
QString testString(s, sizeof(s)/sizeof(s[0]));
QList<int> expectedBreakPositions, expectedStartPositions, expectedEndPositions;
expectedBreakPositions << 0 << 1 << 12;
expectedStartPositions << 1;
expectedEndPositions << 12;
QTest::newRow("ts 2e") << testString << expectedBreakPositions
<< expectedStartPositions << expectedEndPositions;
}
{
QChar s[] = { QChar(0x2060), QChar(0x0061), QChar(0x2060), QChar(0x0062),
QChar(0x2060), QChar(0x00AD), QChar(0x2060), QChar(0x0062),
QChar(0x2060), QChar(0x0061), QChar(0x2060), QChar(0x2060) };
QString testString(s, sizeof(s)/sizeof(s[0]));
QList<int> expectedBreakPositions, expectedStartPositions, expectedEndPositions;
expectedBreakPositions << 0 << 1 << 12;
expectedStartPositions << 1;
expectedEndPositions << 12;
QTest::newRow("ts 3e") << testString << expectedBreakPositions
<< expectedStartPositions << expectedEndPositions;
}
{
QChar s[] = { QChar(0x2060), QChar(0x0061), QChar(0x2060), QChar(0x0024),
QChar(0x2060), QChar(0x002D), QChar(0x2060), QChar(0x0033),
QChar(0x2060), QChar(0x0034), QChar(0x2060), QChar(0x002C),
QChar(0x2060), QChar(0x0035), QChar(0x2060), QChar(0x0036),
QChar(0x2060), QChar(0x0037), QChar(0x2060), QChar(0x002E),
QChar(0x2060), QChar(0x0031), QChar(0x2060), QChar(0x0034),
QChar(0x2060), QChar(0x0025), QChar(0x2060), QChar(0x0062),
QChar(0x2060), QChar(0x2060) };
QString testString(s, sizeof(s)/sizeof(s[0]));
QList<int> expectedBreakPositions, expectedStartPositions, expectedEndPositions;
expectedBreakPositions << 0 << 1 << 3 << 5 << 7 << 25 << 27 << 30;
expectedStartPositions << 1 << 7 << 27;
expectedEndPositions << 3 << 25 << 30;
QTest::newRow("ts 4e") << testString << expectedBreakPositions
<< expectedStartPositions << expectedEndPositions;
}
{
QChar s[] = { QChar(0x2060), QChar(0x0033), QChar(0x2060), QChar(0x0061),
QChar(0x2060), QChar(0x2060) };
QString testString(s, sizeof(s)/sizeof(s[0]));
QList<int> expectedBreakPositions, expectedStartPositions, expectedEndPositions;
expectedBreakPositions << 0 << 1 << 6;
expectedStartPositions << 1;
expectedEndPositions << 6;
QTest::newRow("ts 5e") << testString << expectedBreakPositions
<< expectedStartPositions << expectedEndPositions;
}
}
void tst_QTextBoundaryFinder::wordBoundaries_manual()
{
QFETCH(QString, testString);
QFETCH(QList<int>, expectedBreakPositions);
QFETCH(QList<int>, expectedStartPositions);
QFETCH(QList<int>, expectedEndPositions);
doTestData(testString, expectedBreakPositions, QTextBoundaryFinder::Word);
doTestData(testString, expectedStartPositions, QTextBoundaryFinder::Word, QTextBoundaryFinder::StartOfItem);
doTestData(testString, expectedEndPositions, QTextBoundaryFinder::Word, QTextBoundaryFinder::EndOfItem);
}
void tst_QTextBoundaryFinder::sentenceBoundaries_manual_data()
{
QTest::addColumn<QString>("testString");
QTest::addColumn<QList<int> >("expectedBreakPositions");
{
QChar s[] = { QChar(0x000D), QChar(0x000A), QChar(0x000A) };
QString testString(s, sizeof(s)/sizeof(s[0]));
QList<int> expectedBreakPositions;
expectedBreakPositions << 0 << 2 << 3;
QTest::newRow("+CRxLF+LF+") << testString << expectedBreakPositions;
}
{
QChar s[] = { QChar(0x000D), QChar(0x0308), QChar(0x000A), QChar(0x000A) };
QString testString(s, sizeof(s)/sizeof(s[0]));
QList<int> expectedBreakPositions;
expectedBreakPositions << 0 << 1 << 3 << 4;
QTest::newRow("+CR+FExLF+LF+") << testString << expectedBreakPositions;
}
{
QString testString(QString::fromUtf8("Aaa bbb ccc.\r\nDdd eee fff."));
QList<int> expectedBreakPositions;
expectedBreakPositions << 0 << 14 << 26;
QTest::newRow("data1") << testString << expectedBreakPositions;
}
{
QString testString(QString::fromUtf8("Diga-nos qualé a sua opinião"));
QList<int> expectedBreakPositions;
expectedBreakPositions << 0 << 28;
QTest::newRow("data2") << testString << expectedBreakPositions;
}
{
QString testString(QString::fromUtf8("mr.Hamster"));
QList<int> expectedBreakPositions;
expectedBreakPositions << 0 << 3 << 10;
QTest::newRow("data3") << testString << expectedBreakPositions;
}
{
QString testString(QString::fromUtf8("Doing TEST, doing another test."));
QList<int> expectedBreakPositions;
expectedBreakPositions << 0 << 31;
QTest::newRow("data4") << testString << expectedBreakPositions;
}
}
void tst_QTextBoundaryFinder::sentenceBoundaries_manual()
{
QFETCH(QString, testString);
QFETCH(QList<int>, expectedBreakPositions);
QVERIFY(expectedBreakPositions.size() >= 2);
QList<int> expectedStartPositions = expectedBreakPositions; expectedStartPositions.removeLast();
QList<int> expectedEndPositions = expectedBreakPositions; expectedEndPositions.removeFirst();
doTestData(testString, expectedBreakPositions, QTextBoundaryFinder::Sentence);
doTestData(testString, expectedStartPositions, QTextBoundaryFinder::Sentence, QTextBoundaryFinder::StartOfItem);
doTestData(testString, expectedEndPositions, QTextBoundaryFinder::Sentence, QTextBoundaryFinder::EndOfItem);
}
void tst_QTextBoundaryFinder::lineBoundaries_manual_data()
{
QTest::addColumn<QString>("testString");
QTest::addColumn<QList<int> >("expectedBreakPositions");
QTest::addColumn<QList<int> >("expectedMandatoryBreakPositions");
{
QString testString(QString::fromUtf8("Aaa bbb ccc.\r\nDdd eee fff."));
QList<int> expectedBreakPositions, expectedMandatoryBreakPositions;
expectedBreakPositions << 0 << 4 << 8 << 14 << 18 << 22 << 26;
expectedMandatoryBreakPositions << 0 << 14 << 26;
QTest::newRow("data1") << testString << expectedBreakPositions
<< expectedMandatoryBreakPositions;
}
{
QString testString(QString::fromUtf8("Diga-nos qualé a sua opinião"));
QList<int> expectedBreakPositions, expectedMandatoryBreakPositions;
expectedBreakPositions << 0 << 5 << 9 << 15 << 17 << 21 << 28;
expectedMandatoryBreakPositions << 0 << 28;
QTest::newRow("data2") << testString << expectedBreakPositions
<< expectedMandatoryBreakPositions;
}
{
QChar s[] = { QChar(0x000D), QChar(0x0308), QChar(0x000A), QChar(0x000A), QChar(0x0020) };
QString testString(s, sizeof(s)/sizeof(s[0]));
QList<int> expectedBreakPositions, expectedMandatoryBreakPositions;
expectedBreakPositions << 0 << 1 << 3 << 4 << 5;
expectedMandatoryBreakPositions << 0 << 1 << 3 << 4 << 5;
QTest::newRow("x(CR)+(FE)x(LF)+(LF)+(SP)+") << testString << expectedBreakPositions
<< expectedMandatoryBreakPositions;
}
{
QChar s[] = { QChar(0x000A), QChar(0x2E80), QChar(0x0308), QChar(0x0023), QChar(0x0023) };
QString testString(s, sizeof(s)/sizeof(QChar));
QList<int> expectedBreakPositions, expectedMandatoryBreakPositions;
expectedBreakPositions << 0 << 1 << 3 << 5;
expectedMandatoryBreakPositions << 0 << 1 << 5;
QTest::newRow("x(LF)+(ID)x(CM)+(AL)x(AL)+") << testString << expectedBreakPositions
<< expectedMandatoryBreakPositions;
}
{
QChar s[] = { QChar(0x000A), QChar(0x0308), QChar(0x0023), QChar(0x0023) };
QString testString(s, sizeof(s)/sizeof(QChar));
QList<int> expectedBreakPositions, expectedMandatoryBreakPositions;
expectedBreakPositions << 0 << 1 << 4;
expectedMandatoryBreakPositions << 0 << 1 << 4;
QTest::newRow("x(LF)+(CM)x(AL)x(AL)+") << testString << expectedBreakPositions
<< expectedMandatoryBreakPositions;
}
{
QChar s[] = { QChar(0x0061), QChar(0x00AD), QChar(0x0062), QChar(0x0009), QChar(0x0063), QChar(0x0064) };
QString testString(s, sizeof(s)/sizeof(s[0]));
QList<int> expectedBreakPositions, expectedMandatoryBreakPositions;
expectedBreakPositions << 0 << 2 << 4 << 6;
expectedMandatoryBreakPositions << 0 << 6;
QTest::newRow("x(AL)x(BA)+(AL)x(BA)+(AL)x(AL)+") << testString << expectedBreakPositions
<< expectedMandatoryBreakPositions;
}
}
void tst_QTextBoundaryFinder::lineBoundaries_manual()
{
QFETCH(QString, testString);
QFETCH(QList<int>, expectedBreakPositions);
QFETCH(QList<int>, expectedMandatoryBreakPositions);
QVERIFY(expectedMandatoryBreakPositions.size() >= 2);
QList<int> expectedStartPositions = expectedMandatoryBreakPositions; expectedStartPositions.removeLast();
QList<int> expectedEndPositions = expectedMandatoryBreakPositions; expectedEndPositions.removeFirst();
doTestData(testString, expectedBreakPositions, QTextBoundaryFinder::Line);
doTestData(testString, expectedMandatoryBreakPositions, QTextBoundaryFinder::Line, QTextBoundaryFinder::MandatoryBreak);
doTestData(testString, expectedStartPositions, QTextBoundaryFinder::Line, QTextBoundaryFinder::StartOfItem);
doTestData(testString, expectedEndPositions, QTextBoundaryFinder::Line, QTextBoundaryFinder::EndOfItem);
}
Q_DECLARE_METATYPE(QTextBoundaryFinder)
void tst_QTextBoundaryFinder::emptyText_data()
{
QTest::addColumn<QTextBoundaryFinder>("boundaryFinder");
QString empty;
QString notEmpty(QLatin1String("not empty"));
uchar attrs[11];
QTextBoundaryFinder invalidFinder(QTextBoundaryFinder::Word, empty);
QTest::newRow("empty1") << invalidFinder;
QTextBoundaryFinder finder(invalidFinder);
QTest::newRow("empty2") << finder;
finder = QTextBoundaryFinder(QTextBoundaryFinder::Grapheme, notEmpty);
finder = invalidFinder;
QTest::newRow("empty3") << finder;
QTest::newRow("empty4") << QTextBoundaryFinder(QTextBoundaryFinder::Word, notEmpty.constData(), 0, 0, 0);
QTest::newRow("empty5") << QTextBoundaryFinder(QTextBoundaryFinder::Word, notEmpty.constData(), 0, attrs, 11);
}
void tst_QTextBoundaryFinder::emptyText()
{
QFETCH(QTextBoundaryFinder, boundaryFinder);
QCOMPARE(boundaryFinder.position(), 0);
QCOMPARE(boundaryFinder.boundaryReasons(), QTextBoundaryFinder::NotAtBoundary);
boundaryFinder.toNextBoundary();
QCOMPARE(boundaryFinder.position(), -1);
QCOMPARE(boundaryFinder.boundaryReasons(), QTextBoundaryFinder::NotAtBoundary);
}
void tst_QTextBoundaryFinder::fastConstructor()
{
QString text("Hello World");
QTextBoundaryFinder finder(QTextBoundaryFinder::Word, text.constData(), text.size(), /*buffer*/0, /*buffer size*/0);
QCOMPARE(finder.position(), 0);
QVERIFY(finder.boundaryReasons() & QTextBoundaryFinder::StartOfItem);
finder.toNextBoundary();
QCOMPARE(finder.position(), 5);
QVERIFY(finder.boundaryReasons() & QTextBoundaryFinder::EndOfItem);
finder.toNextBoundary();
QCOMPARE(finder.position(), 6);
QVERIFY(finder.boundaryReasons() & QTextBoundaryFinder::StartOfItem);
finder.toNextBoundary();
QCOMPARE(finder.position(), text.size());
QVERIFY(finder.boundaryReasons() & QTextBoundaryFinder::EndOfItem);
finder.toNextBoundary();
QCOMPARE(finder.position(), -1);
QCOMPARE(finder.boundaryReasons(), QTextBoundaryFinder::NotAtBoundary);
}
void tst_QTextBoundaryFinder::assignmentOperator()
{
QString text(QLatin1String("Hello World"));
QTextBoundaryFinder invalidFinder;
QVERIFY(!invalidFinder.isValid());
QCOMPARE(invalidFinder.string(), QString());
QTextBoundaryFinder validFinder(QTextBoundaryFinder::Word, text);
QVERIFY(validFinder.isValid());
QCOMPARE(validFinder.string(), text);
QTextBoundaryFinder finder(QTextBoundaryFinder::Line, QLatin1String("dummy"));
QVERIFY(finder.isValid());
finder = invalidFinder;
QVERIFY(!finder.isValid());
QCOMPARE(finder.string(), QString());
finder = validFinder;
QVERIFY(finder.isValid());
QCOMPARE(finder.string(), text);
}
void tst_QTextBoundaryFinder::isAtSoftHyphen_data()
{
QTest::addColumn<QString>("testString");
QTest::addColumn<QList<int> >("expectedBreakPositions");
QTest::addColumn<QList<int> >("expectedSoftHyphenPositions");
{
QString testString = QString::fromUtf8("I a-m break-able");
testString.replace(QLatin1Char('-'), QChar(QChar::SoftHyphen));
QList<int> expectedBreakPositions, expectedSoftHyphenPositions;
expectedBreakPositions << 0 << 2 << 4 << 6 << 12 << 16;
expectedSoftHyphenPositions << 4 << 12;
QTest::newRow("Soft Hyphen") << testString << expectedBreakPositions
<< expectedSoftHyphenPositions;
}
}
void tst_QTextBoundaryFinder::isAtSoftHyphen()
{
QFETCH(QString, testString);
QFETCH(QList<int>, expectedBreakPositions);
QFETCH(QList<int>, expectedSoftHyphenPositions);
doTestData(testString, expectedBreakPositions, QTextBoundaryFinder::Line);
doTestData(testString, expectedSoftHyphenPositions, QTextBoundaryFinder::Line, QTextBoundaryFinder::SoftHyphen);
}
#if QT_CONFIG(library)
#include <qlibrary.h>
#endif
#define LIBTHAI_MAJOR 0
typedef int (*th_brk_def) (const unsigned char*, int*, size_t);
static th_brk_def th_brk = 0;
static bool init_libthai()
{
#if QT_CONFIG(library)
static bool triedResolve = false;
if (!triedResolve) {
th_brk = (th_brk_def) QLibrary::resolve("thai", (int)LIBTHAI_MAJOR, "th_brk");
triedResolve = true;
}
#endif
return th_brk != 0;
}
void tst_QTextBoundaryFinder::thaiLineBreak()
{
if (!init_libthai())
QSKIP("This test requires libThai-0.1.1x to be installed.");
#if 0
QString text = QString::fromUtf8("สวัสดีครับ นี่เป็นการงทดสอบตัวเอ");
QTextBoundaryFinder finder(QTextBoundaryFinder::Line, text);
finder.setPosition(0);
QVERIFY(finder.isAtBoundary());
finder.setPosition(1);
QVERIFY(!finder.isAtBoundary());
finder.setPosition(2);
QVERIFY(!finder.isAtBoundary());
finder.setPosition(3);
QVERIFY(!finder.isAtBoundary());
finder.setPosition(4);
QVERIFY(!finder.isAtBoundary());
finder.setPosition(5);
QVERIFY(!finder.isAtBoundary());
finder.setPosition(6);
QVERIFY(finder.isAtBoundary());
finder.setPosition(7);
QVERIFY(finder.isAtBoundary());
finder.setPosition(8);
QVERIFY(!finder.isAtBoundary());
finder.setPosition(9);
QVERIFY(!finder.isAtBoundary());
finder.setPosition(10);
QVERIFY(!finder.isAtBoundary());
finder.setPosition(11);
QVERIFY(finder.isAtBoundary());
finder.setPosition(12);
QVERIFY(!finder.isAtBoundary());
finder.setPosition(13);
QVERIFY(!finder.isAtBoundary());
finder.setPosition(14);
QVERIFY(finder.isAtBoundary());
finder.setPosition(15);
QVERIFY(!finder.isAtBoundary());
finder.setPosition(16);
QVERIFY(!finder.isAtBoundary());
finder.setPosition(17);
QVERIFY(!finder.isAtBoundary());
finder.setPosition(18);
QVERIFY(finder.isAtBoundary());
finder.setPosition(19);
QVERIFY(!finder.isAtBoundary());
finder.setPosition(20);
QVERIFY(finder.isAtBoundary());
finder.setPosition(21);
QVERIFY(finder.isAtBoundary());
finder.setPosition(22);
QVERIFY(!finder.isAtBoundary());
finder.setPosition(23);
QVERIFY(!finder.isAtBoundary());
finder.setPosition(24);
QVERIFY(!finder.isAtBoundary());
finder.setPosition(25);
QVERIFY(finder.isAtBoundary());
finder.setPosition(26);
QVERIFY(finder.isAtBoundary());
for (int i = 27; i < 32; ++i) {
finder.setPosition(i);
QVERIFY(!finder.isAtBoundary());
}
#endif
}
QTEST_MAIN(tst_QTextBoundaryFinder)
#include "tst_qtextboundaryfinder.moc"

View File

@ -0,0 +1,14 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qunicodetools Test:
#####################################################################
qt_internal_add_test(tst_qunicodetools
SOURCES
tst_qunicodetools.cpp
LIBRARIES
Qt::CorePrivate
)

View File

@ -0,0 +1,199 @@
// Copyright (C) 2021 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include <QTest>
#include <qchar.h>
#include <qfile.h>
#include <qstringlist.h>
#include <private/qunicodetables_p.h>
#include <private/qunicodetools_p.h>
class tst_QUnicodeTools : public QObject
{
Q_OBJECT
private slots:
void lineBreakClass();
void graphemeBreakClass_data();
void graphemeBreakClass();
void wordBreakClass_data();
void wordBreakClass();
void sentenceBreakClass_data();
void sentenceBreakClass();
};
void tst_QUnicodeTools::lineBreakClass()
{
QVERIFY(QUnicodeTables::lineBreakClass(0x0029) == QUnicodeTables::LineBreak_CP);
QVERIFY(QUnicodeTables::lineBreakClass(0x0041) == QUnicodeTables::LineBreak_AL);
QVERIFY(QUnicodeTables::lineBreakClass(0x0033) == QUnicodeTables::LineBreak_NU);
QVERIFY(QUnicodeTables::lineBreakClass(0x00ad) == QUnicodeTables::LineBreak_BA);
QVERIFY(QUnicodeTables::lineBreakClass(0x05d0) == QUnicodeTables::LineBreak_HL);
QVERIFY(QUnicodeTables::lineBreakClass(0xfffc) == QUnicodeTables::LineBreak_CB);
QVERIFY(QUnicodeTables::lineBreakClass(0xe0164) == QUnicodeTables::LineBreak_CM);
QVERIFY(QUnicodeTables::lineBreakClass(0x2f9a4) == QUnicodeTables::LineBreak_ID);
QVERIFY(QUnicodeTables::lineBreakClass(0x10000) == QUnicodeTables::LineBreak_AL);
QVERIFY(QUnicodeTables::lineBreakClass(0x1f1e6) == QUnicodeTables::LineBreak_RI);
// mapped to AL:
QVERIFY(QUnicodeTables::lineBreakClass(0xfffd) == QUnicodeTables::LineBreak_AL); // AI -> AL
QVERIFY(QUnicodeTables::lineBreakClass(0x100000) == QUnicodeTables::LineBreak_AL); // XX -> AL
}
static void verifyCharClassPattern(QString str, qulonglong pattern,
QUnicodeTools::CharAttributeOptions type)
{
QUnicodeTools::ScriptItemArray scriptItems;
QUnicodeTools::initScripts(str, &scriptItems);
QCharAttributes cleared;
memset(&cleared, 0, sizeof(QCharAttributes));
QList<QCharAttributes> attributes(str.size() + 1, cleared);
QUnicodeTools::initCharAttributes(str, scriptItems.data(), scriptItems.size(),
attributes.data(), type);
qulonglong bit = 1ull << str.size();
Q_ASSERT(str.size() < std::numeric_limits<decltype(bit)>::digits);
for (qsizetype i = 0; i < str.size(); ++i) {
bit >>= 1;
bool test = pattern & bit;
bool isSet = false;
switch (type) {
case QUnicodeTools::GraphemeBreaks:
isSet = attributes[i].graphemeBoundary;
break;
case QUnicodeTools::WordBreaks:
isSet = attributes[i].wordBreak;
break;
case QUnicodeTools::SentenceBreaks:
isSet = attributes[i].sentenceBoundary;
break;
default:
Q_UNREACHABLE();
break;
};
QVERIFY2(isSet == test,
qPrintable(QString("Character #%1: 0x%2, isSet: %3")
.arg(i).arg(str[i].unicode(), 0, 16).arg(isSet)));
}
}
void tst_QUnicodeTools::graphemeBreakClass_data()
{
QTest::addColumn<QString>("str");
QTest::addColumn<int>("pattern");
// A grapheme cluster is a set of unicode code points that is
// seen as a single character.
// The pattern has one bit per code point.
// A pattern bit is set whenever a new grapheme cluster begins.
// A pattern bit is cleared for every code point that modifies
// the current graphene cluster.
QTest::addRow("g and combining diaeresis")
<< u8"g\u0308"
<< 0b10;
QTest::addRow("hangul gag single")
<< u8"\uAC01"
<< 0b1;
QTest::addRow("hangul gag cluster")
<< u8"\u1100\u1161\u11A8"
<< 0b100;
QTest::addRow("thai ko")
<< u8"\u0E01"
<< 0b1;
QTest::addRow("tamil ni")
<< u8"\u0BA8\u0BBF"
<< 0b10;
QTest::addRow("thai e")
<< u8"\u0E40"
<< 0b1;
QTest::addRow("thai kam")
<< u8"\u0E01\u0E33"
<< 0b10;
QTest::addRow("devanagari ssi")
<< u8"\u0937\u093F"
<< 0b10;
QTest::addRow("thai am")
<< u8"\u0E33"
<< 0b1;
QTest::addRow("devanagari ssa")
<< u8"\u0937"
<< 0b1;
QTest::addRow("devanagari i")
<< u8"\u093F"
<< 0b1;
QTest::addRow("devanagari kshi")
<< u8"\u0915\u094D\u0937\u093F"
<< 0b1000;
}
void tst_QUnicodeTools::graphemeBreakClass()
{
QFETCH(QString, str);
QFETCH(int, pattern);
verifyCharClassPattern(str, pattern, QUnicodeTools::GraphemeBreaks);
}
void tst_QUnicodeTools::wordBreakClass_data()
{
QTest::addColumn<QString>("str");
QTest::addColumn<qulonglong>("pattern");
// Word boundaries are used for things like selection and whole word search.
// Typically they are beginning of words, whitespaces and punctuation.
QTest::addRow("two words")
<< "two words"
<< 0b100110000ULL;
// breaks at beginning of words and space
QTest::addRow("three words")
<< "The quick fox"
<< 0b1001100001100ULL;
// breaks at beginning of words and spaces
QTest::addRow("quoted")
<< u8"The quick (\"brown\") fox"
<< 0b10011000011'110000'111100ULL;
// as above plus quotes and parentesis
QTest::addRow("long")
<< "The quick (\"brown\") fox cant jump 32.3 feet, right?"
<< 0b10011000011'110000'11110011000011000110001100011100001ULL;
// as above plus commma and question mark
// but decimal separator and apostrophes are not word breaks
}
void tst_QUnicodeTools::wordBreakClass()
{
QFETCH(QString, str);
QFETCH(qulonglong, pattern);
verifyCharClassPattern(str, pattern, QUnicodeTools::WordBreaks);
}
void tst_QUnicodeTools::sentenceBreakClass_data()
{
QTest::addColumn<QString>("str");
QTest::addColumn<qulonglong>("pattern");
// Sentence boundaries are at the beginning of each new sentence
QTest::addRow("one sentence")
<< "One sentence."
<< 0b1000000000000ULL;
QTest::addRow("two sentences")
<< "One sentence. One more."
<< 0b10000000000000100000000ULL;
QTest::addRow("question")
<< "Who said \"Hey you?\" I did."
<< 0b100000000'000000000'00100000ULL;
}
void tst_QUnicodeTools::sentenceBreakClass()
{
QFETCH(QString, str);
QFETCH(qulonglong, pattern);
verifyCharClassPattern(str, pattern, QUnicodeTools::SentenceBreaks);
}
QTEST_APPLESS_MAIN(tst_QUnicodeTools)
#include "tst_qunicodetools.moc"

View File

@ -0,0 +1,105 @@
// Copyright (C) 2021 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include <limits>
#include <QtCore/qstring.h>
#include <QtCore/qlocale.h>
struct NumberDoubleTestData
{
double d;
char f;
int p;
QLatin1String expected;
QLatin1String optTitle = {}; // optional
// Tests with same (f, p, expected) should use optTitle to avoid duplicate data tags.
};
template<typename Fun>
inline void add_number_double_shared_data(Fun addTestRowFunction)
{
constexpr double nan = std::numeric_limits<double>::quiet_NaN();
constexpr double inf = std::numeric_limits<double>::infinity();
const static NumberDoubleTestData data[] {
{ 0.0, 'f', 0, QLatin1String("0") },
{ 0.0, 'e', 0, QLatin1String("0e+00") },
{ 0.0, 'e', 1, QLatin1String("0.0e+00") },
{ 0.0001, 'f', 0, QLatin1String("0"), QLatin1String("0(.0001)") },
{ 0.1234, 'f', 5, QLatin1String("0.12340") },
{ -0.1234, 'f', 5, QLatin1String("-0.12340") },
{ 0.0000000314, 'f', 12, QLatin1String("0.000000031400") },
{ -0.0000000314, 'f', 12, QLatin1String("-0.000000031400") },
{ -100000, 'f', 15, QLatin1String("-100000.000000000000000") },
{ 0.5 + qSqrt(1.25), 'f', 15, QLatin1String("1.618033988749895") },
{ 0.5 + qSqrt(1.25), 'e', 15, QLatin1String("1.618033988749895e+00") },
{ 1.7976931348623157e+308, 'f', 120,
QLatin1String(
"17976931348623157081452742373170435679807056752584499659891747680315726078002853"
"87605895586327668781715404589535143824642343213268894641827684675467035375169860"
"49910576551282076245490090389328944075868508455133942304583236903222948165808559"
"332123348274797826204144723168738177180919299881250404026184124858368."
"00000000000000000000000000000000000000000000000000000000000000000000000000000000"
"0000000000000000000000000000000000000000"),
QLatin1String("Big number, high precision") },
{ 1.0, 'f', 350,
QLatin1String(
"1.0000000000000000000000000000000000000000000000000000000000000000000000000"
"00000000000000000000000000000000000000000000000000000000000000000000000000"
"00000000000000000000000000000000000000000000000000000000000000000000000000"
"00000000000000000000000000000000000000000000000000000000000000000000000000"
"0000000000000000000000000000000000000000000000000000000"),
QLatin1String("Very high precision 1") },
{ 1.0e-308, 'f', 350,
QLatin1String("0."
"00000000000000000000000000000000000000000000000000000000000000000000000000"
"00000000000000000000000000000000000000000000000000000000000000000000000000"
"00000000000000000000000000000000000000000000000000000000000000000000000000"
"00000000000000000000000000000000000000000000000000000000000000000000000000"
"000000000000999999999999999909326625337248461995470489"),
QLatin1String("Very small number, very high precision") },
{ std::numeric_limits<double>::epsilon(), 'g', 10, QLatin1String("2.220446049e-16") },
{ 0.0001, 'e', 1, QLatin1String("1.0e-04") },
{ 1e8, 'e', 1, QLatin1String("1.0e+08") },
{ -1e8, 'e', 1, QLatin1String("-1.0e+08") },
{ 1.1e-8, 'e', 6, QLatin1String("1.100000e-08") },
{ -1.1e-8, 'e', 6, QLatin1String("-1.100000e-08") },
{ 1.1e+8, 'e', 6, QLatin1String("1.100000e+08") },
{ -1.1e+8, 'e', 6, QLatin1String("-1.100000e+08") },
{ 100000, 'f', 0, QLatin1String("100000") },
// Increasingly small fraction, test how/when 'g' switches to scientific notation:
{ 0.001, 'g', 6, QLatin1String("0.001") },
{ 0.0001, 'g', 6, QLatin1String("0.0001") },
{ 0.00001, 'g', 6, QLatin1String("1e-05") },
{ 0.000001, 'g', 6, QLatin1String("1e-06") },
// FloatingPointShortest is relied upon by various facilities:
{ 1.0, 'g', QLocale::FloatingPointShortest, QLatin1String("1") },
{ 0.01, 'g', QLocale::FloatingPointShortest, QLatin1String("0.01") },
{ 123.456, 'g', QLocale::FloatingPointShortest, QLatin1String("123.456") },
{ 12.12, 'g', QLocale::FloatingPointShortest, QLatin1String("12.12") },
{ 0.000001, 'g', QLocale::FloatingPointShortest, QLatin1String("1e-06") },
{ 100000, 'g', QLocale::FloatingPointShortest, QLatin1String("1e+05") },
// inf and nan testing:
{ inf, 'g', QLocale::FloatingPointShortest, QLatin1String("inf") },
{ -inf, 'g', QLocale::FloatingPointShortest, QLatin1String("-inf") },
{ nan, 'g', QLocale::FloatingPointShortest, QLatin1String("nan") },
{ inf, 'f', 15, QLatin1String("inf") },
{ -inf, 'f', 15, QLatin1String("-inf") },
{ nan, 'f', 15, QLatin1String("nan") },
{ inf, 'e', 2, QLatin1String("inf") },
{ -inf, 'e', 2, QLatin1String("-inf") },
{ nan, 'e', 2, QLatin1String("nan") },
// Negative precision (except QLocale::F.P.Shortest) defaults to 6:
{ 0.001, 'f', -50, QLatin1String("0.001000") },
{ 0.0001, 'f', -62, QLatin1String("0.000100") },
{ 0.00001, 'f', -11, QLatin1String("0.000010") },
{ 0.000001, 'f', -41, QLatin1String("0.000001") },
{ 0.0000001, 'f', -21, QLatin1String("0.000000") },
// Some rounding tests
{ 10.5, 'f', 0, QLatin1String("11") },
{ 12.05, 'f', 1, QLatin1String("12.1") },
{ 14.500000000000001, 'f', 0, QLatin1String("15") },
{ 16.5000000000000001, 'f', 0, QLatin1String("17") },
};
for (auto datum : data)
addTestRowFunction(datum);
}