From 8c6a82feb045ac859b344cd7665a36ac00f4949e Mon Sep 17 00:00:00 2001 From: Charles McGarvey Date: Fri, 21 May 2010 11:44:17 -0600 Subject: [PATCH] port new sockets stuff to winsock --- src/Moof/Log.cc | 6 +-- src/Moof/Log.hh | 84 +++++++++++++++++++++++++++++++++++------ src/Moof/Socket.hh | 94 +++++++++++++++++++++++++++++++++++++--------- 3 files changed, 151 insertions(+), 33 deletions(-) diff --git a/src/Moof/Log.cc b/src/Moof/Log.cc index 8656dc3..da7985d 100644 --- a/src/Moof/Log.cc +++ b/src/Moof/Log.cc @@ -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) diff --git a/src/Moof/Log.hh b/src/Moof/Log.hh index 324fdee..c09ac01 100644 --- a/src/Moof/Log.hh +++ b/src/Moof/Log.hh @@ -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 @@ -43,10 +43,20 @@ 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 - void operator () (const T& item) + template + void operator () (const A& a) { - *this << item << std::endl; + *this << a << std::endl; } + template + void operator () (const A& a, const B& b) + { + *this << a << " " << b << std::endl; + } + + template + void operator () (const A& a, const B& b, const C& c) + { + *this << a << " " << b << " " << c << std::endl; + } + + template + void operator () (const A& a, const B& b, const C& c, const D& d) + { + *this << a << " " << b << " " << c << " " << d << std::endl; + } + + template + 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 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 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; } diff --git a/src/Moof/Socket.hh b/src/Moof/Socket.hh index cc47f32..60fd8e0 100644 --- a/src/Moof/Socket.hh +++ b/src/Moof/Socket.hh @@ -10,7 +10,7 @@ **************************************************************************/ /** - * \file Network.hh + * \file Socket.hh * Network-related classes, including a reinterpreted sockets API. */ @@ -24,20 +24,24 @@ #include #include +#if HAVE_FCNTL_H +#include +#else +#error No alternative to fcntl implemented yet. +#endif + #if defined(_WIN32) #include #include #include +#define SHUT_RD SD_RECEIVE +#define SHUT_WR SD_SEND +#define SHUT_RDWR SD_BOTH #else #include #include #include #include -#if HAVE_FCNTL_H -#include -#else -#include -#endif #endif #include @@ -45,8 +49,12 @@ #include -#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 int set(int option, const T& value, int level = SOL_SOCKET) { +#if defined(_WIN32) + return setsockopt(mImpl.fd, + level, + option, + reinterpret_cast(&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(&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(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(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(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(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()); -- 2.45.2