Index: compiled/Filter.cpp |
=================================================================== |
new file mode 100644 |
--- /dev/null |
+++ b/compiled/Filter.cpp |
@@ -0,0 +1,150 @@ |
+#include "Filter.h" |
+#include "CommentFilter.h" |
+#include "InvalidFilter.h" |
+#include "RegExpFilter.h" |
+#include "WhitelistFilter.h" |
+#include "ElemHideBase.h" |
+#include "ElemHideFilter.h" |
+#include "ElemHideException.h" |
+#include "CSSPropertyFilter.h" |
+#include "StringMap.h" |
+ |
+namespace |
+{ |
+ StringMap<Filter*> knownFilters(8192); |
+ |
+ void NormalizeWhitespace(DependentString& text) |
+ { |
+ String::size_type start = 0; |
+ String::size_type end = text.length(); |
+ |
+ // Remove leading spaces and special characters like line breaks |
+ for (; start < end; start++) |
+ if (text[start] > ' ') |
+ break; |
+ |
+ // Now look for invalid characters inside the string |
+ String::size_type pos; |
+ for (pos = start; pos < end; pos++) |
+ if (text[pos] < ' ') |
+ break; |
+ |
+ if (pos < end) |
+ { |
+ // Found invalid characters, copy all the valid characters while skipping |
+ // the invalid ones. |
+ String::size_type delta = 1; |
+ for (pos = pos + 1; pos < end; pos++) |
+ { |
+ if (text[pos] < ' ') |
+ delta++; |
+ else |
+ text[pos - delta] = text[pos]; |
+ } |
+ end -= delta; |
+ } |
+ |
+ // Remove trailing spaces |
+ for (; end > 0; end--) |
+ if (text[end - 1] != ' ') |
+ break; |
+ |
+ // Set new string boundaries |
+ text.reset(text, start, end - start); |
+ } |
+} |
+ |
+Filter::Filter(const String& text) |
+ : ref_counted(), mText(text) |
sergei
2016/02/17 12:54:37
`ref_counted()` is not necessary here.
Wladimir Palant
2016/02/18 16:06:41
I preferred to spell this out explicitly neverthel
|
+{ |
+ annotate_address(this, "Filter"); |
+} |
+ |
+Filter::~Filter() |
+{ |
+ // TODO: This should be removing from knownFilters |
+} |
+ |
+OwnedString Filter::Serialize() const |
+{ |
+ OwnedString result(u"[Filter]\ntext="_str); |
+ result.append(mText); |
+ result.append(u'\n'); |
+ return std::move(result); |
sergei
2016/02/17 12:54:36
std::move is not necessary here.
BTW, in C++, here
Wladimir Palant
2016/02/18 16:06:42
Done.
|
+} |
+ |
+Filter* Filter::FromText(DependentString& text) |
+{ |
+ NormalizeWhitespace(text); |
sergei
2016/02/17 12:54:33
For me personally, the approach here is really con
Wladimir Palant
2016/02/18 16:06:43
I've been through multiple iterations here, and th
sergei
2016/02/22 12:45:36
Clear.
BTW, can we avoid copying of strings here
Wladimir Palant
2016/02/23 12:37:20
Reading that file will eventually move into C++ so
sergei
2016/02/23 15:07:24
Acknowledged.
|
+ if (text.empty()) |
+ return nullptr; |
+ |
+ // Parsing also normalizes the filter text, so it has to be done before the |
+ // lookup in knownFilters. |
+ union |
+ { |
+ RegExpFilterData regexp; |
+ ElemHideData elemhide; |
+ } data; |
+ OwnedString error; |
+ |
+ Filter::Type type = CommentFilter::Parse(text); |
+ if (type == Filter::Type::UNKNOWN) |
+ type = ElemHideBase::Parse(text, data.elemhide); |
+ if (type == Filter::Type::UNKNOWN) |
+ type = RegExpFilter::Parse(text, error, data.regexp); |
+ |
+ FilterPtr filter(GetKnownFilter(text)); |
+ if (filter) |
+ return filter; |
+ |
+ switch (type) |
+ { |
+ case Filter::Type::COMMENT: |
+ filter = new CommentFilter(text); |
+ break; |
+ case Filter::Type::INVALID: |
+ filter = new InvalidFilter(text, error); |
+ break; |
+ case Filter::Type::BLOCKING: |
+ filter = new RegExpFilter(text, data.regexp); |
+ break; |
+ case Filter::Type::WHITELIST: |
+ filter = new WhitelistFilter(text, data.regexp); |
+ break; |
+ case Filter::Type::ELEMHIDE: |
+ filter = new ElemHideFilter(text, data.elemhide); |
+ break; |
+ case Filter::Type::ELEMHIDEEXCEPTION: |
+ filter = new ElemHideException(text, data.elemhide); |
+ break; |
+ case Filter::Type::CSSPROPERTY: |
+ filter = new CSSPropertyFilter(text, data.elemhide); |
+ if (reinterpret_cast<CSSPropertyFilter*>(filter.get())->IsGeneric()) |
sergei
2016/02/17 12:54:34
it's better to use `static_cast` here.
Wladimir Palant
2016/02/18 16:06:44
Done.
|
+ filter = new InvalidFilter(text, |
+ u"No active domain specified for CSS property filter"_str); |
+ break; |
+ default: |
+ // This should never happen but just in case |
+ return nullptr; |
+ } |
+ |
+ 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; |
+} |
+ |
+Filter* Filter::GetKnownFilter(const String& text) |
+{ |
+ auto it = knownFilters.find(text); |
+ if (it != knownFilters.end()) |
+ return it->second; |
+ else |
+ return nullptr; |
+} |