diff --git a/CHANGELOG.md b/CHANGELOG.md index 25550a86..8468ca02 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ Version 83: * Add wstest compression option * Turn some flat_static_buffer_tests on * Documentation work +* read_some, async_read_some return bytes used WebSocket diff --git a/include/beast/http/impl/read.ipp b/include/beast/http/impl/read.ipp index 08e7c552..9201b593 100644 --- a/include/beast/http/impl/read.ipp +++ b/include/beast/http/impl/read.ipp @@ -41,6 +41,7 @@ class read_some_op basic_parser& p_; boost::optional mb_; + std::size_t used_ = 0; Handler h_; public: @@ -136,10 +137,14 @@ operator()(error_code ec, std::size_t bytes_transferred) b_.commit(bytes_transferred); do_parse: - b_.consume(p_.put(b_.data(), ec)); + { + auto const used = p_.put(b_.data(), ec); + used_ += used; + b_.consume(used); if(! ec || ec != http::error::need_more) goto do_upcall; ec.assign(0, ec.category()); + } do_read: try @@ -165,7 +170,7 @@ operator()(error_code ec, std::size_t bytes_transferred) break; } upcall: - h_(ec); + h_(ec, used_); } //------------------------------------------------------------------------------ @@ -219,7 +224,8 @@ public: } void - operator()(error_code ec); + operator()( + error_code ec, std::size_t bytes_used = 0); friend void* asio_handler_allocate( @@ -264,7 +270,7 @@ template:: -operator()(error_code ec) +operator()(error_code ec, std::size_t) { switch(state_) { @@ -343,7 +349,8 @@ public: } void - operator()(error_code ec); + operator()( + error_code ec, std::size_t bytes_used = 0); friend void* asio_handler_allocate( @@ -388,7 +395,7 @@ template:: -operator()(error_code ec) +operator()(error_code ec, std::size_t) { auto& d = *d_; switch(d.state) @@ -424,7 +431,7 @@ template< class SyncReadStream, class DynamicBuffer, bool isRequest, class Derived> -void +std::size_t read_some( SyncReadStream& stream, DynamicBuffer& buffer, @@ -436,16 +443,18 @@ read_some( "DynamicBuffer requirements not met"); BOOST_ASSERT(! parser.is_done()); error_code ec; - read_some(stream, buffer, parser, ec); + auto const bytes_used = read_some( + stream, buffer, parser, ec); if(ec) BOOST_THROW_EXCEPTION(system_error{ec}); + return bytes_used; } template< class SyncReadStream, class DynamicBuffer, bool isRequest, class Derived> -void +std::size_t read_some( SyncReadStream& stream, DynamicBuffer& buffer, @@ -457,16 +466,21 @@ read_some( static_assert(is_dynamic_buffer::value, "DynamicBuffer requirements not met"); BOOST_ASSERT(! parser.is_done()); + std::size_t bytes_used = 0; if(buffer.size() == 0) goto do_read; for(;;) { // invoke parser - buffer.consume(parser.put(buffer.data(), ec)); - if(! ec) - break; - if(ec != http::error::need_more) - break; + { + auto const used = parser.put(buffer.data(), ec); + bytes_used += used; + buffer.consume(used); + if(! ec) + break; + if(ec != http::error::need_more) + break; + } do_read: boost::optional b; @@ -478,7 +492,7 @@ read_some( catch(std::length_error const&) { ec = error::buffer_overflow; - return; + return bytes_used; } auto const bytes_transferred = stream.read_some(*b, ec); @@ -501,6 +515,7 @@ read_some( break; buffer.commit(bytes_transferred); } + return bytes_used; } template< @@ -509,7 +524,7 @@ template< bool isRequest, class Derived, class ReadHandler> async_return_type< - ReadHandler, void(error_code)> + ReadHandler, void(error_code, std::size_t)> async_read_some( AsyncReadStream& stream, DynamicBuffer& buffer, diff --git a/include/beast/http/read.hpp b/include/beast/http/read.hpp index 72fea92f..e5cabc63 100644 --- a/include/beast/http/read.hpp +++ b/include/beast/http/read.hpp @@ -56,13 +56,15 @@ namespace http { @param parser The parser to use. + @return The number of bytes consumed by the parser. + @throws system_error Thrown on failure. */ template< class SyncReadStream, class DynamicBuffer, bool isRequest, class Derived> -void +std::size_t read_some( SyncReadStream& stream, DynamicBuffer& buffer, @@ -112,12 +114,14 @@ read_some( @param parser The parser to use. @param ec Set to the error, if any occurred. + + @return The number of bytes consumed by the parser. */ template< class SyncReadStream, class DynamicBuffer, bool isRequest, class Derived> -void +std::size_t read_some( SyncReadStream& stream, DynamicBuffer& buffer, @@ -172,7 +176,8 @@ read_some( completes. Copies will be made of the handler as required. The equivalent function signature of the handler must be: @code void handler( - error_code const& error // result of operation + error_code const& error, // result of operation + std::size_t bytes_used // the number of bytes consumed by the parser ); @endcode Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within @@ -193,7 +198,7 @@ template< void_or_deduced #else async_return_type< - ReadHandler, void(error_code)> + ReadHandler, void(error_code, std::size_t)> #endif async_read_some( AsyncReadStream& stream,