diff --git a/inc/netlib.hpp b/inc/netlib.hpp index 0b039abf0ee4cf77e44854d29b5859f2dc02968a..7dfc681c11f0ea3694da36daa92e9f5a08cd2d08 100644 --- a/inc/netlib.hpp +++ b/inc/netlib.hpp @@ -7,5 +7,6 @@ #include "tcplistener.hpp" #include "udpsocket.hpp" #include "resolver.hpp" +#include "sockcopy.hpp" #endif // _NETLIB_HPP \ No newline at end of file diff --git a/inc/sockcopy.hpp b/inc/sockcopy.hpp new file mode 100644 index 0000000000000000000000000000000000000000..05899e6cc3f8db72650f3354e3c6cb229b54608b --- /dev/null +++ b/inc/sockcopy.hpp @@ -0,0 +1,138 @@ +#ifndef _SOCKCOPY_HPP +#define _SOCKCOPY_HPP + +#include "tcpstream.hpp" +#include "tcplistener.hpp" +#include "udpsocket.hpp" + +namespace netlib +{ + + +/** + * @brief A special wrapper type that can be used to create + * automatically copyable socket objects. Without wrapping + * socket objects in this class, an explicit clone function + * is needed to copy socket objects. + */ +template <class SockType> +class SockCopy +{ +private: + + /** + * @brief The wrapped socket instance. + */ + SockType socket; + +public: + + /** + * @brief Wrap the given socket so that it is copyable. + * + * @note Autoclose should most likely be set to false on + * the either one or both of the sockets to prevent accidentally + * closing the socket. + * + * @param socket The socket that will be wrapped. + */ + SockCopy(const SockType &socket) + : socket{std::move(socket.clone())} + { } + + /** + * @brief Wrap the given socket so that it is copyable. + * + * @param socket The socket that will be wrapped. + */ + SockCopy(SockType &&socket) + : socket{std::move(socket)} + { } + + /** + * @brief Copy the given wrapped socket. + * + * @note Autoclose should most likely be set to false on + * the either one or both of the sockets to prevent accidentally + * closing the socket. + * + * @param socket The warpped socket to copy. + */ + SockCopy(const SockCopy & other) + : SockCopy{std::move(other.socket.clone())} + { } + + /** + * @brief Copy the given wrapped socket. + * + * @note Autoclose should most likely be set to false on + * the either one or both of the sockets to prevent accidentally + * closing the socket. + * + * @param socket The warpped socket to copy. + */ + SockCopy & operator=(const SockCopy & other) + { + socket = std::move(other.socket.clone()); + } + + /** + * @brief Get the wrapped socket + */ + SockType & getSocket() + { + return socket; + } + + /** + * @brief Get the wrapped socket + */ + SockType & operator() () + { + return socket; + } + +}; + + +SockCopy<TcpStream> wrapCopy(TcpStream & other, bool disableAutoclose = true) +{ + if (disableAutoclose) other.setAutoclose(false); + return SockCopy<TcpStream>(other); +} + +SockCopy<TcpListener> wrapCopy(TcpListener & other, bool disableAutoclose = true) +{ + if (disableAutoclose) other.setAutoclose(false); + return SockCopy<TcpListener>(other); +} + +SockCopy<UdpSocket> wrapCopy(UdpSocket & other, bool disableAutoclose = true) +{ + if (disableAutoclose) other.setAutoclose(false); + return SockCopy<UdpSocket>(other); +} + + +SockCopy<TcpStream> wrapCopy(TcpStream && other, bool disableAutoclose = true) +{ + if (disableAutoclose) other.setAutoclose(false); + return SockCopy<TcpStream>(std::move(other)); +} + +SockCopy<TcpListener> wrapCopy(TcpListener && other, bool disableAutoclose = true) +{ + if (disableAutoclose) other.setAutoclose(false); + return SockCopy<TcpListener>(std::move(other)); +} + +SockCopy<UdpSocket> wrapCopy(UdpSocket && other, bool disableAutoclose = true) +{ + if (disableAutoclose) other.setAutoclose(false); + return SockCopy<UdpSocket>(std::move(other)); +} + + +} // namespace netlib + +#endif // _SOCKCOPY_HPP \ No newline at end of file