Socket/Protocols: Make BSDSocketAddress less_than_comparable
g0dil [Wed, 10 Jun 2009 22:01:46 +0000 (22:01 +0000)]
Socket/Protocols: Implement INet4Network input streaming
Socket/Protocols/INet: Add reuseaddr to connected UDPClientSocketHandle constructor
Utils/Console: Add emptyReplies flag to UDPServer

git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@1229 270642c3-0616-0410-b53a-bc976706d245

Socket/Protocols/BSDSocketAddress.cci
Socket/Protocols/BSDSocketAddress.hh
Socket/Protocols/INet/INet4Address.cc
Socket/Protocols/INet/INet4Address.hh
Socket/Protocols/INet/UDPSocketHandle.cc
Utils/Console/Console.hh
Utils/Console/UDPServer.cc
Utils/Console/UDPServer.hh

index 0c2499b..4c4084f 100644 (file)
@@ -71,10 +71,12 @@ prefix_ bool senf::BSDSocketAddress::operator==(BSDSocketAddress const & other)
     return socklen()==other.socklen() && memcmp(sockaddr_p(), other.sockaddr_p(), socklen())==0;
 }
 
-prefix_ bool senf::BSDSocketAddress::operator!=(BSDSocketAddress const & other)
+prefix_ bool senf::BSDSocketAddress::operator<(BSDSocketAddress const & other)
     const
 {
-    return ! operator==(other);
+    if (socklen() < other.socklen()) return true;
+    else if (socklen() > other.socklen()) return false;
+    else return memcmp(sockaddr_p(), other.sockaddr_p(), socklen()) < 0;
 }
 
 prefix_ bool senf::BSDSocketAddress::boolean_test()
index ec3edfd..2040513 100644 (file)
@@ -29,6 +29,7 @@
 // Custom includes
 #include <boost/type_traits/alignment_of.hpp>
 #include <boost/type_traits/type_with_alignment.hpp>
+#include <boost/operators.hpp>
 #include "../../Utils/safe_bool.hh"
 #include <sys/socket.h>
 #include <iostream>
@@ -73,14 +74,19 @@ namespace senf {
         \ingroup addr_group
       */
     class BSDSocketAddress
-        : public senf::comparable_safe_bool<BSDSocketAddress>
+        : public senf::comparable_safe_bool<BSDSocketAddress>,
+          public boost::less_than_comparable<BSDSocketAddress>,
+          public boost::equality_comparable<BSDSocketAddress>
     {
     public:
         bool operator==(BSDSocketAddress const & other) const; ///< Compare two arbitrary addresses
                                         /**< For addresses to be considered equal, they must have
                                              the same family, length and the data must be
                                              identical. */
-        bool operator!=(BSDSocketAddress const & other) const; ///< Inverse of operator==
+        bool operator<(BSDSocketAddress const & other) const; ///< Compare two arbitrary addresses
+                                        /**< Ordering is based on the in-memory representation.  It
+                                             is primarily useful to use addresses as keys in a map
+                                             or set. */
 
         bool boolean_test() const;      ///< Return \c true, if address is not empty
                                         /**< An address is considered empty if
@@ -114,7 +120,6 @@ namespace senf {
         void socklen(socklen_t len);
 
     private:
-        
         // The following incantation is needed to fix the alignment of the sockaddr data members
         // which will be added by the derived classes later: The alignment must be forced
         // to coincide with the struct sockaddr_storage alignment (which must have the largest
index e162200..0e56382 100644 (file)
@@ -166,6 +166,20 @@ prefix_ std::istream & senf::operator>>(std::istream & is, INet4Address & addr)
     return is;
 }
 
+prefix_ std::istream & senf::operator>>(std::istream & is, INet4Network & addr)
+{
+    std::string s;
+    if (!(is >> s))
+        return is;
+    try {
+        addr = INet4Network(s);
+    }
+    catch (AddressException &) {
+        is.setstate(std::ios::failbit);
+    }
+    return is;
+}
+
 ///////////////////////////////cc.e////////////////////////////////////////
 #undef prefix_
 //#include "INet4Address.mpp"
index fc21d0a..6651d68 100644 (file)
@@ -172,7 +172,8 @@ namespace senf {
         \related INet4Address
      */
     std::ostream & operator<<(std::ostream & os, INet4Address const & addr);
-    /** \brief Try to initialize INet4Address instance from a string representation
+
+    /** \brief Initialize INet4Address instance from a string representation
         sets std::ios::failbit on the stream if an error occurred
         \see INet4Address from_string()
         \related INet4Address
@@ -276,6 +277,13 @@ namespace senf {
      */
     std::ostream & operator<<(std::ostream & os, INet4Network const & addr);
 
+    /** \brief Initialize INet4Address instance from a string representation
+        sets std::ios::failbit on the stream if an error occurred
+        \see INet4Address from_string()
+        \related INet4Network
+     */
+    std::istream & operator>>(std::istream & is, INet4Network & addr);
+
 }
 
 ///////////////////////////////hh.e////////////////////////////////////////
index 827738b..dabff8b 100644 (file)
@@ -55,6 +55,7 @@ senf::UDPv4SocketProtocol::init_client(INet4SocketAddress const & address)
     const
 {
     init_client();
+    reuseaddr(true);
     clientHandle().bind(address);
 }
 
index 6f98d86..6b1b6ae 100644 (file)
@@ -41,6 +41,7 @@
 #include "ProgramOptions.hh"
 #include "Sysdir.hh"
 #include "STLSupport.hh"
+#include "UDPServer.hh"
 
 ///////////////////////////////hh.e////////////////////////////////////////
 //#include "Console.cci"
index f67030a..312a03d 100644 (file)
@@ -35,7 +35,8 @@
 ///////////////////////////////cc.p////////////////////////////////////////
 
 prefix_ senf::console::UDPServer::UDPServer(senf::INet4SocketAddress const & address)
-    : replies_ (true), target_ (), handle_ (senf::UDPv4ClientSocketHandle(address)), 
+    : replies_ (true), emptyReplies_ (true), target_ (), 
+      handle_ (senf::UDPv4ClientSocketHandle(address)), 
       readevent_ ("senf::console::UDPServer::readevent", 
                   senf::membind(&UDPServer::handleInput, this), 
                   handle_, 
@@ -82,6 +83,12 @@ senf::console::UDPServer::replies(senf::INet6SocketAddress const & address)
     return *this;
 }
 
+prefix_ senf::console::UDPServer & senf::console::UDPServer::emptyReplies(bool enable)
+{
+    emptyReplies_ = enable;
+    return *this;
+}
+
 prefix_ senf::console::DirectoryNode & senf::console::UDPServer::root()
     const
 {
@@ -123,7 +130,7 @@ prefix_ void senf::console::UDPServer::handleInput(int events)
             msg = msg.substr(i+4);
         stream << msg << std::endl;
     }
-    if (replies_) {
+    if (replies_ && (emptyReplies_ || ! stream.str().empty())) {
         if (target_)
             address = target_;
         if (stream.str().empty())
index b5a91d0..09832c1 100644 (file)
@@ -85,6 +85,8 @@ namespace console {
         UDPServer & replies(senf::INet6SocketAddress const & address);
                                         ///< Send replies to \a address
 
+        UDPServer & emptyReplies(bool enable); ///< Enable or disable empty reply packets
+
         DirectoryNode & root() const;   ///< Get root node
 
         UDPServer & root(DirectoryNode & root); ///< Set root node
@@ -97,6 +99,7 @@ namespace console {
         void handleInput(int events);
 
         bool replies_;
+        bool emptyReplies_;
         senf::GenericBSDSocketAddress target_;
 
         Handle handle_;