]> git.tdb.fi Git - libs/net.git/blobdiff - source/streamsocket.cpp
Move some functions around a bit
[libs/net.git] / source / streamsocket.cpp
index e5f904ffdcbf4bd26851148b16790ad12a2ab374..b06cf69ca9314cb6c750c1147513f9b4dc9c3a0a 100644 (file)
@@ -2,98 +2,53 @@
 #include <sys/socket.h>
 #endif
 #include <cerrno>
+#include <msp/core/systemerror.h>
+#include <msp/io/handle_private.h>
 #include <msp/io/poll.h>
-#include <msp/strings/formatter.h>
+#include <msp/strings/format.h>
+#include "sockaddr_private.h"
+#include "socket_private.h"
 #include "streamsocket.h"
 
 namespace Msp {
 namespace Net {
 
-StreamSocket::StreamSocket(SocketHandle h, const SockAddr &paddr):
-       Socket(h, paddr),
-       connecting(false)
+StreamSocket::StreamSocket(const Private &p, const SockAddr &paddr):
+       ClientSocket(p, paddr)
 {
 #ifdef WIN32
-       WSAEventSelect(handle, event, FD_READ|FD_CLOSE);
+       WSAEventSelect(priv->handle, *priv->event, FD_READ|FD_CLOSE);
 #endif
        set_events(IO::P_INPUT);
 }
 
 StreamSocket::StreamSocket(Family af, int proto):
-       Socket(af, SOCK_STREAM, proto),
-       connecting(false)
+       ClientSocket(af, SOCK_STREAM, proto)
 { }
 
-int StreamSocket::poll_connect(const Time::TimeDelta &timeout)
+bool StreamSocket::connect(const SockAddr &addr)
 {
-       check_state(false);
-       if(!connecting)
-               throw InvalidState("No connection attempt going on");
-
-       int res = poll(*this, IO::P_OUTPUT, timeout);
-       if(res==-1)
-#ifdef WIN32
-               throw Exception(format("Connection polling failed: %d", WSAGetLastError()));
-#else
-               throw SystemError("Connection polling failed", errno);
-#endif
-       else if(res>0)
-       {
-               connecting = false;
-
-               int err;
-               socklen_t len = sizeof(int);
-               get_option(SOL_SOCKET, SO_ERROR, &err, &len);
-
-               if(err!=0)
-               {
-                       set_events(IO::P_NONE);
-#ifdef WIN32
-                       throw Exception(format("Connection failed: %d", err));
-#else
-                       throw SystemError("Connection failed", err);
-#endif
-               }
-
-#ifdef WIN32
-               WSAEventSelect(handle, event, FD_READ|FD_CLOSE);
-#endif
-               set_events(IO::P_INPUT);
-
-               connected = true;
-
-               return 0;
-       }
-
-       return 1;
-}
-
-int StreamSocket::connect(const SockAddr &addr)
-{
-       check_state(false);
-
        if(connected)
-               throw InvalidState("Socket is already connected");
+               throw bad_socket_state("already connected");
 
-       sockaddr_storage sa;
-       socklen_t size = addr.fill_sockaddr(sa);
+       SockAddr::SysAddr sa = addr.to_sys();
 
 #ifdef WIN32
-       int err = WSAConnect(handle, reinterpret_cast<sockaddr *>(&sa), size, 0, 0, 0, 0);
+       int err = WSAConnect(priv->handle, reinterpret_cast<sockaddr *>(&sa.addr), sa.size, 0, 0, 0, 0);
        if(err==SOCKET_ERROR)
        {
                int err_code = WSAGetLastError();
                if(err_code==WSAEWOULDBLOCK)
                {
                        connecting = true;
-                       WSAEventSelect(handle, event, FD_CONNECT);
+                       WSAEventSelect(priv->handle, *priv->event, FD_CONNECT);
                        set_events(IO::P_OUTPUT);
                }
                else
-                       throw Exception(format("Unable to connect: %d", err_code));
+                       throw system_error("connect", err_code);
        }
 #else
-       int err = ::connect(handle, reinterpret_cast<sockaddr *>(&sa), size);
+       int err = ::connect(priv->handle, reinterpret_cast<sockaddr *>(&sa.addr), sa.size);
        if(err==-1)
        {
                if(errno==EINPROGRESS)
@@ -102,7 +57,7 @@ int StreamSocket::connect(const SockAddr &addr)
                        set_events(IO::P_OUTPUT);
                }
                else
-                       throw SystemError("Unable to connect", errno);
+                       throw system_error("connect");
        }
 #endif
 
@@ -110,9 +65,9 @@ int StreamSocket::connect(const SockAddr &addr)
        peer_addr = addr.copy();
 
        delete local_addr;
-       size = sizeof(sockaddr_storage);
-       getsockname(handle, reinterpret_cast<sockaddr *>(&sa), &size);
-       local_addr = SockAddr::create(sa);
+       SockAddr::SysAddr lsa;
+       getsockname(priv->handle, reinterpret_cast<sockaddr *>(&lsa.addr), &lsa.size);
+       local_addr = SockAddr::from_sys(lsa);
 
        if(err==0)
        {
@@ -121,7 +76,48 @@ int StreamSocket::connect(const SockAddr &addr)
                signal_connect_finished.emit(0);
        }
 
-       return (err==0)?0:1;
+       return connected;
+}
+
+bool StreamSocket::poll_connect(const Time::TimeDelta &timeout)
+{
+       if(!connecting)
+               throw bad_socket_state("not connecting");
+
+       int res = poll(*this, IO::P_OUTPUT, timeout);
+       if(res==-1)
+#ifdef WIN32
+               throw system_error("poll", WSAGetLastError());
+#else
+               throw system_error("poll");
+#endif
+       else if(res>0)
+       {
+               connecting = false;
+
+               int err;
+               socklen_t len = sizeof(int);
+               get_option(SOL_SOCKET, SO_ERROR, &err, &len);
+
+               if(err!=0)
+               {
+                       set_events(IO::P_NONE);
+#ifdef WIN32
+                       throw system_error("connect", WSAGetLastError());
+#else
+                       throw system_error("connect");
+#endif
+               }
+
+#ifdef WIN32
+               WSAEventSelect(priv->handle, *priv->event, FD_READ|FD_CLOSE);
+#endif
+               set_events(IO::P_INPUT);
+
+               connected = true;
+       }
+
+       return connected;
 }
 
 void StreamSocket::on_event(IO::PollEvent ev)
@@ -143,7 +139,7 @@ void StreamSocket::on_event(IO::PollEvent ev)
                }
 
 #ifdef WIN32
-               WSAEventSelect(handle, event, FD_READ|FD_CLOSE);
+               WSAEventSelect(priv->handle, *priv->event, FD_READ|FD_CLOSE);
 #endif
                set_events((err==0) ? IO::P_INPUT : IO::P_NONE);
        }