]> git.tdb.fi Git - libs/net.git/commitdiff
Hide platform details of Socket behind pimpl
authorMikko Rasa <tdb@tdb.fi>
Sat, 6 Aug 2011 09:14:36 +0000 (12:14 +0300)
committerMikko Rasa <tdb@tdb.fi>
Sat, 6 Aug 2011 09:14:36 +0000 (12:14 +0300)
source/datagramsocket.cpp
source/socket.cpp
source/socket.h
source/socket_private.h [new file with mode: 0644]
source/streamlistensocket.cpp
source/streamsocket.cpp
source/streamsocket.h
source/types.h [deleted file]

index 1368d153feb87aa7c574dfc4abb3ebdea01f6314..7aee3f868d455429c575f77f0d93cf817aaa860f 100644 (file)
@@ -1,7 +1,9 @@
 #include <cerrno>
 #include <msp/core/systemerror.h>
+#include <msp/io/handle_private.h>
 #include <msp/strings/format.h>
 #include "datagramsocket.h"
+#include "socket_private.h"
 
 namespace Msp {
 namespace Net {
@@ -10,7 +12,7 @@ DatagramSocket::DatagramSocket(Family f, int p):
        Socket(f, SOCK_DGRAM, p)
 {
 #ifdef WIN32
-       WSAEventSelect(handle, event, FD_READ|FD_CLOSE);
+       WSAEventSelect(priv->handle, *priv->event, FD_READ|FD_CLOSE);
 #endif
        set_events(IO::P_INPUT);
 }
@@ -20,7 +22,7 @@ int DatagramSocket::connect(const SockAddr &addr)
        sockaddr_storage sa;
        socklen_t size = addr.fill_sockaddr(sa);
 
-       int err = ::connect(handle, reinterpret_cast<sockaddr *>(&sa), size);
+       int err = ::connect(priv->handle, reinterpret_cast<sockaddr *>(&sa), size);
        if(err==-1)
        {
 #ifdef WIN32
@@ -35,7 +37,7 @@ int DatagramSocket::connect(const SockAddr &addr)
 
        delete local_addr;
        size = sizeof(sockaddr_storage);
-       getsockname(handle, reinterpret_cast<sockaddr *>(&sa), &size);
+       getsockname(priv->handle, reinterpret_cast<sockaddr *>(&sa), &size);
        local_addr = SockAddr::create(sa);
 
        connected = true;
@@ -51,7 +53,7 @@ unsigned DatagramSocket::sendto(const char *buf, unsigned size, const SockAddr &
        sockaddr_storage addr;
        socklen_t addr_len = addr_.fill_sockaddr(addr);
 
-       int ret = ::sendto(handle, buf, size, 0, reinterpret_cast<sockaddr *>(&addr), addr_len);
+       int ret = ::sendto(priv->handle, buf, size, 0, reinterpret_cast<sockaddr *>(&addr), addr_len);
        if(ret<0)
        {
                if(errno==EAGAIN)
@@ -77,7 +79,7 @@ unsigned DatagramSocket::recvfrom(char *buf, unsigned size, SockAddr *&addr_)
        sockaddr_storage addr;
        socklen_t addr_len = sizeof(sockaddr_storage);
 
-       int ret = ::recvfrom(handle, buf, size, 0, reinterpret_cast<sockaddr *>(&addr), &addr_len);
+       int ret = ::recvfrom(priv->handle, buf, size, 0, reinterpret_cast<sockaddr *>(&addr), &addr_len);
        if(ret<0)
        {
                if(errno==EAGAIN)
index 7a82463bcd16609a89bd69bf816aece68ab66b3a..e91b684be8187407a6d323ff276f692756041a2e 100644 (file)
@@ -10,6 +10,7 @@
 #include <msp/time/rawtime_private.h>
 #include <msp/time/units.h>
 #include "socket.h"
+#include "socket_private.h"
 
 namespace {
 
@@ -39,35 +40,38 @@ WinSockHelper wsh;
 namespace Msp {
 namespace Net {
 
-Socket::Socket(SocketHandle h, const SockAddr &paddr):
-       handle(h),
+Socket::Socket(const Private &p, const SockAddr &paddr):
+       priv(new Private),
        connected(true),
        local_addr(0),
        peer_addr(paddr.copy())
 {
+       priv->handle = p.handle;
+
        sockaddr_storage sa;
        socklen_t size = sizeof(sockaddr_storage);
-       getsockname(handle, reinterpret_cast<sockaddr *>(&sa), &size);
+       getsockname(priv->handle, reinterpret_cast<sockaddr *>(&sa), &size);
        local_addr = SockAddr::create(sa);
 
 #ifdef WIN32
-       event = CreateEvent(0, false, false, 0);
+       *priv->event = CreateEvent(0, false, false, 0);
 #else
-       *event = handle;
+       *priv->event = priv->handle;
 #endif
 }
 
 Socket::Socket(Family af, int type, int proto):
+       priv(new Private),
        connected(false),
        local_addr(0),
        peer_addr(0)
 {
-       handle = socket(af, type, proto);
+       priv->handle = socket(af, type, proto);
 
 #ifdef WIN32
-       event = CreateEvent(0, false, false, 0);
+       *priv->event = CreateEvent(0, false, false, 0);
 #else
-       *event = handle;
+       *priv->event = priv->handle;
 #endif
 }
 
@@ -75,14 +79,15 @@ Socket::~Socket()
 {
        signal_flush_required.emit();
 #ifdef WIN32
-       closesocket(handle);
-       CloseHandle(event);
+       closesocket(priv->handle);
+       CloseHandle(*priv->event);
 #else
-       ::close(handle);
+       ::close(priv->handle);
 #endif
 
        delete local_addr;
        delete peer_addr;
+       delete priv;
 }
 
 void Socket::set_block(bool b)
@@ -93,16 +98,16 @@ void Socket::set_block(bool b)
 
 #ifdef WIN32
        u_long flag = !b;
-       ioctlsocket(handle, FIONBIO, &flag);
+       ioctlsocket(priv->handle, FIONBIO, &flag);
 #else
-       int flags = fcntl(handle, F_GETFL);
-       fcntl(handle, F_SETFL, (flags&O_NONBLOCK)|(b?0:O_NONBLOCK));
+       int flags = fcntl(priv->handle, F_GETFL);
+       fcntl(priv->handle, F_SETFL, (flags&O_NONBLOCK)|(b?0:O_NONBLOCK));
 #endif
 }
 
 const IO::Handle &Socket::get_event_handle()
 {
-       return event;
+       return priv->event;
 }
 
 
@@ -111,7 +116,7 @@ void Socket::bind(const SockAddr &addr)
        sockaddr_storage sa;
        unsigned size = addr.fill_sockaddr(sa);
 
-       int err = ::bind(handle, reinterpret_cast<sockaddr *>(&sa), size);
+       int err = ::bind(priv->handle, reinterpret_cast<sockaddr *>(&sa), size);
        if(err==-1)
                throw system_error("bind");
 
@@ -149,18 +154,18 @@ const SockAddr &Socket::get_peer_address() const
 int Socket::set_option(int level, int optname, const void *optval, socklen_t optlen)
 {
 #ifdef WIN32
-       return setsockopt(handle, level, optname, reinterpret_cast<const char *>(optval), optlen);
+       return setsockopt(priv->handle, level, optname, reinterpret_cast<const char *>(optval), optlen);
 #else
-       return setsockopt(handle, level, optname, optval, optlen);
+       return setsockopt(priv->handle, level, optname, optval, optlen);
 #endif
 }
 
 int Socket::get_option(int level, int optname, void *optval, socklen_t *optlen) const
 {
 #ifdef WIN32
-       return getsockopt(handle, level, optname, reinterpret_cast<char *>(optval), optlen);
+       return getsockopt(priv->handle, level, optname, reinterpret_cast<char *>(optval), optlen);
 #else
-       return getsockopt(handle, level, optname, optval, optlen);
+       return getsockopt(priv->handle, level, optname, optval, optlen);
 #endif
 }
 
@@ -172,7 +177,7 @@ unsigned Socket::do_write(const char *buf, unsigned size)
        if(size==0)
                return 0;
 
-       int ret = ::send(handle, buf, size, 0);
+       int ret = ::send(priv->handle, buf, size, 0);
        if(ret<0)
        {
                if(errno==EAGAIN)
@@ -193,7 +198,7 @@ unsigned Socket::do_read(char *buf, unsigned size)
        if(size==0)
                return 0;
 
-       int ret = ::recv(handle, buf, size, 0);
+       int ret = ::recv(priv->handle, buf, size, 0);
        if(ret<0)
        {
                if(errno==EAGAIN)
index 6eb29066e03d078a469f897c79c99f35a19ebcbe..861012b8cc50c0bb2114440f0de2439fcacaa744 100644 (file)
@@ -5,11 +5,15 @@
 #include <msp/io/handle.h>
 #include "constants.h"
 #include "sockaddr.h"
-#include "types.h"
 
 namespace Msp {
 namespace Net {
 
+#ifdef WIN32
+typedef int socklen_t;
+#endif
+
+
 class bad_socket_state: public std::logic_error
 {
 public:
@@ -21,13 +25,14 @@ public:
 class Socket: public IO::EventObject
 {
 protected:
-       SocketHandle handle;
-       IO::Handle event;
+       struct Private;
+
+       Private *priv;
        bool connected;
        SockAddr *local_addr;
        SockAddr *peer_addr;
 
-       Socket(SocketHandle, const SockAddr &);
+       Socket(const Private &, const SockAddr &);
        Socket(Family, int, int);
 public:
        ~Socket();
diff --git a/source/socket_private.h b/source/socket_private.h
new file mode 100644 (file)
index 0000000..83cc369
--- /dev/null
@@ -0,0 +1,26 @@
+#ifndef MSP_NET_SOCKET_PRIVATE_H_
+#define MSP_NET_SOCKET_PRIVATE_H_
+
+#include <msp/io/handle.h>
+#include "socket.h"
+
+namespace Msp {
+namespace Net {
+
+struct Socket::Private
+{
+#ifdef WIN32
+       SOCKET handle;
+#else
+       int handle;
+#endif
+
+       /* On POSIX platforms this is the same as the handle.  This might seem
+       strange but it allows the same syntax on both POSIX and Windows. */
+       IO::Handle event;
+};
+
+} // namespace Net
+} // namespace Msp
+
+#endif
index 693f3040dc85c0a81dcc1bd6b8271dea8a91f88a..3b375bcafcadb54d0581b1cf6500b82a87ca1448 100644 (file)
@@ -1,7 +1,9 @@
 #include <cerrno>
 #include <msp/core/refptr.h>
 #include <msp/core/systemerror.h>
+#include <msp/io/handle_private.h>
 #include <msp/strings/format.h>
+#include "socket_private.h"
 #include "streamlistensocket.h"
 #include "streamsocket.h"
 
@@ -25,12 +27,12 @@ void StreamListenSocket::listen(const SockAddr &addr, unsigned backlog)
 {
        bind(addr);
 
-       int err = ::listen(handle, backlog);
+       int err = ::listen(priv->handle, backlog);
        if(err==-1)
                throw system_error("listen");
 
 #ifdef WIN32
-       WSAEventSelect(handle, event, FD_ACCEPT);
+       WSAEventSelect(priv->handle, *priv->event, FD_ACCEPT);
 #endif
        set_events(IO::P_INPUT);
 
@@ -44,10 +46,11 @@ StreamSocket *StreamListenSocket::accept()
 
        sockaddr_storage sa;
        socklen_t size = sizeof(sockaddr_storage);
-       SocketHandle new_h = ::accept(handle, reinterpret_cast<sockaddr *>(&sa), &size);
+       Private new_p;
+       new_p.handle = ::accept(priv->handle, reinterpret_cast<sockaddr *>(&sa), &size);
 
        RefPtr<SockAddr> paddr = SockAddr::create(sa);
-       return new StreamSocket(new_h, *paddr);
+       return new StreamSocket(new_p, *paddr);
 }
 
 } // namespace Net
index 59590846f16d0661917b4134b4b6aaa9ef919abb..c6cd214e18dc08dc1620cd190f27287dd8c6ce11 100644 (file)
@@ -3,19 +3,21 @@
 #endif
 #include <cerrno>
 #include <msp/core/systemerror.h>
+#include <msp/io/handle_private.h>
 #include <msp/io/poll.h>
 #include <msp/strings/format.h>
+#include "socket_private.h"
 #include "streamsocket.h"
 
 namespace Msp {
 namespace Net {
 
-StreamSocket::StreamSocket(SocketHandle h, const SockAddr &paddr):
-       Socket(h, paddr),
+StreamSocket::StreamSocket(const Private &p, const SockAddr &paddr):
+       Socket(p, paddr),
        connecting(false)
 {
 #ifdef WIN32
-       WSAEventSelect(handle, event, FD_READ|FD_CLOSE);
+       WSAEventSelect(priv->handle, *priv->event, FD_READ|FD_CLOSE);
 #endif
        set_events(IO::P_INPUT);
 }
@@ -56,7 +58,7 @@ int StreamSocket::poll_connect(const Time::TimeDelta &timeout)
                }
 
 #ifdef WIN32
-               WSAEventSelect(handle, event, FD_READ|FD_CLOSE);
+               WSAEventSelect(priv->handle, *priv->event, FD_READ|FD_CLOSE);
 #endif
                set_events(IO::P_INPUT);
 
@@ -77,21 +79,21 @@ int StreamSocket::connect(const SockAddr &addr)
        socklen_t size = addr.fill_sockaddr(sa);
 
 #ifdef WIN32
-       int err = WSAConnect(handle, reinterpret_cast<sockaddr *>(&sa), size, 0, 0, 0, 0);
+       int err = WSAConnect(priv->handle, reinterpret_cast<sockaddr *>(&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 system_error("connect", err_code);
        }
 #else
-       int err = ::connect(handle, reinterpret_cast<sockaddr *>(&sa), size);
+       int err = ::connect(priv->handle, reinterpret_cast<sockaddr *>(&sa), size);
        if(err==-1)
        {
                if(errno==EINPROGRESS)
@@ -109,7 +111,7 @@ int StreamSocket::connect(const SockAddr &addr)
 
        delete local_addr;
        size = sizeof(sockaddr_storage);
-       getsockname(handle, reinterpret_cast<sockaddr *>(&sa), &size);
+       getsockname(priv->handle, reinterpret_cast<sockaddr *>(&sa), &size);
        local_addr = SockAddr::create(sa);
 
        if(err==0)
@@ -141,7 +143,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);
        }
index dcc5dbd63c7025751c771ea141c148a197080436..3ffe72aa164441f1510c383a7ca322dcdd29d4d3 100644 (file)
@@ -19,7 +19,7 @@ public:
 
 private:
        /// Used by StreamListenSocket to construct a new socket from accept.
-       StreamSocket(SocketHandle, const SockAddr &);
+       StreamSocket(const Private &, const SockAddr &);
 public:
        StreamSocket(Family, int = 0);
 
diff --git a/source/types.h b/source/types.h
deleted file mode 100644 (file)
index 3af68ab..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-#ifndef MSP_NET_TYPES_H_
-#define MSP_NET_TYPES_H_
-
-namespace Msp {
-namespace Net {
-
-#ifdef WIN32
-typedef SOCKET SocketHandle;
-typedef int socklen_t;
-
-#define MSP_NET_INVALID_SOCKET_HANDLE static_cast<SOCKET>(-1)
-#else
-typedef int SocketHandle;
-
-#define MSP_NET_INVALID_SOCKET_HANDLE -1
-#endif
-
-} // namespace Net
-} // namespace Msp
-
-#endif