/* * 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://library.iserlohn-fortress.net/aqua/smolbote.git * * SPDX-License-Identifier: GPL-3.0 */ #ifndef SMOLBOTE_ADBLOCK_RULE_H #define SMOLBOTE_ADBLOCK_RULE_H #include "options.h" #include #include #include #include namespace AdblockPlus { class Rule { public: virtual ~Rule() = default; virtual bool hasMatch(const QStringRef &) const = 0; bool shouldRedirect() const { return options.redirect; } bool shouldBlock() const { return !options.exception; } protected: Rule(const Options &opt) : options(opt) { } const Options options; }; class MatcherRule : public Rule { public: enum MatchPosition { UrlStartsWith, UrlEndsWith, UrlContains, UrlEquals }; MatcherRule(const QString &pattern, const Options &opt, const MatchPosition pos = UrlContains) : Rule(opt) , position(pos) , matcher(pattern, opt.matchcase ? Qt::CaseSensitive : Qt::CaseInsensitive) , patternLength(pattern.length()) { } explicit MatcherRule(const MatcherRule &) = delete; MatcherRule &operator=(const MatcherRule &) = delete; explicit MatcherRule(MatcherRule &&) = delete; MatcherRule &operator=(MatcherRule &&) = delete; ~MatcherRule() = default; bool hasMatch(const QStringRef &url) const override { const auto index = matcher.indexIn(url); switch(position) { case UrlStartsWith: return (index == 0); case UrlEndsWith: return (index == url.length() - patternLength); case UrlContains: return (index != -1); case UrlEquals: return (index == 0 && patternLength == url.length()); } } private: const MatchPosition position; const QStringMatcher matcher; const int patternLength; }; class RegexRule : public Rule { public: RegexRule(const QString &rule, const Options &opt) : Rule(opt) , regex(rule) { if(!opt.matchcase) { regex.setPatternOptions(QRegularExpression::CaseInsensitiveOption); } } explicit RegexRule(const RegexRule &) = delete; RegexRule &operator=(const RegexRule &) = delete; explicit RegexRule(RegexRule &&) = delete; RegexRule &operator=(RegexRule &&) = delete; ~RegexRule() = default; bool hasMatch(const QStringRef &url) const override { const auto match = regex.match(url); return match.hasMatch(); } private: QRegularExpression regex; }; } // namespace AdblockPlus #endif // SMOLBOTE_ADBLOCK_RULE_H