| Index: compiled/ElemHideBase.cpp |
| =================================================================== |
| new file mode 100644 |
| --- /dev/null |
| +++ b/compiled/ElemHideBase.cpp |
| @@ -0,0 +1,109 @@ |
| +#include "ElemHideBase.h" |
| +#include "ElemHideFilter.h" |
| +#include "ElemHideException.h" |
| + |
| +namespace |
| +{ |
| + class Scanner |
| + { |
| + private: |
| + const std::u16string& str; |
| + size_t pos; |
| + size_t end; |
| + public: |
| + Scanner(const std::u16string& str) : str(str), pos(0), end(str.length()) {} |
| + |
| + bool done() |
| + { |
| + return pos >= end; |
| + } |
| + |
| + size_t position() |
| + { |
| + return pos - 1; |
| + } |
| + |
| + char16_t next() |
| + { |
| + return done() ? u'\0' : str[pos++]; |
| + } |
| + }; |
| +} |
| + |
| +ElemHideBase::ElemHideBase(const std::u16string& text, size_t domainsEnd, |
| + size_t selectorStart) |
| + : ActiveFilter(text) |
| +{ |
| +} |
| + |
| +Filter::Type ElemHideBase::Parse(const std::u16string& text, size_t* domainsEnd, |
| + size_t* selectorStart) |
| +{ |
| + Scanner scanner(text); |
| + |
| + // Domains part |
| + loop: |
| + while (!scanner.done()) |
| + { |
| + char16_t next = scanner.next(); |
| + if (next == u'#') |
| + { |
| + *domainsEnd = scanner.position(); |
| + break; |
| + } |
| + |
| + switch (next) |
| + { |
| + case u'/': |
| + case u'*': |
| + case u'|': |
| + case u'@': |
| + case u'"': |
| + case u'!': |
| + return Type::UNKNOWN; |
| + } |
| + } |
| + |
| + bool exception = false; |
| + char16_t next = scanner.next(); |
| + if (next == u'@') |
| + { |
| + exception = true; |
| + next = scanner.next(); |
| + } |
| + |
| + if (next != u'#') |
| + return Type::UNKNOWN; |
| + |
| + // Selector part |
| + |
| + // Selector shouldn't be empty |
| + if (scanner.done()) |
| + return Type::UNKNOWN; |
| + |
| + *selectorStart = scanner.position() + 1; |
| + while (!scanner.done()) |
| + { |
| + switch (scanner.next()) |
| + { |
| + case u'{': |
| + case u'}': |
| + return Type::UNKNOWN; |
| + } |
| + } |
| + |
| + return exception ? Type::ELEMHIDEEXCEPTION : Type::ELEMHIDE; |
| +} |
| + |
| +ElemHideBase* ElemHideBase::Create(const std::u16string& text) |
| +{ |
| + size_t domainsEnd; |
| + size_t selectorStart; |
| + Type type = Parse(text, &domainsEnd, &selectorStart); |
| + if (type == Type::UNKNOWN) |
| + return nullptr; |
| + else if (type == Type::ELEMHIDEEXCEPTION) |
| + return new ElemHideException(text, domainsEnd, selectorStart); |
| + else |
| + return new ElemHideFilter(text, domainsEnd, selectorStart); |
| +} |