Index: compiled/Filter.cpp |
=================================================================== |
new file mode 100644 |
--- /dev/null |
+++ b/compiled/Filter.cpp |
@@ -0,0 +1,122 @@ |
+#include "Filter.h" |
+#include "CommentFilter.h" |
+#include "RegExpFilter.h" |
+#include "ElemHideFilter.h" |
+#include "ElemHideException.h" |
+#include "StringMap.h" |
+ |
+namespace |
+{ |
+ /* TODO: This is a memory leak. Store raw/weak pointers as soon as we are |
+ actually using the filters somewhere. */ |
+ StringMap<FilterPtr> 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(); |
+} |
+ |
+String Filter::Serialize() |
+{ |
+ String result(u"[Filter]\ntext="_str); |
+ result.append(mText); |
+ result.append(u'\n'); |
+ return std::move(result); |
+} |
+ |
+FilterPtr Filter::FromText(const String& text) |
+{ |
+ auto it = knownFilters.find(text); |
+ if (it != knownFilters.end()) |
+ return it->second; |
+ |
+ FilterPtr filter = FilterPtr(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; |
+ exit_context(); |
+ 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; |
+} |