Index: net/base/swr_histogram_domains/swr_histogram_domains.cc |
diff --git a/net/base/swr_histogram_domains/swr_histogram_domains.cc b/net/base/swr_histogram_domains/swr_histogram_domains.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..995f00d9d69a29714f288b7beda690ef7979684d |
--- /dev/null |
+++ b/net/base/swr_histogram_domains/swr_histogram_domains.cc |
@@ -0,0 +1,79 @@ |
+// Copyright 2015 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "net/base/swr_histogram_domains/swr_histogram_domains.h" |
+ |
+#include <stddef.h> |
+ |
+#include "base/logging.h" |
+#include "net/base/dafsa/lookup_string.h" |
+ |
+namespace net { |
+ |
+namespace swr_histogram_domains { |
+ |
+namespace { |
+ |
+#include "net/base/swr_histogram_domains/swr_histogram_domains-inc.cc" |
+ |
+// The maximum number of dots in any domain in the list. This is used to ignore |
+// parts of the host name that are irrelevant, and so must be correct. |
+const int kMaxDots = 2; |
+ |
+// The minimum number of dots in a host necessary for it to be considered a |
+// match. |
+const int kMinDots = 1; |
+ |
+const size_t npos = base::StringPiece::npos; |
+ |
+bool LookupTail(const base::StringPiece& host, size_t pos) { |
+ DCHECK_LT(pos, host.size()); |
+ return LookupString(kDafsa, sizeof(kDafsa), host.data() + pos, |
+ host.size() - pos) == 0; |
+} |
+ |
+bool LookupTrimmedHost(const base::StringPiece& trimmed) { |
+ // |trimmed| contains at least one non-dot. The maximum number of dots we want |
+ // to look for is kMaxInterestingDots; any dots before that will not affect |
+ // the outcome of the match. |
+ const int kMaxInterestingDots = kMaxDots + 1; |
+ |
+ // Scan |trimmed| from the right for up to kMaxInterestingDots dots, checking |
+ // for a domain match at each position. |
+ int found_dots = 0; |
+ size_t pos = npos; |
+ while (found_dots < kMaxInterestingDots) { |
+ pos = trimmed.find_last_of('.', pos); |
+ if (pos == npos) |
+ break; |
+ ++found_dots; |
+ if (found_dots > kMinDots && LookupTail(trimmed, pos + 1)) |
+ return true; |
+ if (pos == 0) |
+ return false; |
+ --pos; |
+ } |
+ |
+ if (found_dots >= kMinDots && found_dots <= kMaxDots) { |
+ // We might have an exact match. |
+ return LookupTail(trimmed, 0); |
+ } |
+ |
+ return false; |
+} |
+ |
+} // namespace |
+ |
+bool IsHostInSWRHistogramDomain(const base::StringPiece& host) { |
+ // Ignore trailing dots. |
+ size_t last_interesting_pos = host.find_last_not_of('.'); |
+ if (last_interesting_pos == npos) |
+ return false; |
+ |
+ return LookupTrimmedHost(host.substr(0, last_interesting_pos + 1)); |
+} |
+ |
+} // namespace swr_histogram_domains |
+ |
+} // namespace net |