QStringMatcher: port internals to QStringView and char16_t

Change-Id: If540b094d003ad373d3c581e1de8c526ad4c7d73
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
This commit is contained in:
Marc Mutz 2020-05-13 21:07:31 +02:00
parent 57037145f5
commit 7a3a9b8eb5
2 changed files with 30 additions and 24 deletions

View File

@ -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

View File

@ -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];