diff --git a/tlib/include/tlib/net.hpp b/tlib/include/tlib/net.hpp index 1d7f04d9..98f2bcda 100644 --- a/tlib/include/tlib/net.hpp +++ b/tlib/include/tlib/net.hpp @@ -33,6 +33,54 @@ std::expected wait_for_packet(size_t socket_fd); std::expected wait_for_packet(size_t socket_fd, size_t ms); void release_packet(packet& packet); +struct socket { + socket(socket_domain domain, socket_type type, socket_protocol protocol); + ~socket(); + + /*! + * \brief Indicates if the socket is open or not + * \return true if the socket is open, false otherwise + */ + bool open() const ; + + /*! + * \brief Indicates if everything is in order + * \return true if everything is good, false otherwise + */ + bool good() const ; + + /*! + * \brief Indicates if everything is in order + * \return true if everything is good, false otherwise + */ + operator bool(); + + /*! + * \brief Returns the error code, if any + * \return the error code if any, 0 otherwise + */ + size_t error() const ; + + /*! + * \brief Clear the error code + */ + void clear(); + + void listen(bool l); + + packet prepare_packet(void* desc); + void finalize_packet(packet p); + packet wait_for_packet(); + packet wait_for_packet(size_t ms); + +private: + socket_domain domain; ///< The socket domain + socket_type type; ///< The socket type + socket_protocol protocol; ///< The socket protocol + size_t fd; ///< The socket file descriptor + size_t error_code; ///< The error code +}; + } // end of namespace tlib #endif diff --git a/tlib/src/net.cpp b/tlib/src/net.cpp index 499f56bc..c6879ee5 100644 --- a/tlib/src/net.cpp +++ b/tlib/src/net.cpp @@ -4,7 +4,6 @@ // (See accompanying file LICENSE or copy at // http://www.opensource.org/licenses/MIT) //======================================================================= - #include "tlib/net.hpp" #include "tlib/malloc.hpp" @@ -129,3 +128,106 @@ void tlib::release_packet(packet& packet){ free(packet.payload); } } + +tlib::socket::socket(socket_domain domain, socket_type type, socket_protocol protocol) : domain(domain), type(type), protocol(protocol), fd(0), error_code(0) { + auto open_status = tlib::socket_open(domain, type, protocol); + + if(open_status.valid()){ + fd = *open_status; + } else { + error_code = open_status.error(); + } +} + +tlib::socket::~socket(){ + if(fd){ + tlib::socket_close(fd); + } +} + +bool tlib::socket::open() const { + return fd > 0; +} + +bool tlib::socket::good() const { + return error_code == 0; +} + +tlib::socket::operator bool(){ + return good(); +} + +size_t tlib::socket::error() const { + return error_code; +} + +void tlib::socket::clear(){ + error_code = 0; +} + +void tlib::socket::listen(bool l){ + if(!good() || !open()){ + return; + } + + auto status = tlib::listen(fd, l); + if(!status){ + error_code = status.error(); + } +} + +tlib::packet tlib::socket::prepare_packet(void* desc){ + if(!good() || !open()){ + return tlib::packet(); + } + + auto packet = tlib::prepare_packet(fd, desc); + + if(!packet){ + error_code = packet.error(); + return tlib::packet(); + } else { + return *packet; + } +} + +void tlib::socket::finalize_packet(tlib::packet p){ + if(!good() || !open()){ + return; + } + + auto status = tlib::finalize_packet(fd, p); + if(!status){ + error_code = status.error(); + } +} + +tlib::packet tlib::socket::wait_for_packet(){ + if(!good() || !open()){ + return tlib::packet(); + } + + auto p = tlib::wait_for_packet(fd); + + if(!p){ + error_code = p.error(); + return tlib::packet(); + } else { + return *p; + } +} + +tlib::packet tlib::socket::wait_for_packet(size_t ms){ + if(!good() || !open()){ + return tlib::packet(); + } + + auto p = tlib::wait_for_packet(fd, ms); + + if(!p){ + error_code = p.error(); + return tlib::packet(); + } else { + return *p; + } +}