port new sockets stuff to winsock
authorCharles McGarvey <chazmcgarvey@brokenzipper.com>
Fri, 21 May 2010 17:44:17 +0000 (11:44 -0600)
committerCharles McGarvey <chazmcgarvey@brokenzipper.com>
Fri, 21 May 2010 17:44:17 +0000 (11:44 -0600)
src/Moof/Log.cc
src/Moof/Log.hh
src/Moof/Socket.hh

index 8656dc306a4531e4ea928cf3a645364f43708168..da7985d60115bff1bde22cc9557131f7059c6742 100644 (file)
@@ -26,7 +26,7 @@ void Log::setLevel(Level level)
        gLevel = level;
 }
 
-Log::Level Log::getLevel()
+Log::Level Log::level()
 {
        return gLevel;
 }
@@ -37,9 +37,9 @@ std::ostream& log(std::clog);
 static std::ofstream nullLog_;
 std::ostream& nullLog(nullLog_);
 
-Log logError(Log::ERRORR, "  error: ");
+Log logError(  Log::ERRORR,  "  error: ");
 Log logWarning(Log::WARNING, "warning: ");
-Log logInfo(Log::INFO, "   info: ");
+Log logInfo(   Log::INFO,    "   info: ");
 
 
 static int logScript_(Script& script, Log::Level level)
index 324fdeed8555b0c747c1fd8eecacae903496cac7..c09ac017690600fb302cb79a382a5ef55b24750e 100644 (file)
@@ -13,7 +13,7 @@
 #define _MOOF_LOG_H_
 
 /**
- * @file log.h
+ * \file Log.h
  * Functions related to logging the process.
  * The logging functions are logError(), logWarning(), and logInfo(),
  * listed from most critical to least critical.
@@ -24,9 +24,9 @@
 
 
 /**
- * Macro which tests an assertion and issues an logError() and exits if
- * false.
- * @param X test to perform
+ * Macro which tests an assertion and issues a logError() and exits if the
+ * assertion is false.
+ * \param X test to perform
  */
 
 #undef ASSERT
 namespace Mf {
 
 
+/**
+ * A class for handling a log priority.  There are two ways to log
+ * messages: by treating a log object as a function whose parameters are
+ * printed with default spacing, or by treating a log object as an output
+ * stream.  Either way, any object can be printed to the log as long as
+ * there is an override for the ostream insertion operator.
+ */
 class Log
 {
 public:
 
+       /**
+        * A type for the level or priority of a log message.
+        */
        enum Level
        {
                NONE            = 0,            ///< Disable all logging.
@@ -55,21 +65,71 @@ public:
                INFO            = 3,            ///< Log everything.
        };
 
+
+       /**
+        * Set the lowest-priority log message that will be outputted to the
+        * log.  Any logging with a lower priority will be ignored.
+        * \param level The log level.
+        */
        static void setLevel(Level level);
-       static Level getLevel();
 
+       /**
+        * Get the current lowest-priority log level.  If unchanged, the
+        * default level is INFO.
+        * \return The log level.
+        */
+       static Level level();
 
-       Log(Level level, const char* type) :
+
+       /**
+        * Construct a log with a certain priority and prefix string.
+        * \param level The log level.
+        * \param prefix The string printed before each log message.
+        */
+       Log(Level level, const char* prefix) :
                mLevel(level),
-               mType(type) /* only pass literal strings */ {}
+               mPrefix(prefix) /* only pass literal strings */ {}
 
 
-       template <class T>
-       void operator () (const T& item)
+       template <class A>
+       void operator () (const A& a)
        {
-               *this << item << std::endl;
+               *this << a << std::endl;
        }
 
+       template <class A, class B>
+       void operator () (const A& a, const B& b)
+       {
+               *this << a << " " << b << std::endl;
+       }
+
+       template <class A, class B, class C>
+       void operator () (const A& a, const B& b, const C& c)
+       {
+               *this << a << " " << b << " " << c << std::endl;
+       }
+
+       template <class A, class B, class C, class D>
+       void operator () (const A& a, const B& b, const C& c, const D& d)
+       {
+               *this << a << " " << b << " " << c << " " << d << std::endl;
+       }
+
+       template <class A, class B, class C, class D, class E>
+       void operator () (const A& a,
+                                         const B& b,
+                                         const C& c,
+                                         const D& d,
+                                         const E& e)
+       {
+               *this << a << " "
+                         << b << " "
+                         << c << " "
+                         << d << " "
+                         << e << std::endl;
+       }
+
+
 private:
 
        template <class T> friend std::ostream& operator << (Log&, const T&);
@@ -77,7 +137,7 @@ private:
        static Level    gLevel;
 
        Level                   mLevel;
-       const char*             mType;
+       const char*             mPrefix;
 };
 
 
@@ -93,7 +153,7 @@ template <class T>
 inline std::ostream& operator << (Log& logObj, const T& item)
 {
        if (Log::gLevel < logObj.mLevel) return nullLog;
-       return log << logObj.mType << item;
+       return log << logObj.mPrefix << item;
 }
 
 
index cc47f32ee41cf46f5c8bd38a8e9363fbc4e1171c..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
 
 
@@ -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
        }
 
        /**
@@ -734,8 +772,15 @@ public:
                                  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());
+#endif
        }
 
        /**
@@ -774,7 +819,13 @@ public:
         */
        ssize_t read(void* bytes, size_t size, int flags = 0)
        {
+#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;
        }
@@ -800,8 +851,15 @@ 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());
This page took 0.030439 seconds and 4 git commands to generate.