From 2a5d960e569db8ea3cd5ed40d82ddd47d815c129 Mon Sep 17 00:00:00 2001 From: Fred Nicolson Date: Tue, 27 Dec 2016 21:58:39 +0000 Subject: [PATCH] Added fr::Socket::has_data to check if recv buffer is empty If using a SocketSelector, you should keep accepting data from the socket until has_data returns false, indicating that you've read everything. --- include/frnetlib/SSLSocket.h | 8 ++++++++ include/frnetlib/Socket.h | 8 ++++++++ include/frnetlib/TcpListener.h | 1 + include/frnetlib/TcpSocket.h | 13 ++++++++++++- src/SSLSocket.cpp | 5 +++++ src/TcpSocket.cpp | 5 +++++ 6 files changed, 39 insertions(+), 1 deletion(-) diff --git a/include/frnetlib/SSLSocket.h b/include/frnetlib/SSLSocket.h index 54d317e..27e6f2a 100644 --- a/include/frnetlib/SSLSocket.h +++ b/include/frnetlib/SSLSocket.h @@ -98,6 +98,14 @@ namespace fr abort(); } + /*! + * Checks to see if there's data still in the socket's + * recv buffer. + * + * @return True if there is data in the buffer, false otherwise. + */ + virtual bool has_data() const override; + private: std::string unprocessed_buffer; std::unique_ptr recv_buffer; diff --git a/include/frnetlib/Socket.h b/include/frnetlib/Socket.h index 2cbdcf9..af384c8 100644 --- a/include/frnetlib/Socket.h +++ b/include/frnetlib/Socket.h @@ -146,6 +146,14 @@ namespace fr */ void shutdown(); + /*! + * Checks to see if there's data still in the socket's + * recv buffer. + * + * @return True if there is data in the buffer, false otherwise. + */ + virtual bool has_data() const = 0; + protected: std::string remote_address; bool is_blocking; diff --git a/include/frnetlib/TcpListener.h b/include/frnetlib/TcpListener.h index a84120e..d5c54d5 100644 --- a/include/frnetlib/TcpListener.h +++ b/include/frnetlib/TcpListener.h @@ -45,6 +45,7 @@ private: virtual fr::Socket::Status send_raw(const char*, size_t){return Socket::Error;} virtual fr::Socket::Status receive_raw(void*, size_t, size_t&){return Socket::Error;} virtual int32_t get_socket_descriptor() const {return socket_descriptor;} + virtual bool has_data() const override {return false;}; }; } diff --git a/include/frnetlib/TcpSocket.h b/include/frnetlib/TcpSocket.h index 56a4f72..43c4e78 100644 --- a/include/frnetlib/TcpSocket.h +++ b/include/frnetlib/TcpSocket.h @@ -18,7 +18,10 @@ class TcpSocket : public Socket public: TcpSocket() noexcept; virtual ~TcpSocket() noexcept; - TcpSocket(TcpSocket &&) noexcept = default; + TcpSocket(TcpSocket &&other) noexcept + : unprocessed_buffer(std::move(other.unprocessed_buffer)), + recv_buffer(std::move(other.recv_buffer)), + socket_descriptor(other.socket_descriptor){} void operator=(const TcpSocket &other)=delete; /*! @@ -92,6 +95,14 @@ public: */ int32_t get_socket_descriptor() const override; + /*! + * Checks to see if there's data still in the socket's + * recv buffer. + * + * @return True if there is data in the buffer, false otherwise. + */ + virtual bool has_data() const override; + protected: std::string unprocessed_buffer; std::unique_ptr recv_buffer; diff --git a/src/SSLSocket.cpp b/src/SSLSocket.cpp index 8d307b8..782fba0 100644 --- a/src/SSLSocket.cpp +++ b/src/SSLSocket.cpp @@ -168,6 +168,11 @@ namespace fr is_connected = true; ssl_socket_descriptor = std::move(context); } + + bool SSLSocket::has_data() const + { + return !unprocessed_buffer.empty(); + } } #endif \ No newline at end of file diff --git a/src/TcpSocket.cpp b/src/TcpSocket.cpp index 732be2d..ead70d3 100644 --- a/src/TcpSocket.cpp +++ b/src/TcpSocket.cpp @@ -159,4 +159,9 @@ namespace fr { return socket_descriptor; } + + bool TcpSocket::has_data() const + { + return !unprocessed_buffer.empty(); + } } \ No newline at end of file