SBUFPUB(3CC4)

名前
sbufpub - ストリームバッファ基底クラスの公開バッファ

形式

#include <iostream.h>

typedef long streampos;
typedef long streamoff;

class ios : virtual public unsafe_ios, public stream_MT {
public:
        enum open_mode  {
            in       = 0x01,    // 読み取り用にオープン
            out      = 0x02,    // 書き込み用にオープン
            ate      = 0x04,    // EOF までシークする
            app      = 0x08,    // 追加モード: EOF 以降に追加
            trunc    = 0x10,    // ファイルがあれば内容をクリア
            nocreate = 0x20,    // ファイルがなければオープンを失敗させる
            noreplace= 0x40     // ファイルがあればオープンを失敗させる
        };
        // ストリームのシーク方向
        enum seek_dir { beg=0, cur=1, end=2 };

	// 残りの部分については ios(3CC4) を参照 ...
};

class streambuf : public stream_MT {
public:
        int             in_avail();
        int             out_waiting();
        int             sbumpc();
        streambuf*      setbuf(char* ptr, int len);
        streampos       seekpos(streampos, int =ios::in|ios::out);
        streampos       seekoff(streamoff, seek_dir, int =ios::in|ios::out);
        int             sgetc();
        int             sgetn(char* ptr, int n);
        int             snextc();
        int             sputbackc(char);
        int             sputc(int c);
        int             sputn(const char* s, int n);
        void            stossc();
        virtual int     sync();

        int             in_avail_unlocked();
        int             out_waiting_unlocked();
        int             sbumpc_unlocked();
        int             sgetc_unlocked();
        int             sgetn_unlocked(char* ptr, int n);
        int             snextc_unlocked();
        int             sputbackc_unlocked(char);
        int             sputc_unlocked(int c);
        int             sputn_unlocked(const char* s, int n);
        void            stossc_unlocked();
};

機能説明

クラス streambuf はバッファクラスの基本的な機能を定義するもので、 このクラスから実際のバッファクラスを派生します。 この公開インタフェースは、 どのストリームクラスからでもそのバッファ関連の機能を 実行するときに呼び出す必要がある関数を表します。 streambuf 型のオブジェクトを作成する必要はありません。 むしろ、バッファオブジェクトのクラスの型は、 streambuf から派生したものでなければなりません。 そのような派生に必要な限定公開インタフェースについては、 sbufprot(3CC4) を参照してください。

環境

streambuf を MT-safe、すなわちマルチスレッド環境で正しく機能するようにするため、 公開メンバー関数のそれぞれにロックが使用されています。 パフォーマンスが重要になるシングルスレッドのアプリケーションのために、 各関数にロックを使用しないバージョンが導入されました。 ロックを使用しない関数は、オリジナルの関数名に _unlocked という接尾辞が付いています。 マルチスレッド環境で使用できない (MT-unsafe) であることを除き、 ロックを使用しない関数は それぞれのオリジナルの関数と同じ機能を持ちます。 詳細については、 MT-Safe libC Programmer's Guide を参照してください。

クラス streambuf は、抽象バッファクラスをサポートします。 論理的には、文字の列と、 格納またはフェッチ、またはその両方が行われる 次の文字の場所を定義する 1 つまたは 2 つのポインタで構成されます。 入力 (または出力) だけを目的にしたバッファクラスは、 get (または put ) ポインタの一方しか持っていません。 入出力の両方を目的にしたバッファクラスは両方のポインタを持っています。

入力ポインタと出力ポインタは、 列の中の各文字の間を指していると考えてください。 入力バッファから次に取り出す文字は、 入力ポインタのすぐ後ろの文字です。 出力ストリームに置かれている次の文字は、 出力ポインタのすぐ後ろに格納されます。 ポインタは、 列の先頭では先頭の文字のすぐ前を指し、 列の終端では最後の文字のすぐ後ろを指します。

複数の異なるデバイスを使用する場合は、 異なる方法を用いた複数の種類のバッファ (確保領域ともいう) が 存在することがあります。 strstreambuf( ssbuf(3CC4) 参照) などの「キュー」型バッファは、 入力ポインタと出力ポインタを別々に持っています。 strstreambuf はメモリー内の文字配列であり、 格納 (出力) とフェッチ (入力) を任意の場所で行うことができます。 filebuf( filebuf(3CC4) 参照) などの「ファイル」型バッファは、 入力操作と出力操作の両方が行われる場合がありますが、 実質上は 1 つのポインタしか持っていません。 次の入力または出力は、 必ず現在の位置で行われます (実際には 2 つのポインタが存在する場合も ありますが、その場合でも 2 つのポインタは必ず同じ位置を指します)。

streambuf は文字配列をバッファとして使用し、 空の入力バッファにデータを入れたり、 フル状態になった出力バッファをフラッシュする場合は 関数を呼び出します (詳細については sbufprot(3CC4) を参照)。 通常、できるだけ効率を高めるために、 格納、フェッチ、ポインタ操作を行う関数はインラインにします。 これらの関数について、以下に示します。

  入力関数

int c = sbuf.sgetc()
    入力ポインタの後ろの文字を返します。 入力ポインタが列の終端にある場合は を返します。 その名前にかかわらず、入力ポインタは移動しません。

int c = sbuf.snextc()
    入力ポインタを 1 つ進め (文字列の後ろに向かって 1 文字分移動し)、 ポインタの新しい位置の後ろの文字を返します。 この関数の呼び出しの前または後に、入力ポインタが入力文字列の 終端にあるとき (取得できる文字がないとき) は、 EOF を返します。 たとえば、入力バッファの内容が次のような場合を 考えます (`|' は入力ポインタの位置を示します)。
    abc|def
    ここで `|' は入力ポインタの位置を示しています。 この関数は、入力ポインタを進め、`e' を返します。

int c = sbuf.sbumpc()
    この関数はおそらく ``sgetc'' と名付けられるべきです。 入力ポインタを 1 つ進め、 新しいポインタ位置の前の文字を返します。 入力ポインタが入力文字列の終端に位置している場合は、 EOF を返します。

sbuf.stossc()
    入力ポインタを 1 つ進め、何も返しません。 sgetc とこの関数を組み合わせれば、 プットバックを行わないでスキャナを実装できます。

int i = sbuf.sgetn(ptr, len)
    入力ポインタの後ろの len 個の文字を取得し、 ptr が指す char 型配列にコピーします。 入力ポインタは、最後にフェッチした文字の後ろに移動します。 バッファ内に残されている文字数が len より少ないときは、 残されている文字のすべてを取得します。 戻り値はフェッチした文字数です。

int c = sbuf.sputbackc(c)
    入力ポインタを 1 つ戻し (入力文字列の先頭に向かって 1 文字分移動し)、 その新しい位置に c を置こうとします。 使用しているバッファ機構によっては、 ポインタを返したり、 その位置に c を格納できない場合があります。 したがって、入力ポインタの後ろにある文字と c とが同じでない場合、 関数が正しく機能したかどうかはっきりしません。 使用しているバッファ機構によっては、 外部のデバイスと同期しなおす必要があります。 プットバックに失敗した場合は、 EOF を返します。 失敗の原因は、実際のバッファクラスの具体的な内容によって異なりますが、 その 1 つとして、すでにデバイスの先頭に位置していることがあります。

int i = sbuf.in_avail()
    get 領域ですぐに利用できる文字の数を返します。 この結果、外部のどのデバイスにアクセスしなくても、 i 個の文字をエラーなしでフェッチできることが確かになります。

  出力関数

int i = sbuf.sputc(c)
    出力ポインタのすぐ後ろに c を格納し、ポインタを 1 文字分 (文字列の終端方向に) 進めます。 このとき、文字列はおそらく拡大されます。 戻り値は、正常終了の場合は c 、エラー時には EOF です。エラーの原因は、実際の派生バッファクラスによって異なります。

int i = sbuf.sputn(ptr, len)
    ptr が指している位置から、出力ポインタの後ろに正確に len 個の文字を格納し、出力ポインタを最後の文字のすぐ後ろに進めます。 戻り値は格納された文字の数で、 len と等しくなければなりません。格納された引数の数が len より少ないとき (戻り値が len より小さいとき) は、何らかのエラーが発生したことを示します。

int i = sbuf.out_waiting()
    出力領域内の文字数、すなわち、最終的な宛先への出力が保留されている文字の数を 返します。

  位置決め関数

streampos pos = sbuf.seekoff(off, dir, mode)
    mode でセットされているビットに従って、入力ポインタと出力ポインタの 一方または両方の位置を変更します。 mode で ios::in がセットされている場合は、入力ポインタを移動します。 mode で ios::out がセットされている場合は、出力ポインタを移動します。 移動距離は符号つきの値 off によって指定します。 dirに 指定可能な値は次の 3 種類です。
    ios::beg - ストリームの先頭から off バイト移動する。
    ios::cur - 現在の位置から off バイト移動する。
    ios::end - ストリームの終端から off バイト移動する。
    戻り値は新しい位置です。 ポインタの位置を指定されたとおりに設定できなかった場合は、 EOF を返します。この関数でポインタの位置を変更できないストリームもあるので 注意してください。 また、返された位置 ( streampos 型) は算術演算のサブジェクトとして使用しないで、 「マジック」値として扱ってください。

streampos newpos = sbuf.seekpos(pos, mode)
    mode でセットされているビットと pos で指定される位置に従って、 入力ポインタと出力ポインタの一方または両方の位置を変更します。 mode で ios::in がセットされている場合は、入力ポインタを移動します。 mode で ios::out がセットされている場合は、出力ポインタを移動します。 pos の値は、 seekoff または seekpos の呼び出しによって返されたものでなければなりません。例外として、 従来の意味を持つ次の 2 つの値が用意されています。
    (streampos)0 - ストリームの先頭
    (streampos)EOF - エラー指示子

int i = sbuf.sync()
    streambuf をその実際の文字ストリームと同期させます。 詳細は、個々の派生バッファクラスに依存します。 通常、put 領域内のすべての文字をその最終的な宛先にフラッシュし、 可能であれば、入力バッファ内のすべての文字をその入力元に戻します。 これは通常、 sync の後には、 in_avail() と out_waiting() がともにゼロを返すということを意味します。 戻り値は、エラー発生時には EOF 、正常終了時にはゼロとなります。

  その他の関数

streambuf* sb = sbuf.setbuf(ptr, len)
    この関数は論理的には限定公開インタフェースに属していますが、 オリジナルのストリーム・パッケージと互換性をとるために 公開インタフェースに置かれています。 ptr が指している位置から始まる len バイトの配列をバッファ領域として使用しようとします。 ptr の値がゼロ、または len の値がゼロ以下の場合は、バッファリングなし (unbuffered) 状態を要求します。 派生クラスの詳細によっては、 この要求を受け入れることが可能な場合があります。 戻り値は、正常終了時には streambuf を指すポインタ、要求を受け入れることができた場合はゼロになります。

関連項目

ios.intro(3CC4)、 ios(3CC4)、 sbufprot(3CC4)、 『C++ ライブラリ・リファレンス』の第 3 章「iostream ライブラリ」 および第 4 章「マルチスレッド環境での従来型の iostream ライブラリの使用」