55#include < deque>
66#include < strings.h>
77#include < stdexcept>
8+
89// #include "dns.hh"
910// #include "logger.hh"
1011
@@ -77,11 +78,12 @@ public:
7778 ar & d_empty;
7879 }
7980
80- bool canonCompare (const DNSName& rhs) const ;
81+ inline bool canonCompare (const DNSName& rhs) const ;
8182
8283private:
8384 // typedef __gnu_cxx::__sso_string string_t;
8485 typedef std::string string_t ;
86+ bool slowCanonCompare (const DNSName& rhs) const ;
8587 string_t d_storage;
8688 bool d_empty;
8789 int d_recurse;
@@ -93,6 +95,80 @@ private:
9395
9496size_t hash_value (DNSName const & d);
9597
98+ inline char dns2_tolower (char c)
99+ {
100+ if (c>=' A' && c<=' Z' )
101+ c+=' a' -' A' ;
102+ return c;
103+ }
104+
105+
106+ inline bool DNSName::canonCompare (const DNSName& rhs) const
107+ {
108+ // 01234567890abcd
109+ // us: 1a3www4ds9a2nl
110+ // rhs: 3www6online3com
111+ // to compare, we start at the back, is nl < com? no -> done
112+ //
113+ // 0,2,6,a
114+ // 0,4,a
115+
116+ uint8_t ourpos[64 ], rhspos[64 ];
117+ uint8_t ourcount=0 , rhscount=0 ;
118+ // cout<<"Asked to compare "<<toString()<<" to "<<rhs.toString()<<endl;
119+ for (const char * p = d_storage.c_str (); p < d_storage.c_str () + d_storage.size () && ourcount < sizeof (ourpos); p+=*p+1 )
120+ ourpos[ourcount++]=(p-d_storage.c_str ());
121+ 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 )
122+ rhspos[rhscount++]=(p-rhs.d_storage .c_str ());
123+
124+ if (ourcount == sizeof (ourpos) || rhscount==sizeof (rhspos)) {
125+ return slowCanonCompare (rhs);
126+ }
127+
128+ for (;;) {
129+ if (ourcount == 0 && rhscount != 0 )
130+ return true ;
131+ if (ourcount == 0 && rhscount == 0 )
132+ return false ;
133+ if (ourcount !=0 && rhscount == 0 )
134+ return false ;
135+ ourcount--;
136+ rhscount--;
137+
138+ /*
139+ cout<<"Going to compare: '"<<string(d_storage.c_str() + ourpos[ourcount] + 1,
140+ d_storage.c_str() + ourpos[ourcount] + 1 + *(d_storage.c_str() + ourpos[ourcount]))<<"'"<<endl;
141+ cout<<"Against: '"<<string(rhs.d_storage.c_str() + rhspos[rhscount] + 1,
142+ rhs.d_storage.c_str() + rhspos[rhscount] + 1 + *(rhs.d_storage.c_str() + rhspos[rhscount]))<<"'"<<endl;
143+ */
144+ bool res=std::lexicographical_compare (
145+ d_storage.c_str () + ourpos[ourcount] + 1 ,
146+ d_storage.c_str () + ourpos[ourcount] + 1 + *(d_storage.c_str () + ourpos[ourcount]),
147+ rhs.d_storage .c_str () + rhspos[rhscount] + 1 ,
148+ rhs.d_storage .c_str () + rhspos[rhscount] + 1 + *(rhs.d_storage .c_str () + rhspos[rhscount]),
149+ [](const char & a, const char & b) {
150+ return dns2_tolower (a) < dns2_tolower (b);
151+ });
152+
153+ // cout<<"Forward: "<<res<<endl;
154+ if (res)
155+ return true ;
156+
157+ res=std::lexicographical_compare ( rhs.d_storage .c_str () + rhspos[rhscount] + 1 ,
158+ rhs.d_storage .c_str () + rhspos[rhscount] + 1 + *(rhs.d_storage .c_str () + rhspos[rhscount]),
159+ d_storage.c_str () + ourpos[ourcount] + 1 ,
160+ d_storage.c_str () + ourpos[ourcount] + 1 + *(d_storage.c_str () + ourpos[ourcount]),
161+ [](const char & a, const char & b) {
162+ return dns2_tolower (a) < dns2_tolower (b);
163+ });
164+ // cout<<"Reverse: "<<res<<endl;
165+ if (res)
166+ return false ;
167+ }
168+ return false ;
169+ }
170+
171+
96172struct CanonDNSNameCompare : public std ::binary_function<DNSName, DNSName, bool >
97173{
98174 bool operator ()(const DNSName&a, const DNSName& b) const
0 commit comments