]> Dogcows Code - chaz/yoink/blobdiff - src/Moof/Socket.hh
port new sockets stuff to winsock
[chaz/yoink] / src / Moof / Socket.hh
index a4cb310b3403b4183562354dedbc54d56ab24738..60fd8e054531aa080f7cc1740d6075664f3ffb18 100644 (file)
@@ -10,7 +10,7 @@
 **************************************************************************/
 
 /**
- * \file Network.hh
+ * \file Socket.hh
  * Network-related classes, including a reinterpreted sockets API.
  */
 
 #include <string>
 #include <vector>
 
+#if HAVE_FCNTL_H
+#include <fcntl.h>
+#else
+#error No alternative to fcntl implemented yet.
+#endif
+
 #if defined(_WIN32)
 #include <winsock2.h>
 #include <ws2tcpip.h>
 #include <wspiapi.h>
+#define SHUT_RD   SD_RECEIVE
+#define SHUT_WR   SD_SEND
+#define SHUT_RDWR SD_BOTH
 #else
 #include <arpa/inet.h>
 #include <netdb.h>
 #include <sys/socket.h>
 #include <sys/types.h>
-#if HAVE_FCNTL_H
-#include <fcntl.h>
-#else
-#include <sys/ioctl.h>
-#endif
 #endif
 
 #include <Moof/Log.hh>
 #include <Moof/Thread.hh>
 
 
-#ifndef SO_NONBLOCK
-#define SO_NONBLOCK 1024
+#ifndef AI_ADDRCONFIG
+#define AI_ADDRCONFIG 0
+#endif
+
+#ifndef AI_V4MAPPED
+#define AI_V4MAPPED 0
 #endif
 
 
@@ -95,9 +103,9 @@ public:
         * \param type The type of socket; either SOCK_STREAM or SOCK_DGRAM.
         * \param family The family; can be AF_INET or AF_INET6.
         */
-       SocketAddress(const std::string& service,
-                                 int type = SOCK_STREAM,
-                                 int family = AF_UNSPEC)
+       explicit SocketAddress(const std::string& service,
+                                                  int type = SOCK_STREAM,
+                                                  int family = AF_UNSPEC)
        {
                init(service, type, family);
        }
@@ -527,10 +535,10 @@ public:
         * \param family The family; can be AF_INET or AF_INET6.
         * \param flags The socket options.
         */
-       Socket(const std::string& service,
-                  int type = SOCK_STREAM,
-                  int family = AF_UNSPEC,
-                  int flags = 0) :
+       explicit Socket(const std::string& service,
+                                       int type = SOCK_STREAM,
+                                       int family = AF_UNSPEC,
+                                       int flags = 0) :
                mImpl(SocketAddress(service, type, family), flags) {}
 
 
@@ -636,7 +644,15 @@ public:
        template <class T>
        int set(int option, const T& value, int level = SOL_SOCKET)
        {
+#if defined(_WIN32)
+               return setsockopt(mImpl.fd,
+                                                 level,
+                                                 option,
+                                                 reinterpret_cast<const char*>(&value),
+                                                 sizeof(value));
+#else
                return setsockopt(mImpl.fd, level, option, &value, sizeof(value));
+#endif
        }
 
        /**
@@ -678,33 +694,49 @@ public:
                char            str[256] = {'\0'};
                socklen_t       size = sizeof(str);
 
+#if defined(_WIN32)
+               int result = getsockopt(mImpl.fd,
+                                                               level,
+                                                               option,
+                                                               reinterpret_cast<char*>(&str),
+                                                               &size);
+#else
                int result = getsockopt(mImpl.fd, level, option, &str, &size);
+#endif
                value.assign(str, size);
                return result;
        }
 
 
+       /**
+        * Set the socket IO mode to either blocking or non-blocking.
+        * \param isBlocking True if the socket blocks, false otherwise.
+        */
        void setBlocking(bool isBlocking)
        {
-               int value = isBlocking;
 #ifdef HAVE_FCNTL
                int flags = fcntl(mImpl.fd, F_GETFL);
-               fcntl(mImpl.fd, F_SETFL, flags | (value ? O_NONBLOCK : 0));
-#else
-               ioctl(mImpl.fd, FIONBIO, value);
+               flags = isBlocking ? (flags & ~O_NONBLOCK) : (flags | O_NONBLOCK);
+               fcntl(mImpl.fd, F_SETFL, flags);
+#elif defined(_WIN32)
+               u_long value = isBlocking;
+               ioctlsocket(mImpl.fd, FIONBIO, &value);
 #endif
        }
 
+       /**
+        * Get whether or not the socket is blocking or non-blocking.  If the
+        * IO mode can't be determined, this method will assume the socket is
+        * a blocking socket.
+        * \return True if the socket blocks, false otherwise.
+        */
        bool isBlocking() const
        {
 #ifdef HAVE_FCNTL
                int flags = fcntl(mImpl.fd, F_GETFL);
-               return flags & O_NONBLOCK;
-#else
-               int value;
-               ioctl(mImpl.fd, FIONBIO, &value);
-               return value;
+               return !(flags & O_NONBLOCK);
 #endif
+               return true;
        }
 
 
@@ -717,7 +749,13 @@ public:
         */
        ssize_t write(const void* bytes, size_t size, int flags = 0)
        {
+#if defined(_WIN32)
+               return send(mImpl.fd,
+                                       reinterpret_cast<const char *>(bytes), size,
+                                       flags);
+#else
                return send(mImpl.fd, bytes, size, flags);
+#endif
        }
 
        /**
@@ -729,11 +767,20 @@ public:
         * \param flags The send options.
         * \return The number of bytes written.
         */
-       ssize_t write(const void* bytes, size_t size,
-               const SocketAddress& address, int flags = 0)
+       ssize_t write(const void* bytes,
+                                 size_t size,
+                                 const SocketAddress& address,
+                                 int flags = 0)
        {
+#if defined(_WIN32)
+               return sendto(mImpl.fd,
+                                         reinterpret_cast<const char*>(bytes), size,
+                                         flags,
+                                         address.address(), address.size());
+#else
                return sendto(mImpl.fd, bytes, size, flags,
-                       address.address(), address.size());
+                                         address.address(), address.size());
+#endif
        }
 
        /**
@@ -755,8 +802,9 @@ public:
         * \param flags The send options.
         * \return The number of bytes written.
         */
-       ssize_t write(const Packet& packet, const SocketAddress& address,
-                       int flags = 0)
+       ssize_t write(const Packet& packet,
+                                 const SocketAddress& address,
+                                 int flags = 0)
        {
                return write(packet.bytes(), packet.size(), address, flags);
        }
@@ -771,7 +819,15 @@ public:
         */
        ssize_t read(void* bytes, size_t size, int flags = 0)
        {
-               return recv(mImpl.fd, bytes, size, flags);
+#if defined(_WIN32)
+               ssize_t result = recv(mImpl.fd,
+                                                         reinterpret_cast<char*>(bytes), size,
+                                                         flags);
+#else
+               ssize_t result = recv(mImpl.fd, bytes, size, flags);
+#endif
+               if (result == 0) mImpl.isConnected = false;
+               return result;
        }
 
        /**
@@ -783,8 +839,10 @@ public:
         * \param flags The recv options.
         * \return The number of bytes read.
         */
-       ssize_t read(void* bytes, size_t size, SocketAddress& address,
-                       int flags = 0)
+       ssize_t read(void* bytes,
+                                size_t size,
+                                SocketAddress& address,
+                                int flags = 0)
        {
                union
                {
@@ -793,12 +851,23 @@ public:
                } addr;
                socklen_t length = sizeof(addr);
 
+#if defined(_WIN32)
+               ssize_t result = recvfrom(mImpl.fd,
+                                                                 reinterpret_cast<char*>(bytes), size,
+                                                                 flags,
+                                                                 &addr.sa, &length);
+#else
                ssize_t result = recvfrom(mImpl.fd, bytes, size, flags,
-                               &addr.sa, &length);
+                                                                 &addr.sa, &length);
+#endif
                if (result != -1)
                {
                        address = SocketAddress(&addr.sa, length, mImpl.address.type());
                }
+               else if (result == 0)
+               {
+                       mImpl.isConnected = false;
+               }
                return result;
        }
 
@@ -910,7 +979,7 @@ public:
                                                                Packet&,
                                                                const SocketAddress&)> Function;
 
-       SocketMultiplexer(Socket sock) :
+       explicit SocketMultiplexer(Socket sock) :
                mSocket(sock) {}
 
 
This page took 0.026879 seconds and 4 git commands to generate.