Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Unified Diff: compiled/Filter.cpp

Issue 29333474: Issue 4125 - [emscripten] Convert filter classes to C++ (Closed)
Patch Set: Optimized hash lookup performance a bit Created Feb. 8, 2016, 7:11 p.m.
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
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;
+}

Powered by Google App Engine
This is Rietveld