Socket/Protocols/INet: Fix INet6Network matching
g0dil [Fri, 4 Sep 2009 09:41:16 +0000 (09:41 +0000)]
git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@1377 270642c3-0616-0410-b53a-bc976706d245

senf/Socket/Protocols/INet/INet6Address.ct
senf/Socket/Protocols/INet/INet6Address.test.cc

index adcbaca..d7121a3 100644 (file)
@@ -68,9 +68,9 @@ prefix_ ForwardIterator1 senf::detail::find_if_mask(unsigned bits, ForwardIterat
         if (fn(*b1, *b2, boost::lambda::make_const(0xFFu)))
             return b1;
     if (bits > 0 && b1 != e1)
-        if (fn( *(b1++), *(b2++), boost::lambda::make_const(~ low_bits_mask(8-bits))))
+        if (fn(*b1, *b2, boost::lambda::make_const(~ low_bits_mask(8-bits))))
             return b1;
-    for(; b1 != e1; ++b1, ++b2)
+    for(++b1, ++b2; b1 != e1; ++b1, ++b2)
         if (fn(*b1, *b2, boost::lambda::make_const(0u)))
             return b1;
     return e1;
index 7a09b83..11dd197 100644 (file)
 #define prefix_
 ///////////////////////////////cc.p////////////////////////////////////////
 
+namespace {
+
+    template <class ForwardIterator1, class ForwardIterator2, class Function>
+    prefix_ ForwardIterator1 find_if_mask(unsigned bits, ForwardIterator1 b1,
+                                          ForwardIterator1 e1, ForwardIterator2 b2, 
+                                          Function fn)
+    {
+        std::cerr << ">>> " << bits << ' ' << e1-b1 << '\n';
+        for(; bits>8 && b1 != e1; bits -= 8, ++b1, ++b2) 
+            if (fn(*b1, *b2, boost::lambda::make_const(0xFFu)))
+                return b1;
+        std::cerr << ">>> " << bits << ' ' << e1-b1 << '\n';
+        if (bits > 0 && b1 != e1)
+            if (fn( *(b1++), *(b2++), boost::lambda::make_const(~ senf::detail::low_bits_mask(8-bits))))
+                return b1;
+        std::cerr << ">>> " << bits << ' ' << e1-b1 << '\n';
+        for(; b1 != e1; ++b1, ++b2)
+            if (fn(*b1, *b2, boost::lambda::make_const(0u)))
+                return b1;
+        return e1;
+    }
+
+    bool match(senf::INet6Network const & n, senf::INet6Address a)
+    {
+        using boost::lambda::_1;
+        using boost::lambda::_2;
+        using boost::lambda::_3;
+        using boost::lambda::ret;
+        using boost::lambda::constant;
+        senf::INet6Address na (n.address());
+        return find_if_mask(
+            n.prefix_len(), na.begin(), na.end(), a.begin(),
+            (
+                std::cerr << constant(">> ") << _1 << ' ' << _2 << ' ' << ret<unsigned>(_3) << '\n',
+                _1 != (_2 & _3)
+            )) == na.end();
+    }
+
+}
+
 BOOST_AUTO_UNIT_TEST(inet6Address)
 {
     using senf::INet6Address;
@@ -185,6 +225,8 @@ BOOST_AUTO_UNIT_TEST(inet6Network)
     BOOST_CHECK( ! net.match(net2) );
     BOOST_CHECK( net2.match(INet6Network("2001:db8:1234::/48")) );
     BOOST_CHECK( ! net2.match(INet6Network("2001:db8:1234::/32")) );
+    
+    BOOST_CHECK( ! INet6Network("ff14:1234::1/128").match(INet6Network("ff14:1234::2/128")) );
 
     BOOST_CHECK_EQUAL( senf::str(net2), "2001:db8:1230::/44" );