From 7a3a9b8eb542196ed8e18e36b830396f54a3f63d Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Wed, 13 May 2020 21:07:31 +0200 Subject: [PATCH] QStringMatcher: port internals to QStringView and char16_t Change-Id: If540b094d003ad373d3c581e1de8c526ad4c7d73 Reviewed-by: Lars Knoll Reviewed-by: Edward Welbourne --- src/corelib/text/qstringmatcher.cpp | 50 ++++++++++++++++------------- src/corelib/text/qstringmatcher.h | 4 +-- 2 files changed, 30 insertions(+), 24 deletions(-) diff --git a/src/corelib/text/qstringmatcher.cpp b/src/corelib/text/qstringmatcher.cpp index 167a467480..8694255052 100644 --- a/src/corelib/text/qstringmatcher.cpp +++ b/src/corelib/text/qstringmatcher.cpp @@ -42,8 +42,10 @@ QT_BEGIN_NAMESPACE -static void bm_init_skiptable(const ushort *uc, qsizetype len, uchar *skiptable, Qt::CaseSensitivity cs) +static void bm_init_skiptable(QStringView needle, uchar *skiptable, Qt::CaseSensitivity cs) { + const char16_t *uc = needle.utf16(); + const qsizetype len = needle.size(); int l = int(qMin(len, qsizetype(255))); memset(skiptable, l, 256 * sizeof(uchar)); uc += len - l; @@ -53,7 +55,7 @@ static void bm_init_skiptable(const ushort *uc, qsizetype len, uchar *skiptable, ++uc; } } else { - const ushort *start = uc; + const char16_t *start = uc; while (l--) { skiptable[foldCase(uc, start) & 0xff] = l; ++uc; @@ -61,15 +63,20 @@ static void bm_init_skiptable(const ushort *uc, qsizetype len, uchar *skiptable, } } -static inline qsizetype bm_find(const ushort *uc, qsizetype l, qsizetype index, const ushort *puc, qsizetype pl, +static inline qsizetype bm_find(QStringView haystack, qsizetype index, QStringView needle, const uchar *skiptable, Qt::CaseSensitivity cs) { + const char16_t *uc = haystack.utf16(); + const qsizetype l = haystack.size(); + const char16_t *puc = needle.utf16(); + const qsizetype pl = needle.size(); + if (pl == 0) return index > l ? -1 : index; const qsizetype pl_minus_one = pl - 1; - const ushort *current = uc + index + pl_minus_one; - const ushort *end = uc + l; + const char16_t *current = uc + index + pl_minus_one; + const char16_t *end = uc + l; if (cs == Qt::CaseSensitive) { while (current < end) { qsizetype skip = skiptable[*current & 0xff]; @@ -121,6 +128,11 @@ static inline qsizetype bm_find(const ushort *uc, qsizetype l, qsizetype index, return -1; // not found } +void QStringMatcher::updateSkipTable() +{ + bm_init_skiptable(p.sv, p.q_skiptable, q_cs); +} + /*! \class QStringMatcher \inmodule QtCore @@ -163,9 +175,8 @@ QStringMatcher::QStringMatcher() QStringMatcher::QStringMatcher(const QString &pattern, Qt::CaseSensitivity cs) : d_ptr(nullptr), q_pattern(pattern), q_cs(cs) { - p.uc = pattern.unicode(); - p.len = pattern.size(); - bm_init_skiptable((const ushort *)p.uc, p.len, p.q_skiptable, cs); + p.sv = q_pattern; + updateSkipTable(); } /*! @@ -192,9 +203,8 @@ QStringMatcher::QStringMatcher(const QChar *uc, int len, Qt::CaseSensitivity cs) QStringMatcher::QStringMatcher(QStringView str, Qt::CaseSensitivity cs) : d_ptr(nullptr), q_cs(cs) { - p.uc = str.data(); - p.len = int(str.size()); - bm_init_skiptable((const ushort *)p.uc, p.len, p.q_skiptable, cs); + p.sv = str; + updateSkipTable(); } /*! Copies the \a other string matcher to this string matcher. @@ -235,9 +245,8 @@ QStringMatcher &QStringMatcher::operator=(const QStringMatcher &other) void QStringMatcher::setPattern(const QString &pattern) { q_pattern = pattern; - p.uc = pattern.unicode(); - p.len = pattern.size(); - bm_init_skiptable((const ushort *)pattern.unicode(), pattern.size(), p.q_skiptable, q_cs); + p.sv = q_pattern; + updateSkipTable(); } /*! @@ -253,7 +262,7 @@ QString QStringMatcher::pattern() const { if (!q_pattern.isEmpty()) return q_pattern; - return QString(p.uc, p.len); + return p.sv.toString(); } /*! @@ -266,8 +275,8 @@ void QStringMatcher::setCaseSensitivity(Qt::CaseSensitivity cs) { if (cs == q_cs) return; - bm_init_skiptable((const ushort *)p.uc, p.len, p.q_skiptable, cs); q_cs = cs; + updateSkipTable(); } /*! @@ -316,9 +325,7 @@ qsizetype QStringMatcher::indexIn(QStringView str, qsizetype from) const { if (from < 0) from = 0; - return bm_find((const ushort *)str.data(), str.size(), from, - (const ushort *)p.uc, p.len, - p.q_skiptable, q_cs); + return bm_find(str, from, p.sv, p.q_skiptable, q_cs); } /*! @@ -338,11 +345,10 @@ qsizetype qFindStringBoyerMoore( QStringView needle, Qt::CaseSensitivity cs) { uchar skiptable[256]; - bm_init_skiptable((const ushort *)needle.data(), needle.size(), skiptable, cs); + bm_init_skiptable(needle, skiptable, cs); if (haystackOffset < 0) haystackOffset = 0; - return bm_find((const ushort *)haystack.data(), haystack.size(), haystackOffset, - (const ushort *)needle.data(), needle.size(), skiptable, cs); + return bm_find(haystack, haystackOffset, needle, skiptable, cs); } QT_END_NAMESPACE diff --git a/src/corelib/text/qstringmatcher.h b/src/corelib/text/qstringmatcher.h index 6de4353930..c731efcc97 100644 --- a/src/corelib/text/qstringmatcher.h +++ b/src/corelib/text/qstringmatcher.h @@ -51,6 +51,7 @@ class QStringMatcherPrivate; class Q_CORE_EXPORT QStringMatcher { + void updateSkipTable(); public: QStringMatcher(); explicit QStringMatcher(const QString &pattern, @@ -79,8 +80,7 @@ private: Qt::CaseSensitivity q_cs; struct Data { uchar q_skiptable[256]; - const QChar *uc; - int len; + QStringView sv; }; union { uint q_data[256];