]> git.tdb.fi Git - libs/net.git/blobdiff - source/net/clientsocket.cpp
Add a dynamic receiver class for more flexible packet handling
[libs/net.git] / source / net / clientsocket.cpp
index d28d0e90b930487b4a573cb751356baf10575666..51a8dfa01b7913485397438ddcc3c24b5e9ae35b 100644 (file)
@@ -1,26 +1,19 @@
-#ifdef WIN32
-#include <winsock2.h>
-#else
-#include <cerrno>
-#include <sys/socket.h>
-#endif
-#include <msp/core/systemerror.h>
+#include "platform_api.h"
 #include "clientsocket.h"
+#include <msp/core/systemerror.h>
 #include "socket_private.h"
 
+using namespace std;
+
 namespace Msp {
 namespace Net {
 
 ClientSocket::ClientSocket(Family af, int type, int proto):
-       Socket(af, type, proto),
-       connecting(false),
-       connected(false),
-       peer_addr(0)
+       Socket(af, type, proto)
 { }
 
 ClientSocket::ClientSocket(const Private &p, const SockAddr &paddr):
        Socket(p),
-       connecting(false),
        connected(true),
        peer_addr(paddr.copy())
 { }
@@ -28,15 +21,13 @@ ClientSocket::ClientSocket(const Private &p, const SockAddr &paddr):
 ClientSocket::~ClientSocket()
 {
        signal_flush_required.emit();
-
-       delete peer_addr;
 }
 
 void ClientSocket::shutdown(IO::Mode m)
 {
        int how;
        m = m&IO::M_RDWR;
-#ifdef WIN32
+#ifdef _WIN32
        if(m==IO::M_READ)
                how = SD_RECEIVE;
        else if(m==IO::M_WRITE)
@@ -60,12 +51,12 @@ void ClientSocket::shutdown(IO::Mode m)
 
 const SockAddr &ClientSocket::get_peer_address() const
 {
-       if(peer_addr==0)
+       if(!peer_addr)
                throw bad_socket_state("not connected");
        return *peer_addr;
 }
 
-unsigned ClientSocket::do_write(const char *buf, unsigned size)
+size_t ClientSocket::do_write(const char *buf, size_t size)
 {
        check_access(IO::M_WRITE);
        if(!connected)
@@ -74,43 +65,31 @@ unsigned ClientSocket::do_write(const char *buf, unsigned size)
        if(size==0)
                return 0;
 
-       int ret = ::send(priv->handle, buf, size, 0);
-       if(ret<0)
-       {
-               if(errno==EAGAIN)
-                       return 0;
-               else
-                       throw system_error("send");
-       }
-
-       return ret;
+       return check_sys_error(::send(priv->handle, buf, size, 0), "send");
 }
 
-unsigned ClientSocket::do_read(char *buf, unsigned size)
+size_t ClientSocket::do_read(char *buf, size_t size)
 {
        check_access(IO::M_READ);
        if(!connected)
                throw bad_socket_state("not connected");
 
+       // XXX This breaks level-triggered semantics on Windows
        if(size==0)
                return 0;
 
-       int ret = ::recv(priv->handle, buf, size, 0);
-       if(ret<0)
+       make_signed<size_t>::type ret = ::recv(priv->handle, buf, size, 0);
+       if(ret==0)
        {
-               if(errno==EAGAIN)
-                       return 0;
-               else
-                       throw system_error("recv");
-       }
-       else if(ret==0 && !eof_flag)
-       {
-               eof_flag = true;
-               signal_end_of_file.emit();
-               set_events(IO::P_NONE);
+               if(!eof_flag)
+               {
+                       set_socket_events(S_NONE);
+                       set_eof();
+               }
+               return 0;
        }
 
-       return ret;
+       return check_sys_error(ret, "recv");
 }
 
 } // namespace Net