おおよそ正しいように聞こえますが、何をしているのかはあまり明確ではありません。念のため:ostream
を作成してインストールするための便利なコンストラクタstreambuf
、デストラクタ、およびrdbuf
適切なタイプのバッファを処理するための の実装を提供するだけです。xsputn
それが正しいと仮定すると、 yourでの定義streambuf
は純粋に最適化です。定義しなければならない重要な機能はoverflow
. の最も単純な実装overflow
は、単一の文字を取り、それをシンクに出力します。それを超えるものはすべて最適化です。たとえば、を使用してバッファを設定できsetp
ます。これを行うoverflow
と、バッファがいっぱいになったとき、またはフラッシュが要求されたときにのみ呼び出されます。この場合、バッファも出力する必要があります (使用pbase
してpptr
アドレスを取得します)。(streambuf
基本クラスはポインタを初期化して長さ 0 のバッファを作成するためoverflow
、すべての文字に対して呼び出されます。) (非常に) 特定のケースでオーバーライドしたいその他の関数:
imbue
: 何らかの理由でロケールが必要な場合。(現在の文字エンコーディングはロケールの一部であることに注意してください。)
setbuf
: クライアント コードでバッファを指定できるようにします。(私見、通常はわざわざする価値はありませんが、特別な要件がある場合があります。)
seekoff
: シークのサポート。私はこれを自分streambuf
の s で使用したことがないので、標準で読み取れる以上の情報を提供することはできません。
sync
: フラッシュ時に呼び出され、バッファ内のすべての文字をシンクに出力する必要があります。呼び出しを行わないsetp
(つまりバッファーがない) 場合は、常に同期しているため、操作を行わない可能性があります。
overflow
またはuflow
これを呼び出すか、両方で別の関数を呼び出すことができます。( と の唯一の違いはsync
、uflow
はuflow
バッファがある場合にのみ呼び出され、バッファが空の場合は呼び出されないことです。
sync
は、クライアント コードがストリームをフラッシュした場合に呼び出されます。)
独自のストリームを作成するときは、パフォーマンスが別の方法で指示しない限り、シンプルに保ち、オーバーライドのみを行いますoverflow
。パフォーマンスがバッファを決定する場合、通常、バッファをフラッシュするコードを別の関数に配置し、次の行に沿ってwrite(address, length)
実装overflow
します。sync
int MyStreambuf::overflow( int ch )
{
if ( pbase() == NULL ) {
// save one char for next overflow:
setp( buffer, buffer + bufferSize - 1 );
if ( ch != EOF ) {
ch = sputc( ch );
} else {
ch = 0;
}
} else {
char* end = pptr();
if ( ch != EOF ) {
*end ++ = ch;
}
if ( write( pbase(), end - pbase() ) == failed ) {
ch = EOF;
} else if ( ch == EOF ) {
ch = 0;
}
setp( buffer, buffer + bufferSize - 1 );
}
return ch;
}
int sync()
{
return (pptr() == pbase()
|| write( pbase(), pptr() - pbase() ) != failed)
? 0
: -1;
}
通常、私は気にしませんxsputn
が、クライアント コードが多くの長い文字列を出力している場合は、役に立つ可能性があります。このような何かがうまくいくはずです:
streamsize xsputn(char const* p, streamsize n)
{
streamsize results = 0;
if ( pptr() == pbase()
|| write( pbase(), pptr() - pbase() ) != failed ) {
if ( write(p, n) != failed ) {
results = n;
}
}
setp( buffer, buffer + bufferSize - 1 );
return results;
}