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 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))); int l = int(qMin(len, qsizetype(255)));
memset(skiptable, l, 256 * sizeof(uchar)); memset(skiptable, l, 256 * sizeof(uchar));
uc += len - l; uc += len - l;
@ -53,7 +55,7 @@ static void bm_init_skiptable(const ushort *uc, qsizetype len, uchar *skiptable,
++uc; ++uc;
} }
} else { } else {
const ushort *start = uc; const char16_t *start = uc;
while (l--) { while (l--) {
skiptable[foldCase(uc, start) & 0xff] = l; skiptable[foldCase(uc, start) & 0xff] = l;
++uc; ++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 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) if (pl == 0)
return index > l ? -1 : index; return index > l ? -1 : index;
const qsizetype pl_minus_one = pl - 1; const qsizetype pl_minus_one = pl - 1;
const ushort *current = uc + index + pl_minus_one; const char16_t *current = uc + index + pl_minus_one;
const ushort *end = uc + l; const char16_t *end = uc + l;
if (cs == Qt::CaseSensitive) { if (cs == Qt::CaseSensitive) {
while (current < end) { while (current < end) {
qsizetype skip = skiptable[*current & 0xff]; 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 return -1; // not found
} }
void QStringMatcher::updateSkipTable()
{
bm_init_skiptable(p.sv, p.q_skiptable, q_cs);
}
/*! /*!
\class QStringMatcher \class QStringMatcher
\inmodule QtCore \inmodule QtCore
@ -163,9 +175,8 @@ QStringMatcher::QStringMatcher()
QStringMatcher::QStringMatcher(const QString &pattern, Qt::CaseSensitivity cs) QStringMatcher::QStringMatcher(const QString &pattern, Qt::CaseSensitivity cs)
: d_ptr(nullptr), q_pattern(pattern), q_cs(cs) : d_ptr(nullptr), q_pattern(pattern), q_cs(cs)
{ {
p.uc = pattern.unicode(); p.sv = q_pattern;
p.len = pattern.size(); updateSkipTable();
bm_init_skiptable((const ushort *)p.uc, p.len, p.q_skiptable, cs);
} }
/*! /*!
@ -192,9 +203,8 @@ QStringMatcher::QStringMatcher(const QChar *uc, int len, Qt::CaseSensitivity cs)
QStringMatcher::QStringMatcher(QStringView str, Qt::CaseSensitivity cs) QStringMatcher::QStringMatcher(QStringView str, Qt::CaseSensitivity cs)
: d_ptr(nullptr), q_cs(cs) : d_ptr(nullptr), q_cs(cs)
{ {
p.uc = str.data(); p.sv = str;
p.len = int(str.size()); updateSkipTable();
bm_init_skiptable((const ushort *)p.uc, p.len, p.q_skiptable, cs);
} }
/*! /*!
Copies the \a other string matcher to this string matcher. 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) void QStringMatcher::setPattern(const QString &pattern)
{ {
q_pattern = pattern; q_pattern = pattern;
p.uc = pattern.unicode(); p.sv = q_pattern;
p.len = pattern.size(); updateSkipTable();
bm_init_skiptable((const ushort *)pattern.unicode(), pattern.size(), p.q_skiptable, q_cs);
} }
/*! /*!
@ -253,7 +262,7 @@ QString QStringMatcher::pattern() const
{ {
if (!q_pattern.isEmpty()) if (!q_pattern.isEmpty())
return q_pattern; 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) if (cs == q_cs)
return; return;
bm_init_skiptable((const ushort *)p.uc, p.len, p.q_skiptable, cs);
q_cs = cs; q_cs = cs;
updateSkipTable();
} }
/*! /*!
@ -316,9 +325,7 @@ qsizetype QStringMatcher::indexIn(QStringView str, qsizetype from) const
{ {
if (from < 0) if (from < 0)
from = 0; from = 0;
return bm_find((const ushort *)str.data(), str.size(), from, return bm_find(str, from, p.sv, p.q_skiptable, q_cs);
(const ushort *)p.uc, p.len,
p.q_skiptable, q_cs);
} }
/*! /*!
@ -338,11 +345,10 @@ qsizetype qFindStringBoyerMoore(
QStringView needle, Qt::CaseSensitivity cs) QStringView needle, Qt::CaseSensitivity cs)
{ {
uchar skiptable[256]; uchar skiptable[256];
bm_init_skiptable((const ushort *)needle.data(), needle.size(), skiptable, cs); bm_init_skiptable(needle, skiptable, cs);
if (haystackOffset < 0) if (haystackOffset < 0)
haystackOffset = 0; haystackOffset = 0;
return bm_find((const ushort *)haystack.data(), haystack.size(), haystackOffset, return bm_find(haystack, haystackOffset, needle, skiptable, cs);
(const ushort *)needle.data(), needle.size(), skiptable, cs);
} }
QT_END_NAMESPACE QT_END_NAMESPACE

View File

@ -51,6 +51,7 @@ class QStringMatcherPrivate;
class Q_CORE_EXPORT QStringMatcher class Q_CORE_EXPORT QStringMatcher
{ {
void updateSkipTable();
public: public:
QStringMatcher(); QStringMatcher();
explicit QStringMatcher(const QString &pattern, explicit QStringMatcher(const QString &pattern,
@ -79,8 +80,7 @@ private:
Qt::CaseSensitivity q_cs; Qt::CaseSensitivity q_cs;
struct Data { struct Data {
uchar q_skiptable[256]; uchar q_skiptable[256];
const QChar *uc; QStringView sv;
int len;
}; };
union { union {
uint q_data[256]; uint q_data[256];