のbuffers引数として渡されるオブジェクトの場合async_read()
、buffers引数は次のいずれかです。
Sink
したがって、読み取りが発生したときにオブジェクトと対話するカスタムクラスを作成することができます。ただし、はboost::asio::basic_streambuf
基本クラスとして機能するように設計されているようには見えません。
Sink::write
が基になるメモリの抽象化にすぎない場合は、と同様のアプローチを使用することを検討してbasic_streambuf::prepare()
ください。ここで、メンバー関数は、指定されたサイズのバッファへのハンドルを返します。基盤となるメモリの実装は、の背後で抽象化されたままになりmutable_buffer
ます。例えば:
boost::asio::async_read( socket, sink.buffer( size ), ... );
Sink::write
特定のバイトの値に基づいてロジック分岐を実行するなどのビジネスロジックがある場合は、中間バッファをに渡す必要がある場合がありますasync_read()
。Sink::write()
中間バッファを使用したの呼び出しは、async_read()
のハンドラ内から実行されます。例えば:
void handle_read_into_sink( boost::system::error_code error,
std::size_t bytes_transferred,
boost::asio::ip::tcp::socket& socket,
Sink& sink,
char* buffer,
std::size_t buffer_size,
std::size_t bytes_remaining,
boost::function< void() > on_finish )
{
sink.write( buffer, buffer_size );
bytes_remaining -= bytes_transferred;
// If there are more bytes remaining, then continue reading.
if ( bytes_remaining )
{
read_into_sink( socket, sink, buffer, buffer_size,
bytes_remaining, on_finish );
}
// Otherwise, all data has been read.
else
{
on_finish();
}
}
void read_into_sink( boost::asio::ip::tcp::socket& socket,
Sink& sink,
char* buffer,
std::size_t buffer_size,
std::size_t bytes_remaining,
boost::function< void() > on_finish )
{
boost::asio::async_read(
socket, boost::asio::buffer( buffer , buffer_size ),
boost::asio::transfer_exactly( buffer_size ),
boost::bind( handle_read_into_sink,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred,
boost::ref( socket ),
boost::ref( sink ),
buffer,
buffer_size,
bytes_remaining,
on_finish ) );
}
そして、非同期読み取りループを次のように開始します。
read_into_sink( socket, sink, small_buffer, sizeof_small_buffer,
total_stream_size, read_handler_callback );
必要なロジックに基づいてエラーをチェックして処理してください。