| Index: compiled/Filter.cpp |
| =================================================================== |
| new file mode 100644 |
| --- /dev/null |
| +++ b/compiled/Filter.cpp |
| @@ -0,0 +1,130 @@ |
| +#include "Filter.h" |
| +#include "CommentFilter.h" |
| +#include "RegExpFilter.h" |
| +#include "ElemHideFilter.h" |
| +#include "ElemHideException.h" |
| +#include "StringMap.h" |
| + |
| +namespace |
| +{ |
| + StringMap<Filter*> knownFilters(8192); |
| + |
| + void trim_spaces(String& str) |
| + { |
| + String::size_type pos; |
| + |
| + // Remove leading whitespace |
| + for (pos = 0; pos < str.length(); ++pos) |
| + if (str[pos] != u' ') |
| + break; |
| + str.reset(str, pos); |
| + |
| + // Remove trailing whitespace |
| + for (pos = str.length(); pos > 0; --pos) |
| + if (str[pos - 1] != u' ') |
| + break; |
| + str.reset(str, 0, pos); |
| + } |
| + |
| + void remove_spaces(String& str) |
| + { |
| + String::size_type pos; |
| + |
| + for (String::size_type i = 0; i < str.length(); ++i) |
| + if (str[i] != u' ') |
| + str[pos++] = str[i]; |
| + |
| + str.reset(str, 0, pos); |
| + } |
| +} |
| + |
| +Filter::Filter(const String& text) |
| + : mText(text) |
| +{ |
| + annotate_address(this, "Filter"); |
| + mText.ensure_own_buffer(); |
| +} |
| + |
| +Filter::~Filter() |
| +{ |
| + // TODO: This should be removing from knownFilters |
| +} |
| + |
| +String Filter::Serialize() const |
| +{ |
| + String result(u"[Filter]\ntext="_str); |
| + result.append(mText); |
| + result.append(u'\n'); |
| + return std::move(result); |
| +} |
| + |
| +Filter* Filter::FromText(const String& text) |
| +{ |
| + auto it = knownFilters.find(text); |
| + if (it != knownFilters.end()) |
| + return it->second; |
| + |
| + FilterPtr filter(CommentFilter::Create(text)); |
| + if (!filter) |
| + filter.reset(ElemHideBase::Create(text)); |
| + if (!filter) |
| + filter.reset(RegExpFilter::Create(text)); |
| + |
| + enter_context("Adding to known filters"); |
| + knownFilters[filter->mText] = filter.get(); |
| + exit_context(); |
| + |
| + // TODO: We intentionally leak the filter here - currently it won't be used |
| + // for anything and would be deleted immediately. |
| + filter->AddRef(); |
| + |
| + return filter; |
| +} |
| + |
| +String Filter::Normalize(String& text) |
| +{ |
| + // Removing special characters like line breaks |
| + String::size_type delta = 0; |
| + for (String::size_type i = 0; i < text.length(); ++i) |
| + { |
| + if (text[i] >= u' ') |
| + text[i - delta] = text[i]; |
| + else |
| + ++delta; |
| + } |
| + text.reset(text, 0, text.length() - delta); |
| + |
| + trim_spaces(text); |
| + |
| + { |
| + String::size_type domainsEnd; |
| + String::size_type selectorStart; |
| + Filter::Type type = ElemHideBase::Parse(text, &domainsEnd, &selectorStart); |
| + if (type != Filter::Type::UNKNOWN) |
| + { |
| + String domains(text, 0, domainsEnd); |
| + String selector(text, selectorStart); |
| + remove_spaces(domains); |
| + trim_spaces(selector); |
| + |
| + String::size_type domainsDelta = domainsEnd - domains.length(); |
| + String::size_type selectorDelta = text.length() - selectorStart - |
| + selector.length(); |
| + |
| + if (domainsDelta) |
| + for (String::size_type i = domainsEnd; i < selectorStart; ++i) |
| + text[i - domainsDelta] = text[i]; |
| + |
| + if (domainsDelta + selectorDelta) |
| + for (String::size_type i = 0; i < selector.length(); ++i) |
| + text[selectorStart - domainsDelta + i] = selector[i]; |
| + |
| + text.reset(text, 0, text.length() - domainsDelta - selectorDelta); |
| + return text; |
| + } |
| + } |
| + |
| + if (CommentFilter::Parse(text) == Filter::Type::UNKNOWN) |
| + remove_spaces(text); |
| + return text; |
| +} |