]> granicus.if.org Git - pdns/commitdiff
Add SimpleMatch matcher
authorAki Tuomi <cmouse@desteem.org>
Fri, 31 Jul 2015 19:38:55 +0000 (22:38 +0300)
committerAki Tuomi <cmouse@cmouse.fi>
Tue, 4 Aug 2015 12:26:16 +0000 (15:26 +0300)
This utility class lets you do simple * and ? based matching.

pdns/misc.hh
pdns/test-misc_hh.cc

index eaeff786a070cb9ad9c9809f3d77f5d71e36d800..63816c8a88ed092938f86236cb14b60ca55c999a 100644 (file)
@@ -558,6 +558,57 @@ private:
   regex_t d_preg;
 };
 
+class SimpleMatch
+{
+public:
+  SimpleMatch(const string &mask, bool caseFold = false)
+  {
+    this->d_mask = mask;
+    this->d_fold = caseFold;
+  }
+  bool match(string::const_iterator mi, string::const_iterator mend, string::const_iterator vi, string::const_iterator vend)
+  {
+    for(;;mi++) {
+      if (mi == mend) {
+        return vi == vend;
+      } else if (*mi == '?') {
+        if (vi == vend) return false;
+        vi++;
+      } else if (*mi == '*') {
+        while(*mi == '*') mi++;
+        if (mi == d_mask.end()) return true;
+        while(vi != vend) {
+          if (match(mi,mend,vi,vend)) return true;
+          vi++;
+        }
+        return false;
+      } else {
+        if ((mi == mend && vi != vend)||
+            (mi != mend && vi == vend)) return false;
+        if (d_fold) {
+          if (dns_tolower(*mi) != dns_tolower(*vi)) return false;
+        } else {
+          if (*mi != *vi) return false;
+        }
+        vi++;
+      }
+    }
+  }
+
+  bool match(const string& value) {
+    return match(d_mask.begin(), d_mask.end(), value.begin(), value.end());
+  }
+
+  bool match(const DNSName& name) {
+    return match(name.toStringNoDot());
+  }
+
+private:
+  string d_mask;
+  bool d_fold;
+};
+
 union ComboAddress;
 void addCMsgSrcAddr(struct msghdr* msgh, void* cmsgbuf, const ComboAddress* source);
 
index 1d081b4aa9d99c4e74f49cc3cda08f1fbaadd3cc..117b0eebd901265e0710f216db61c47807cef853 100644 (file)
@@ -145,5 +145,31 @@ BOOST_AUTO_TEST_CASE(test_parseService) {
     BOOST_CHECK_EQUAL(tp.port, 25);
 }
 
+BOOST_AUTO_TEST_CASE(test_SimpleMatch) {
+  BOOST_CHECK_EQUAL(SimpleMatch("").match(std::string("")), true);
+  BOOST_CHECK_EQUAL(SimpleMatch("?").match(std::string("")), false);
+  BOOST_CHECK_EQUAL(SimpleMatch("*").match(std::string("")), true);
+
+  BOOST_CHECK_EQUAL(SimpleMatch("abc").match(std::string("abc")), true);
+  BOOST_CHECK_EQUAL(SimpleMatch("abc").match(std::string("ab")), false);
+  BOOST_CHECK_EQUAL(SimpleMatch("abc").match(std::string("bc")), false);
+
+  BOOST_CHECK_EQUAL(SimpleMatch("?").match(std::string("a")), true);
+  BOOST_CHECK_EQUAL(SimpleMatch("a?c").match(std::string("abc")), true);
+  BOOST_CHECK_EQUAL(SimpleMatch("a?c").match(std::string("ab")), false);
+  BOOST_CHECK_EQUAL(SimpleMatch("a?c").match(std::string("bc")), false);
+
+  BOOST_CHECK_EQUAL(SimpleMatch("*").match(std::string("*")), true);
+  BOOST_CHECK_EQUAL(SimpleMatch("a*c").match(std::string("abc")), true);
+  BOOST_CHECK_EQUAL(SimpleMatch("a*c").match(std::string("ab")), false);
+  BOOST_CHECK_EQUAL(SimpleMatch("a*c").match(std::string("bc")), false);
+
+  BOOST_CHECK_EQUAL(SimpleMatch("*").match(std::string("abcdefghj")), true);
+  BOOST_CHECK_EQUAL(SimpleMatch("*a").match(std::string("abca")), true);
+  BOOST_CHECK_EQUAL(SimpleMatch("*a").match(std::string("abcb")), false);
+  BOOST_CHECK_EQUAL(SimpleMatch("abc*").match(std::string("abcabcabcabacabac")), true);
+  BOOST_CHECK_EQUAL(SimpleMatch("abc*").match(std::string("abc")), true);
+}
+
 BOOST_AUTO_TEST_SUITE_END()