/* * @file Socket.h * @brief Abstract class to perform API global operations * * @author Mohamed Amine Mzoughi * @date 2017-02-10 */ #ifndef INCLUDE_ASOCKET_H_ #define INCLUDE_ASOCKET_H_ #if defined (_WIN32) && !defined (WINDOWS) #define WINDOWS #endif #include // snprintf #include #include #include #include // va_start, etc. #include #ifdef WINDOWS #include #include // Need to link with Ws2_32.lib #pragma comment(lib,"WS2_32.lib") #else #include #include #include #include #include #include #include #include #include #include #include #endif #include #define ACCEPT_WAIT_INF_DELAY std::numeric_limits::max() class ASocket { public: // Public definitions //typedef std::function ProgressFnCallback; typedef std::function LogFnCallback; // socket file descriptor id #ifdef WINDOWS typedef SOCKET Socket; #else typedef int Socket; #define INVALID_SOCKET -1 #endif enum SettingsFlag { NO_FLAGS = 0x00, ENABLE_LOG = 0x01, ALL_FLAGS = 0xFF }; /* Please provide your logger thread-safe routine, otherwise, you can turn off * error log messages printing by not using the flag ALL_FLAGS or ENABLE_LOG */ explicit ASocket(const LogFnCallback& oLogger, const SettingsFlag eSettings = ALL_FLAGS); virtual ~ASocket() = 0; static int SelectSockets(const Socket* pSocketsToSelect, const size_t count, const size_t msec, size_t& selectedIndex); static int SelectSocket(const Socket sd, const size_t msec); static struct timeval TimevalFromMsec(unsigned int time_msec); // String Helpers static std::string StringFormat(const std::string strFormat, ...); protected: // Log printer callback /*mutable*/const LogFnCallback m_oLog; SettingsFlag m_eSettingsFlags; #ifdef WINDOWS static WSADATA s_wsaData; #endif private: friend class SocketGlobalInitializer; class SocketGlobalInitializer { public: static SocketGlobalInitializer& instance(); SocketGlobalInitializer(SocketGlobalInitializer const&) = delete; SocketGlobalInitializer(SocketGlobalInitializer&&) = delete; SocketGlobalInitializer& operator=(SocketGlobalInitializer const&) = delete; SocketGlobalInitializer& operator=(SocketGlobalInitializer&&) = delete; ~SocketGlobalInitializer(); private: SocketGlobalInitializer(); }; SocketGlobalInitializer& m_globalInitializer; }; class EResolveError : public std::logic_error { public: explicit EResolveError(const std::string &strMsg) : std::logic_error(strMsg) {} }; #endif