7

consumer() と commit() が実際に何を意味するのかについての良い説明が見つからないようです。実際には、streambuf をまったく理解していません。

私の理解では、streambuf は単なる文字配列です。しかし、なぜそれがドキュメントにあるのですか、

basic_streambuf::data
Get a list of buffers that represents the input sequence.

実際には多くのバッファがありますか?そして、「入力シーケンス」と「出力シーケンス」とは何ですか? これらは別の 2 つのバッファーですか?

次のコードは実際に何をしますか?

streambuf b;
size_t size;
size = read( socket, b.prepare( 1024 ) ); 
b.commit( size );
size = write( socket, b.data() );
b.consume( size );

b.prepare() を呼び出すと、read() がデータを配置するための新しいバッファが割り当てられますか? では、データがそのバッファから基になる streambuf バッファに転送されるのはいつですか? commit()かと思ったのですが、

basic_streambuf::commit
Move characters from the output sequence to the input sequence.

そのため、コミットは実際にデータを「出力シーケンス」から「入力シーケンス」に移動するように見えますが、データを格納するために使用される基礎となるバッファーについて言及することはありません!

4

1 に答える 1

7

Boost ASIO streambuf は単なる文字配列ではありません。basic_streambuf ドキュメントから:

basic_streambuf クラスは std::streambuf から派生し、streambuf の入力および出力シーケンスを 1 つ以上の文字配列に関連付けます。これらの文字配列は、basic_streambuf オブジェクトの内部にありますが、I/O 操作で効率的に使用できるように、配列要素への直接アクセスが提供されています。basic_streambuf オブジェクトの出力シーケンスに書き込まれた文字は、同じオブジェクトの入力シーケンスに追加されます。

ドキュメントでは、可能な実装戦略について説明しています。streambuf オブジェクトは、入力シーケンスと出力シーケンスを管理するために、ポインターを含む 1 つの連続した文字配列を使用するだけです。しかし、インターフェースはより複雑なスキームを可能にします。

コード スニペットが実際に何をするのかを尋ねましたが、これは基になる実装によって異なります。つまり、 prepare() は、基礎となるバッファーが、入れようとしているものを保持するのに十分な大きさであることを保証します。また、mutuable_buffers オブジェクトを介してバッファにアクセスすることもできます。データが streambuf に書き込まれると (おそらく、読み取りハンドラーが呼び出されると)、commit() はそのデータを入力シーケンスで使用できるようにします。これらのバイトには、data() を使用してアクセスできます。バッファー内のデータの処理が終了した後 (コピーしたり処理したりしたため)、consume() は入力シーケンスからデータを削除します。data() への後続の呼び出しには、前の呼び出しからのバイトが含まれません。

また、データを格納するために使用される基になるバッファーについては言及されていないと主張しましたが、それは正しいです。実際のデータを格納する方法を決定するのは、ASIO の作成者次第です。

于 2014-12-04T20:52:03.023 に答える