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

Unified Diff: compiled/ActiveFilter.cpp

Issue 29333474: Issue 4125 - [emscripten] Convert filter classes to C++ (Closed)
Patch Set: Fixed annotation for hash buffers Created Jan. 28, 2016, 5:07 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
« no previous file with comments | « compiled/ActiveFilter.h ('k') | compiled/CSSPropertyFilter.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: compiled/ActiveFilter.cpp
===================================================================
new file mode 100644
--- /dev/null
+++ b/compiled/ActiveFilter.cpp
@@ -0,0 +1,183 @@
+#include <cstdio>
+
+#include "ActiveFilter.h"
+#include "StringScanner.h"
+
+namespace
+{
+ void ProcessDomain(String& docDomain, bool ignoreTrailingDot)
+ {
+ String::size_type len = docDomain.length();
+ if (ignoreTrailingDot)
+ {
+ for (; len > 0; --len)
+ {
+ if (docDomain[len - 1] != u'.')
+ break;
+ }
+ }
+
+ for (String::size_type i = 0; i < len; ++i)
+ {
+ String::value_type currChar = docDomain[i];
+ // TODO: This needs to work for non-ASCII as well
+ if (currChar >= u'A' && currChar <= u'Z')
+ docDomain[i] = currChar + u'a' - u'A';
+ }
+
+ docDomain.reset(docDomain, 0, len);
+ }
+
+ String to_string(unsigned int i)
+ {
+ char buffer[11];
+ int len = sprintf(buffer, "%u", i);
+ return std::move(String(buffer, len));
+ }
+}
+
+ActiveFilter::ActiveFilter(const String& text, bool ignoreTrailingDot)
+ : Filter(text), mDisabled(false), mHitCount(0), mLastHit(0),
+ mIgnoreTrailingDot(ignoreTrailingDot)
+{
+}
+
+void ActiveFilter::ParseDomains(const String& str, String::value_type separator)
+{
+ DomainMap::size_type count = 2;
+ for (String::size_type i = 0; i < str.length(); i++)
+ if (str[i] == separator)
+ count++;
+
+ mDomains.reset(new DomainMap(count));
+ annotate_address(mDomains.get(), "DomainMap");
+
+ StringScanner scanner(str, separator);
+ String::size_type start = 0;
+ bool reverse = false;
+ bool hasIncludes = false;
+ bool done = false;
+ while (!done)
+ {
+ done = scanner.done();
+ String::value_type currChar = scanner.next();
+ if (currChar == u'~' && scanner.position() == start)
+ {
+ start++;
+ reverse = true;
+ }
+ else if (currChar == separator)
+ {
+ if (scanner.position() > start)
+ {
+ String domain(str, start, scanner.position() - start);
+ ProcessDomain(domain, mIgnoreTrailingDot);
+
+ enter_context("Adding to ActiveFilter.mDomains");
+ (*mDomains)[domain] = !reverse;
+ exit_context();
+
+ if (!reverse)
+ hasIncludes = true;
+ }
+ start = scanner.position() + 1;
+ reverse = false;
+ }
+ }
+ enter_context("Adding to ActiveFilter.mDomains");
+ (*mDomains)[u""_str] = !hasIncludes;
+ exit_context();
+}
+
+void ActiveFilter::AddSitekey(const String& sitekey)
+{
+ if (!mSitekeys)
+ {
+ mSitekeys.reset(new SitekeySet());
+ annotate_address(mSitekeys.get(), "SitekeySet");
+ }
+
+ enter_context("Adding to ActiveFilter.mSitekeys");
+ mSitekeys->insert(sitekey);
+ exit_context();
+}
+
+bool ActiveFilter::IsActiveOnDomain(String& docDomain, const String& sitekey)
+{
+ if (mSitekeys && mSitekeys->find(sitekey) == mSitekeys->end())
+ return false;
+
+ // If no domains are set the rule matches everywhere
+ if (!mDomains)
+ return true;
+
+ // If the document has no host name, match only if the filter isn't restricted
+ // to specific domains
+ if (docDomain.empty())
+ return (*mDomains)[u""_str];
+
+ ProcessDomain(docDomain, mIgnoreTrailingDot);
+ while (true)
+ {
+ auto it = mDomains->find(docDomain);
+ if (it != mDomains->end())
+ return it->second;
+
+ String::size_type nextDot = docDomain.find(u'.');
+ if (nextDot == docDomain.npos)
+ break;
+ docDomain.reset(docDomain, nextDot + 1);
+ }
+ return (*mDomains)[u""_str];
+}
+
+bool ActiveFilter::IsActiveOnlyOnDomain(String& docDomain)
+{
+ if (!mDomains || docDomain.empty() || (*mDomains)[u""_str])
+ return false;
+
+ ProcessDomain(docDomain, mIgnoreTrailingDot);
+ for (auto it = mDomains->begin(); it != mDomains->end(); ++it)
+ {
+ if (!it->second || it->first.equals(docDomain))
+ continue;
+
+ size_t len1 = it->first.length();
+ size_t len2 = docDomain.length();
+ if (len1 > len2 &&
+ String(it->first, len1 - len2).equals(docDomain) &&
+ it->first[len1 - len2 - 1] == u'.')
+ {
+ continue;
+ }
+
+ return false;
+ }
+ return true;
+}
+
+bool ActiveFilter::IsGeneric()
+{
+ return !mSitekeys && (!mDomains || (*mDomains)[u""_str]);
+}
+
+String ActiveFilter::Serialize()
+{
+ /* TODO this is very inefficient */
+ String result(Filter::Serialize());
+ if (mDisabled)
+ result.append(u"disabled=true\n"_str);
+ if (mHitCount)
+ {
+ result.append(u"hitCount="_str);
+ result.append(to_string(mHitCount));
+ result.append(u'\n');
+ }
+ if (mLastHit)
+ {
+ result.append(u"lastHit="_str);
+ result.append(to_string(mLastHit));
+ result.append(u'\n');
+ }
+ return std::move(result);
+}
« no previous file with comments | « compiled/ActiveFilter.h ('k') | compiled/CSSPropertyFilter.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld