d_storage = prep+d_storage;
}
+bool DNSName::slowCanonCompare(const DNSName& rhs) const
+{
+ auto ours=getRawLabels(), rhsLabels = rhs.getRawLabels();
+ return std::lexicographical_compare(ours.rbegin(), ours.rend(), rhsLabels.rbegin(), rhsLabels.rend(), CIStringCompare());
+}
+
vector<string> DNSName::getRawLabels() const
{
vector<string> ret;
return ret;
}
-bool DNSName::canonCompare(const DNSName& rhs) const
-{
- auto ours=getRawLabels(), rhsLabels = rhs.getRawLabels();
- return std::lexicographical_compare(ours.rbegin(), ours.rend(), rhsLabels.rbegin(), rhsLabels.rend(), CIStringCompare());
-}
bool DNSName::chopOff()
{
#include <deque>
#include <strings.h>
#include <stdexcept>
+
// #include "dns.hh"
// #include "logger.hh"
ar & d_empty;
}
- bool canonCompare(const DNSName& rhs) const;
+ inline bool canonCompare(const DNSName& rhs) const;
private:
// typedef __gnu_cxx::__sso_string string_t;
typedef std::string string_t;
+ bool slowCanonCompare(const DNSName& rhs) const;
string_t d_storage;
bool d_empty;
int d_recurse;
size_t hash_value(DNSName const& d);
+inline char dns2_tolower(char c)
+{
+ if(c>='A' && c<='Z')
+ c+='a'-'A';
+ return c;
+}
+
+
+inline bool DNSName::canonCompare(const DNSName& rhs) const
+{
+ // 01234567890abcd
+ // us: 1a3www4ds9a2nl
+ // rhs: 3www6online3com
+ // to compare, we start at the back, is nl < com? no -> done
+ //
+ // 0,2,6,a
+ // 0,4,a
+
+ uint8_t ourpos[64], rhspos[64];
+ uint8_t ourcount=0, rhscount=0;
+ //cout<<"Asked to compare "<<toString()<<" to "<<rhs.toString()<<endl;
+ for(const char* p = d_storage.c_str(); p < d_storage.c_str() + d_storage.size() && ourcount < sizeof(ourpos); p+=*p+1)
+ ourpos[ourcount++]=(p-d_storage.c_str());
+ for(const char* p = rhs.d_storage.c_str(); p < rhs.d_storage.c_str() + rhs.d_storage.size() && rhscount < sizeof(rhspos); p+=*p+1)
+ rhspos[rhscount++]=(p-rhs.d_storage.c_str());
+
+ if(ourcount == sizeof(ourpos) || rhscount==sizeof(rhspos)) {
+ return slowCanonCompare(rhs);
+ }
+
+ for(;;) {
+ if(ourcount == 0 && rhscount != 0)
+ return true;
+ if(ourcount == 0 && rhscount == 0)
+ return false;
+ if(ourcount !=0 && rhscount == 0)
+ return false;
+ ourcount--;
+ rhscount--;
+
+ /*
+ cout<<"Going to compare: '"<<string(d_storage.c_str() + ourpos[ourcount] + 1,
+ d_storage.c_str() + ourpos[ourcount] + 1 + *(d_storage.c_str() + ourpos[ourcount]))<<"'"<<endl;
+ cout<<"Against: '"<<string(rhs.d_storage.c_str() + rhspos[rhscount] + 1,
+ rhs.d_storage.c_str() + rhspos[rhscount] + 1 + *(rhs.d_storage.c_str() + rhspos[rhscount]))<<"'"<<endl;
+ */
+ bool res=std::lexicographical_compare(
+ d_storage.c_str() + ourpos[ourcount] + 1,
+ d_storage.c_str() + ourpos[ourcount] + 1 + *(d_storage.c_str() + ourpos[ourcount]),
+ rhs.d_storage.c_str() + rhspos[rhscount] + 1,
+ rhs.d_storage.c_str() + rhspos[rhscount] + 1 + *(rhs.d_storage.c_str() + rhspos[rhscount]),
+ [](const char& a, const char& b) {
+ return dns2_tolower(a) < dns2_tolower(b);
+ });
+
+ // cout<<"Forward: "<<res<<endl;
+ if(res)
+ return true;
+
+ res=std::lexicographical_compare( rhs.d_storage.c_str() + rhspos[rhscount] + 1,
+ rhs.d_storage.c_str() + rhspos[rhscount] + 1 + *(rhs.d_storage.c_str() + rhspos[rhscount]),
+ d_storage.c_str() + ourpos[ourcount] + 1,
+ d_storage.c_str() + ourpos[ourcount] + 1 + *(d_storage.c_str() + ourpos[ourcount]),
+ [](const char& a, const char& b) {
+ return dns2_tolower(a) < dns2_tolower(b);
+ });
+ // cout<<"Reverse: "<<res<<endl;
+ if(res)
+ return false;
+ }
+ return false;
+}
+
+
struct CanonDNSNameCompare: public std::binary_function<DNSName, DNSName, bool>
{
bool operator()(const DNSName&a, const DNSName& b) const
DNSName lower("bert.com."), higher("alpha.nl.");
BOOST_CHECK(lower.canonCompare(higher));
+ BOOST_CHECK(DNSName("bert.com").canonCompare(DNSName("www.bert.com")));
+ BOOST_CHECK(DNSName("BeRt.com").canonCompare(DNSName("WWW.berT.com")));
+ BOOST_CHECK(!DNSName("www.BeRt.com").canonCompare(DNSName("WWW.berT.com")));
vector<DNSName> vec;
for(const std::string& a : {"bert.com.", "alpha.nl.", "articles.xxx.",
}
sort(vec.begin(), vec.end(), CanonDNSNameCompare());
// for(const auto& v : vec)
- // cerr<<'"'<<v.toString()<<'"'<<endl;
+ // cerr<<'"'<<v.toString()<<'"'<<endl;
vector<DNSName> right;
for(const auto& a: {"bert.com.", "Aleph1.powerdns.com.",
"yyy.XXX."})
right.push_back(DNSName(a));
+
BOOST_CHECK(vec==right);
}