OLD | NEW |
(Empty) | |
| 1 #include "ActiveFilter.h" |
| 2 #include "StringScanner.h" |
| 3 |
| 4 namespace |
| 5 { |
| 6 const std::u16string ProcessDomain(const std::u16string& docDomain, |
| 7 bool ignoreTrailingDot) |
| 8 { |
| 9 size_t len = docDomain.length(); |
| 10 if (ignoreTrailingDot) |
| 11 { |
| 12 for (; len > 0; --len) |
| 13 { |
| 14 if (docDomain[len - 1] != u'.') |
| 15 break; |
| 16 } |
| 17 } |
| 18 |
| 19 std::u16string domain(docDomain.substr(0, len)); |
| 20 for (size_t i = 0, l = domain.length(); i < l; ++i) |
| 21 { |
| 22 char16_t currChar = domain[i]; |
| 23 // TODO: This needs to work for non-ASCII as well |
| 24 if (currChar >= u'a' && currChar <= u'z') |
| 25 domain[i] = currChar + u'A' - u'a'; |
| 26 } |
| 27 return domain; |
| 28 } |
| 29 |
| 30 const std::u16string to_u16string(unsigned int i) |
| 31 { |
| 32 std::string str(std::to_string(i)); |
| 33 std::u16string result(str.length(), u'\0'); |
| 34 |
| 35 for (size_t i = 0, l = str.length(); i < l; ++i) |
| 36 result[i] = str[i]; |
| 37 return result; |
| 38 } |
| 39 } |
| 40 |
| 41 ActiveFilter::ActiveFilter(const std::u16string& text, bool ignoreTrailingDot) |
| 42 : Filter(text), disabled(false), hitCount(0), lastHit(0), |
| 43 ignoreTrailingDot(ignoreTrailingDot) |
| 44 { |
| 45 } |
| 46 |
| 47 void ActiveFilter::ParseDomains(const std::u16string& str, char16_t separator) |
| 48 { |
| 49 StringScanner scanner(str + separator); |
| 50 size_t start = 0; |
| 51 bool reverse = false; |
| 52 bool hasIncludes = false; |
| 53 while (!scanner.done()) |
| 54 { |
| 55 char16_t currChar = scanner.next(); |
| 56 if (currChar == u'~' && scanner.position() == start) |
| 57 { |
| 58 start++; |
| 59 reverse = true; |
| 60 } |
| 61 else if (currChar == separator) |
| 62 { |
| 63 if (scanner.position() > start) |
| 64 { |
| 65 std::u16string domain( |
| 66 ProcessDomain(str.substr(start, scanner.position() - start), |
| 67 ignoreTrailingDot) |
| 68 ); |
| 69 domains[domain] = !reverse; |
| 70 if (!reverse) |
| 71 hasIncludes = true; |
| 72 } |
| 73 start = scanner.position() + 1; |
| 74 reverse = false; |
| 75 } |
| 76 } |
| 77 domains[u""] = !hasIncludes; |
| 78 } |
| 79 |
| 80 |
| 81 bool ActiveFilter::IsActiveOnDomain(const std::u16string& docDomain, |
| 82 const std::u16string& sitekey) |
| 83 { |
| 84 if (!sitekeys.empty() && sitekeys.find(sitekey) == sitekeys.end()) |
| 85 return false; |
| 86 |
| 87 // If no domains are set the rule matches everywhere |
| 88 if (domains.empty()) |
| 89 return true; |
| 90 |
| 91 // If the document has no host name, match only if the filter isn't restricted |
| 92 // to specific domains |
| 93 if (docDomain.empty()) |
| 94 return domains[u""]; |
| 95 |
| 96 std::u16string domain(ProcessDomain(docDomain, ignoreTrailingDot)); |
| 97 while (true) |
| 98 { |
| 99 auto it = domains.find(domain); |
| 100 if (it != domains.end()) |
| 101 return it->second; |
| 102 |
| 103 size_t nextDot = domain.find(u'.'); |
| 104 if (nextDot == domain.npos) |
| 105 break; |
| 106 domain = domain.substr(nextDot + 1); |
| 107 } |
| 108 return domains[u""]; |
| 109 } |
| 110 |
| 111 bool ActiveFilter::IsActiveOnlyOnDomain(const std::u16string& docDomain) |
| 112 { |
| 113 if (domains.empty() || docDomain.empty() || domains[u""]) |
| 114 return false; |
| 115 |
| 116 std::u16string domain(ProcessDomain(docDomain, ignoreTrailingDot)); |
| 117 for (auto it = domains.begin(); it != domains.end(); ++it) |
| 118 { |
| 119 if (!it->second || it->first == domain) |
| 120 continue; |
| 121 |
| 122 size_t len1 = it->first.length(); |
| 123 size_t len2 = domain.length(); |
| 124 if (len1 > len2 && it->first.rfind(u"." + domain) == len1 - len2 - 1) |
| 125 continue; |
| 126 |
| 127 return false; |
| 128 } |
| 129 return true; |
| 130 } |
| 131 |
| 132 bool ActiveFilter::IsGeneric() |
| 133 { |
| 134 return (sitekeys.empty() && (domains.empty() || domains[u""])); |
| 135 } |
| 136 |
| 137 const std::u16string ActiveFilter::Serialize() |
| 138 { |
| 139 std::u16string result(Filter::Serialize()); |
| 140 if (disabled) |
| 141 result += u"disabled=true\n"; |
| 142 if (hitCount) |
| 143 result += u"hitCount=" + to_u16string(hitCount) + u"\n"; |
| 144 if (lastHit) |
| 145 result += u"lastHit=" + to_u16string(lastHit) + u"\n"; |
| 146 return result; |
| 147 } |
OLD | NEW |