diff options
author | Aqua-sama <aqua@iserlohn-fortress.net> | 2019-01-09 19:38:58 +0100 |
---|---|---|
committer | Aqua-sama <aqua@iserlohn-fortress.net> | 2019-01-09 19:38:58 +0100 |
commit | 3d2ae07c455c0e423c64f19e445518427a5684fa (patch) | |
tree | 58f6b47c3db33658a6f2e605fd021f08d1fa9964 /lib/urlfilter/matcher.h | |
parent | Add assorted unfished doc files to repo (diff) | |
download | smolbote-3d2ae07c455c0e423c64f19e445518427a5684fa.tar.xz |
Rewrite lib/urlfilter
- Make HostList and AdBlockList implementations independent from each
other
- Move urlfilter tests to lib/urlfilter
Diffstat (limited to 'lib/urlfilter/matcher.h')
-rw-r--r-- | lib/urlfilter/matcher.h | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/lib/urlfilter/matcher.h b/lib/urlfilter/matcher.h new file mode 100644 index 0000000..6696958 --- /dev/null +++ b/lib/urlfilter/matcher.h @@ -0,0 +1,109 @@ +/* + * This file is part of smolbote. It's copyrighted by the contributors recorded + * in the version control history of the file, available from its original + * location: https://neueland.iserlohn-fortress.net/gitea/aqua/smolbote + * + * SPDX-License-Identifier: GPL-3.0 + */ + +#ifndef SMOLBOTE_URLFILTER_MATCHER +#define SMOLBOTE_URLFILTER_MATCHER + +#include <QUrl> +#include <QString> +#include <utility> +#include <QRegularExpression> +#include <QStringMatcher> +#include <QWebEngineUrlRequestInfo> + +/** An interface class so we can use templated ContentsMatcher interchangeably + */ +class Matcher +{ +public: + virtual ~Matcher() = default; + + virtual void setCaseSensitive(bool matchCase) = 0; + virtual bool hasMatch(const QString &where) const = 0; +}; + +template <typename T> +class ContentsMatcher : public Matcher +{ +public: + ContentsMatcher(const QString &pattern, UrlFilter::MatchType type) + : patternLength(pattern.length()) + , matchType(type) + { + if constexpr(std::is_same_v<T, QRegularExpression>) { + matcher.setPatternOptions(matcher.patternOptions() | QRegularExpression::CaseInsensitiveOption); + matcher.setPattern(pattern); + } else if constexpr(std::is_same_v<T, QStringMatcher>) { + matcher.setCaseSensitivity(Qt::CaseInsensitive); + matcher.setPattern(pattern); + } else if constexpr(std::is_same_v<T, QString>) { + matcher = QUrl::fromUserInput(pattern).host(); + } + } + ~ContentsMatcher() = default; + + void setCaseSensitive(bool matchCase) override + { + if constexpr(std::is_same_v<T, QRegularExpression>) { + auto options = matcher.patternOptions(); + options.setFlag(QRegularExpression::CaseInsensitiveOption, !matchCase); + matcher.setPatternOptions(options); + + } else if constexpr(std::is_same_v<T, QStringMatcher>) { + matcher.setCaseSensitivity(matchCase ? Qt::CaseSensitive : Qt::CaseInsensitive); + } + } + + bool hasMatch(const QString &where) const override + { + if constexpr(std::is_same_v<T, QStringMatcher>) { + switch (matchType) { + case UrlFilter::InvalidMatch: + case UrlFilter::RegularExpressionMatch: + case UrlFilter::DomainMatch: + qWarning("ContentsMatcher is a String Matcher, but not doing string matching!"); + return false; + + case UrlFilter::StringContains: + return (matcher.indexIn(where) != -1); + + case UrlFilter::StringStartsWith: + return (matcher.indexIn(where) == 0); + + case UrlFilter::StringEndsWith: + return (matcher.indexIn(where) == where.length() - patternLength); + + case UrlFilter::StringEquals: + return (matcher.indexIn(where) == 0) && (patternLength == where.length()); + } + + } else if constexpr(std::is_same_v<T, QRegularExpression>) { + if(matchType != UrlFilter::RegularExpressionMatch) + qWarning("ContentsMatcher is a regular expression, but not doing a regular expression match!"); + return matcher.match(where).hasMatch(); + } else if constexpr(std::is_same_v<T, QString>) { + // TODO: fix + if(matchType == UrlFilter::DomainMatch) { +// qDebug("matching %s", qUtf8Printable(QUrl(where).host())); + return QUrl(where).host().endsWith(matcher); + } else + return matcher == where; + } + + qWarning("Matcher has no backend, returning false"); + return false; + } + +private: + const int patternLength; + const UrlFilter::MatchType matchType; + T matcher; +}; + +#endif // SMOLBOTE_URLFILTER_MATCHER + |