websocket read returns the number of bytes inserted (API Change):

* read and async_read now return the number of bytes inserted
into the caller's buffer.

Actions Required:

* Change the signature of completion handlers used with
  websocket::stream::async_read to void(error_code, std::size_t)
This commit is contained in:
Vinnie Falco
2017-07-25 08:50:58 -07:00
parent 6e33072832
commit e56d9955de
5 changed files with 69 additions and 52 deletions

View File

@ -16,6 +16,15 @@ Version 86:
* Fix Deferred Body Type Example Documentation
* Add library metadata
API Changes:
* websocket read returns the number of bytes inserted
Actions Required:
* Change the signature of completion handlers used with
websocket::stream::async_read to void(error_code, std::size_t)
--------------------------------------------------------------------------------
Version 85:

View File

@ -804,7 +804,7 @@ operator()(
template<class NextLayer>
template<class DynamicBuffer>
void
std::size_t
stream<NextLayer>::
read(DynamicBuffer& buffer)
{
@ -813,14 +813,15 @@ read(DynamicBuffer& buffer)
static_assert(beast::is_dynamic_buffer<DynamicBuffer>::value,
"DynamicBuffer requirements not met");
error_code ec;
read(buffer, ec);
auto const bytes_written = read(buffer, ec);
if(ec)
BOOST_THROW_EXCEPTION(system_error{ec});
return bytes_written;
}
template<class NextLayer>
template<class DynamicBuffer>
void
std::size_t
stream<NextLayer>::
read(DynamicBuffer& buffer, error_code& ec)
{
@ -828,18 +829,20 @@ read(DynamicBuffer& buffer, error_code& ec)
"SyncStream requirements not met");
static_assert(beast::is_dynamic_buffer<DynamicBuffer>::value,
"DynamicBuffer requirements not met");
std::size_t bytes_written = 0;
do
{
read_some(buffer, 0, ec);
bytes_written += read_some(buffer, 0, ec);
if(ec)
return;
return bytes_written;
}
while(! is_message_done());
return bytes_written;
}
template<class NextLayer>
template<class DynamicBuffer, class ReadHandler>
async_return_type<ReadHandler, void(error_code)>
async_return_type<ReadHandler, void(error_code, std::size_t)>
stream<NextLayer>::
async_read(DynamicBuffer& buffer, ReadHandler&& handler)
{
@ -848,15 +851,11 @@ async_read(DynamicBuffer& buffer, ReadHandler&& handler)
static_assert(beast::is_dynamic_buffer<DynamicBuffer>::value,
"DynamicBuffer requirements not met");
async_completion<
ReadHandler, void(error_code)> init{handler};
ReadHandler, void(error_code, std::size_t)> init{handler};
read_op<
DynamicBuffer,
beast::detail::bound_handler<
handler_type<ReadHandler, void(error_code)>,
decltype(std::placeholders::_1) &> >{
beast::bind_handler(
handler_type<ReadHandler, void(error_code, std::size_t)> >{
init.completion_handler,
std::placeholders::_1),
*this,
buffer,
0,

View File

@ -2835,43 +2835,46 @@ public:
//
//--------------------------------------------------------------------------
/** Read a message from the stream.
/** Read a complete message
This function is used to synchronously read a message from
the stream. The call blocks until one of the following is true:
This function is used to synchronously read a message from the stream.
The call blocks until one of the following is true:
@li A complete message is received.
@li A close frame is received. In this case the error indicated by
the function will be @ref error::closed.
@li An error occurs on the stream.
This call is implemented in terms of one or more calls to the
stream's `read_some` and `write_some` operations.
This operation is implemented in terms of one or more calls to the next
layer's `read_some` and `write_some` functions.
Upon a success, the input area of the stream buffer will
hold the received message payload bytes (which may be zero
in length). The functions @ref got_binary and @ref got_text
may be used to query the stream and determine the type
of the last received message.
Received message data, if any, is appended to the input area of the buffer.
The functions @ref got_binary and @ref got_text may be used to query
the stream and determine the type of the last received message.
During reads, the implementation handles control frames as
follows:
While this operation is active, the implementation will read incoming
control frames and handle them automatically as follows:
@li A pong frame is sent when a ping frame is received.
@li The @ref control_callback will be invoked for each control frame.
@li The @ref control_callback is invoked when a ping frame
or pong frame is received.
@li For each received ping frame, a pong frame will be automatically sent.
@li The WebSocket close procedure is started if a close frame
is received. In this case, the operation will eventually
complete with the error set to @ref error::closed.
@li If a close frame is received, the WebSocket close procedure is
performed. In this case, when the function returns, the error
@ref error::closed will be indicated.
@param buffer A dynamic buffer to hold the message data after
any masking or decompression has been applied.
@return The number of message payload bytes appended to the buffer.
@throws system_error Thrown on failure.
@param buffer A dynamic buffer to hold the message data after any
masking or decompression has been applied.
@throws system_error Thrown to indicate an error. The corresponding
error code may be retrieved from the exception object for inspection.
*/
template<class DynamicBuffer>
void
std::size_t
read(DynamicBuffer& buffer);
/** Read a message from the stream.
@ -2910,10 +2913,10 @@ public:
@param ec Set to indicate what error occurred, if any.
*/
template<class DynamicBuffer>
void
std::size_t
read(DynamicBuffer& buffer, error_code& ec);
/** Start an asynchronous operation to read a message from the stream.
/** Read a complete message asynchronously
This function is used to asynchronously read a message from
the stream. The function call always returns immediately. The
@ -2963,7 +2966,8 @@ public:
function signature of the handler must be:
@code
void handler(
error_code const& ec; // Result of operation
error_code const& ec, // Result of operation
std::size_t bytes_
);
@endcode
Regardless of whether the asynchronous operation completes
@ -2976,9 +2980,12 @@ public:
void_or_deduced
#else
async_return_type<
ReadHandler, void(error_code)>
ReadHandler,
void(error_code, std::size_t)>
#endif
async_read(DynamicBuffer& buffer, ReadHandler&& handler);
async_read(
DynamicBuffer& buffer,
ReadHandler&& handler);
//--------------------------------------------------------------------------

View File

@ -209,7 +209,7 @@ boost::asio::ip::tcp::socket sock{ios};
//[ws_snippet_20
multi_buffer buffer;
ws.async_read(buffer,
[](error_code)
[](error_code, std::size_t)
{
// Do something with the buffer
});

View File

@ -270,7 +270,7 @@ public:
template<
class NextLayer, class DynamicBuffer>
void
std::size_t
read(stream<NextLayer>& ws,
DynamicBuffer& buffer) const
{
@ -506,14 +506,16 @@ public:
template<
class NextLayer, class DynamicBuffer>
void
std::size_t
read(stream<NextLayer>& ws,
DynamicBuffer& buffer) const
{
error_code ec;
auto const bytes_written =
ws.async_read(buffer, yield_[ec]);
if(ec)
throw system_error{ec};
return bytes_written;
}
template<
@ -1342,7 +1344,7 @@ public:
// Read text message with bad utf8.
// Causes a close to be sent, blocking writes.
ws.async_read(db,
[&](error_code ec)
[&](error_code ec, std::size_t)
{
// Read should fail with protocol error
++count;
@ -1350,7 +1352,7 @@ public:
ec == error::failed, ec.message());
// Reads after failure are aborted
ws.async_read(db,
[&](error_code ec)
[&](error_code ec, std::size_t)
{
++count;
BOOST_BEAST_EXPECTS(ec == boost::asio::
@ -1409,7 +1411,7 @@ public:
// Read a close frame.
// Sends a close frame, blocking writes.
ws.async_read(db,
[&](error_code ec)
[&](error_code ec, std::size_t)
{
// Read should complete with error::closed
++count;
@ -1472,7 +1474,7 @@ public:
multi_buffer db;
std::size_t count = 0;
ws.async_read(db,
[&](error_code ec)
[&](error_code ec, std::size_t)
{
++count;
BOOST_BEAST_EXPECTS(ec == error::closed,
@ -1521,7 +1523,7 @@ public:
});
multi_buffer db;
ws.async_read(db,
[&](error_code ec)
[&](error_code ec, std::size_t)
{
BOOST_BEAST_EXPECTS(ec == error::closed, ec.message());
});