#include "Socket/Socket.hpp" #include "Socket/Log.hpp" #include "precomp.hpp" namespace Chattr { Socket::Socket(int domain, int type, int protocol) { init(domain, type, protocol); } Socket::~Socket() { destruct(); } void Socket::init(int domain, int type, int protocol) { if (domain == AF_INET) bindAddr.length = sizeof(sockaddr_in); else if (domain == AF_INET6) bindAddr.length = sizeof(sockaddr_in6); sock_ = ::socket(domain, type, protocol); if (sock_ == INVALID_SOCKET) log::critical("socket()"); valid_ = true; } void Socket::destruct() { if (!valid_) return; #ifdef _WIN32 ::closesocket(sock_); #elif __linux__ ::close(sock_); #endif } Socket::operator SOCKET() const { if (valid_) return sock_; spdlog::critical("No valid socket created."); return INVALID_SOCKET; } void Socket::set(const SOCKET __sock) { if (__sock == INVALID_SOCKET) log::critical("socket()"); destruct(); sock_ = __sock; valid_ = true; }; void Socket::bind(sockaddr *__addr) { bind((struct sockaddr *)__addr, sizeof(sockaddr)); } void Socket::bind(sockaddr *__addr, socklen_t __len) { bindAddr.length = __len; std::memcpy(&bindAddr, __addr, __len); int retVal = ::bind(sock_, __addr, __len); if (retVal == INVALID_SOCKET) log::critical("bind()"); } void Socket::bind(sockaddr_in *__addr) { bind((struct sockaddr *)__addr, sizeof(sockaddr_in)); } void Socket::bind(sockaddr_in *__addr, socklen_t __len) { bind((struct sockaddr *)__addr, __len); } void Socket::bind(sockaddr_in6 *__addr) { bind((struct sockaddr *)__addr, sizeof(sockaddr_in6)); } void Socket::bind(sockaddr_in6 *__addr, socklen_t __len) { bind((struct sockaddr *)__addr, __len); } int Socket::recvfrom(void *__restrict __buf, size_t __n, int __flags, struct Address& __addr) { int retVal = ::recvfrom(sock_, __buf, __n, __flags, &__addr.addr, &__addr.length); if (retVal == SOCKET_ERROR) log::error("recvfrom()"); return retVal; } int Socket::sendto(const void *__buf, size_t __n, int __flags, struct Address __addr) { int retVal = ::sendto(sock_, __buf, __n, __flags, &__addr.addr, __addr.length); if (retVal == SOCKET_ERROR) log::error("sendto()"); return retVal; } Socket::Socket(Socket &&other_) { other_.valid_ = false; sock_ = other_.sock_; valid_ = true; } Socket& Socket::operator=(Socket && other_) { other_.valid_ = false; sock_ = other_.sock_; valid_ = true; return *this; } }