# マニュアルページ sbufprot.3

## 名前

         sbufprot - ストリームバッファ基底クラスの限定 公 開 イ ン タ
         フェース

## 形式

         #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:
                 streambuf() ;
                 streambuf(char* p, int len);
                 void    dbp() ;
         protected:
                 int     allocate();
                 char*   base();
                 int     blen();
                 char*   eback();
                 char*   ebuf();
                 char*   egptr();
                 char*   epptr();
                 void    gbump(int n);
                 char*   gptr();
                 char*   pbase();
                 void    pbump(int n);
                 char*   pptr();
                 void    setg(char* eb, char* g, char* eg);
                 void    setp(char* p, char* ep);
                 void    setb(char* b, char* eb, int a=0);
                 int     unbuffered();
                 void    unbuffered(int);

                 virtual int     doallocate();
                 virtual ~streambuf() ;

                 int     allocate_unlocked();
                 char*   base_unlocked();
                 int     blen_unlocked();
                 char*   eback_unlocked();
                 char*   ebuf_unlocked();
                 char*   egptr_unlocked();
                 char*   epptr_unlocked();
                 void    gbump_unlocked(int n);
                 char*   gptr_unlocked();
                 char*   pbase_unlocked();
                 void    pbump_unlocked(int n);
                 char*   pptr_unlocked();
                 void    setg_unlocked(char* eb, char* g, char* eg);
                 void    setp_unlocked(char* p, char* ep);
                 int     unbuffered_unlocked();
                 void    unbuffered_unlocked(int);

         streambuf(char* buf, int len);
         public:
                 virtual int     pbackfail(int c);
                 virtual int     overflow(int c=EOF);
                 virtual int     underflow();
                 virtual streambuf*
                         setbuf(char* p, int len);
                 streambuf*
                         setbuf(unsigned char* p, in len);
                 virtual streampos
                         seekpos(streampos, int =ios::in|ios:out);
                 virtual streampos
                         seekoff(streamoff, seek_dir, int =ios::in|ios:out);
                 virtual int     sync();
         };

## 機能説明

         streambuf の公開インタフェースについては、 sbuf.pub(3CC4) を
         参照してください。ここでは、使用可能なバッファクラスを派生さ
         せるときに必要な限定公開インタフェースについて説明します。ク
         ラ ス streambuf は、基底クラスとしてだけ使用するように設計さ
         れています。したがって、クラス streambuf のオブジェクトは 作
         成できません。代わりに、3 つの派生バッファクラスが定義されて
         います。 filebuf(3CC4) 、 ssbuf(3CC4) 、 stdiobuf(3CC4) を参
         照してください。

         一般に、ここで説明する非仮想関数は、変更して使用するようには
         設計されていません。これらの関数は、低レベルのバッファ管理機
         能を提供します。

         ここでは、各仮想関数の機能と、そのデフォルトの動作について説
         明します。関数のデフォルトの動作が作成する派生バッファクラス
         に適していれば、その関数を変更する必要はありません。た と え
         ば、入力ソースを持たないバッファクラスは、アンダーフロー時に
         は EOF を返すこと (デフォルトの動作) 以外、何も行いませ ん。
         デフォルトの動作が適さない場合は、その関数を変更し、クラス固
         有のバージョンを用意しなければなりません。たとえば、ファイル
         に 接 続されている入力バッファは、アンダーフロー時にもさらに
         データの読み込みを試みなければなりません。クラス固有の仮想関
         数 は、 その動作に依存する他の関数を続けて機能させるために、
         streambuf 版の仕様に従わなければなりません。

         streambuf の限定公開メンバーー関数は、それぞれロック機能を使
         用して streambuf をマルチスレッド環境で正しく動作させます。

         streambuf を MT-safe にするロック機能を持たない関数も提供 さ
         れ ています。これらの関数は、名前の接尾辞 "_unlocked" で区別
         されます。

      コンストラクタと
      代入演算子
         streambuf()
              コンストラクタ。空の入力ストリームのための空のバッ ファ
              を作成します。

         streambuf(ptr, len)
              コンストラクタ。空のバッファか、または ptr が指す場所か
              ら 始まる len バイトの reserve 領域 (下記参照) を作成し
              ます。

         streambuf(streambuf&) // 非公開
         operator= (streambuf&) // 非公開
              コピーコンストラクタと代入演算子は非公開です。  stream-
              buf  の コ ピー を 防止するようには実装されていません。
              streambuf をコピーする代わりに、1 つの streambuf を指す
              複数のポインタの受け渡しを行うことがあります。

      入力領域、出力領域
      確保領域
         streambuf のバッファは、入力領域、出力領域、確保領域  ( バッ
         ファ 領域と同じ) の 3 つの部分から構成されていると見なすこと
         ができます。入力領域には、入力データとしてそのまま使用できる
         文字が含まれます。出力領域には、最終的な宛先によってまだ消費
         されていない (フラッシュされていない) 出力文字が保持さ れ ま
         す。入力領域や出力領域は、別々にも、また重複させても確保する
         ことができます。確保領域はバッファ全体に対応し、入力領域と出
         力領域もその中に含まれます。入力領域と出力領域は、確保領域の
         残りの部分まで拡大できます。入出力操作中、入力領域と出力領域
         のサイズは、常に合計バッファサイズ (確保領域のサイズ) の範囲
         内で拡張したり縮小したりします。

         バッファとその領域は、非公開のポインタ変数によって定義されま
         す。それは、限定公開のメンバー関数によって読み込みや設定が可
         能です。後述するポインタは、文字間を指していると考えてくださ
         い。 すなわち、ポインタは 1 つの文字を指していますが、文字の
         直前を指しているものとして調べる方が便利です。これに よ り、
         sbuf.pub(3CC4)  で説明されている抽象的な表現に対応するものが
         確立されます。

      ポインタを調べるための非仮想関数
         char* ptr = sbuf.base()
              確保領域の先頭を指すポインタを返します。

         char* ptr = sbuf.ebuf()
              確保領域のすぐ後ろを指すポインタを返します。 base()  か
              ら  ebuf()-1  までの領域が確保領域です。 ebuf()==base()
              である場合、ストリームはバッファリングされません。

         char* ptr = sbuf.gptr()
              入力領域の先頭を指すポインタ、すなわち、次にフェッチ す
              る 文字があればその文字を指すポインタを返します。直ちに
              使用できる文字は、 gptr()から egptr()-1 までの領域に あ
              ります。 egptr()<=gptr() である場合、使用できる文字は存
              在しません。

         char* ptr = sbuf.egptr()
              入力領域のすぐ後ろを指すポインタを返します。このポイ ン
              タは、 gptr() で可能な最大値を示します。

         char* ptr = sbuf.eback()
              gptr() で可能な最小値を返します。文字をプットバッ ク  (
              get  ポ インタをバックアップする) のために eback() から
              gptr()-1 までの領域を使用できます。 back()==gptr() のと
              き、プットバック操作を試みても失敗することがあります。

         char* ptr = sbuf.pptr()
              出力領域の先頭を指すポインタを返します。このポ イ ン タ
              は、 次に格納できる文字があれば、その文字の位置を示しま
              す。

         char* ptr = sbuf.pbase()
              出力領域に使用できる領域の先頭を指すポインタを 返 し ま
              す。 このポインタは、 pptr() で可能な最小値を示します。
              pbase() から pptr()-1までの領域はバッファに格納されてい
              るが、まだ使用されていない文字を表します。

         char* ptr = sbuf.epptr()
              出力領域のすぐ後ろを指すポインタを返します。このポイ ン
              タ は、  pptr()  で可能な最大値を示します。 pptr() から
              epptr() までの領域は、文字を格納するための領域とし て、
              フラッシュ操作なしですぐに使用できます。

      ポインタ設定のための
      非仮想関数
         ポインタを設定するためには、ここで取り上げる関数を使用する必
         要があります。各種ポインタ間の整合性を保証するため、ポインタ
         に直接アクセスすることはできません。関数のポインタ引数は、何
         も領域 (入力、出力、確保) がないことを示す場合はすべてゼロで
         なければなりません。値が等しい (ゼロを除く) ポインタを複数使
         用すると、不適切な動作が行われることがあります。

         sbuf.setb(buf, end, del)
              確保領域 (バッファ) を確立します。 base() を buf に設定
              し、  ebuf()  を  end に設定します。 del がゼロ以外の場
              合、 base() が setb() の別の呼び出しによって変更され る
              たび、または streambuf のデストラクタが呼び出されるとき
              に、バッファが削除 ( delete ) されます。 del がゼロの場
              合、 これらの関数によってバッファが自動的に削除されるこ
              とはありません。

         sbuf.setg(back, g, eg)
              入力領域を確立します。 eback() を back に、 gptr() を g
              に、 egptr() を eg にそれぞれ設定します。

         sbuf.setp(p, ep)
              出力領域を確立します。 pptr() を p に設定 し、  epptr()
              を ep に設定します。

      その他の非仮想関数
         int i = sbuf.allocate()
              この関数は、 streambuf のどの非仮想メンバーによっても呼
              び 出されることはありません。指定されていないデフォルト
              のサイズの確保領域のセットアップを試みます。確保領域 が
              すでに存在する場合、または streambuf がバッファリングし
              ないように設定されている場合、ゼロを返して何も行いま せ
              ん。 それ以外の場合、仮想関数 doallocate() を呼び出すこ
              とによって領域の割り当てを試みます。割り当てに成功し た
              場 合は 1、失敗した場合は EOF を返します。 unbuffered()
              と doallocate() については、下記を参照してください。

         int i = sbuf.blen()
              確保領域 ebuf()-base() のサイズを文字数で返します。

         sbuf.gbump(n)
              符号つきの量 n を妥当性検査なしで get ポインタに追加 し
              ます。

         sbuf.pbump(n)
              符号つきの量 n を妥当性検査なしで get ポインタに追加 し
              ます。

         int i = sbuf.unbuffered()
         sbuf.unbuffered(i)
              streambuf は、確保領域が割り当てられているかどうかに 関
              係 なく、ストリームがバッファリングされているかどうかを
              追跡するための非公開関数を持っています。主にこ の 関 数
              は、  allocate() によって確保領域を実際に割り当てるかど
              うかを制御するために使用します。上の引数なしの 形 式 で
              は、 変数がセットされていればゼロ以外の値、セットされて
              いなければゼロを返します。下の形式では、引数 i がゼロで
              な い場合に変数をセットし、ゼロの場合には変数をクリアし
              ます。

         dpb()
              streambuf のすべての状態変数をテキストとして、ファイ ル
              記 述子 1 (標準出力) に直接書き込みます。このデータは、
              実装のデバッグに利用できます。この関数は公開関数で す。
              し た がっ て、それが論理的に限定公開関数の一部であって
              も、デバッグの目的でどこからでも呼び出すことが で き ま
              す。

      仮想関数
         ここで取り上げる関数は、上記で示した特別なバッファクラ ス に
         よって再定義できる、または再定義しなければならない仮想関数で
         す。再定義した関数は、それらに依存する他の関数が適切に動作す
         るように、ここで示す仕様に従っていなければなりません。ここで
         はまた、各関数の基底クラス版のデフォルト動作についても示しま
         す。

         int i = sbuf.doallocate()
              この関数は、 unbuffered() と base() がともにゼロの場 合
              に  allocate によって呼び出されます。適切なサイズのバッ
              ファを作成するように試みます。バッファの作成に成功し た
              場 合は、 setb を呼び出して確保領域を確立し、ゼロよりも
              大きい値を返されなければなりません。バッファの作成に 失
              敗 した場合は EOF を返します。デフォルトでは、 new を使
              用してバッファを割り当てます。

         int i = sbuf.overflow(c)
              この関数は、通常出力領域がフル状態になっているときに 別
              の 文字が格納されようとした場合に呼び出され、領域内の文
              字を消費 (出力にフラッシュ) します。 c が EOF 以外の と
              き、  overflow は、出力領域にすでに存在する文字の後ろに
              ある文字を格納するか、消費しなければなりません。エ ラー
              が発生した場合は EOF 、正常終了した場合はそれ以外の任意
              の値を返します。
              基底クラス版のデフォルトの動作は未定義であるため、各 派
              生 クラスでは独自の overflow を定義する必要があります。
              通常、派生クラス版関数は出力領域内の文字 (  pbase()  と
              pptr() の間にあるもの) を消費し、 setp() を呼び出して新
              しい出力領域をセットアップした後、 cが EOF でなければ、
              ( sputc() を用いて) それを格納します。

         int i = sbuf.pbackfail(c)
              この関数は、文字列 c のプットバックが試みられたと き に
              プッ ト バッ ク 領 域 に 領 域 が残っていなかった場合 (
              eback()==gptr() のとき) に呼び出されます。外部デバイ ス
              の 再配置などによってこの状況を処理できれば、派生クラス
              版の pbackfail はその処理を行なって c を返します。何 ら
              か の 理 由によって文字を書き戻すことができない場合は、
              EOF を返さなければなりません。基底クラス版のデフォル ト
              では、 EOFを返します。

         streampos pos = sbuf.seekoff(off, dir, mode)
              この関数のパラメ タ、 戻 り 値、 目 的 に つ い て は、
              sbuf.pub(3CC4)  を 参 照 し て ください。特に gptr() や
              pptr() とは対照的に、 get と put の抽象ポインタは可能で
              あ ればこの関数によって変更されます。派生クラス版は、ス
              トリームが再配置をサポートしていないか、何らかのエ ラー
              があった場合は EOF を、それ以外の場合は新しい位置を返さ
              なければなりません。基底クラス版のデフォルトでは、  EOF
              を返します。

         streampos pos2 = sbuf.seekpos(pos, mode)
              この関数のパラメ タ、 戻 り 値、 目 的 に つ い て は、
              sbuf.pub(3CC4)  を 参 照 し て ください。特に gptr() や
              pptr() とは対照的に、get と put の抽象ポインタは可能 で
              あ れ ば この関数によって変更されます。基底クラス版のデ
              フォルトでは次の値を返します。
                   sbuf.seekoff( (streamoff)pos, ios::beg, mode )
              すなわち、通常は派生クラスで seekoff を実装し、基底クラ
              ス seekpos を継承するだけでよいということになります。

         streambuf* sb = sbuf.setbuf(ptr, len)
              ptr が指す位置から始まる len バイトの配列をバッファ領域
              として使用するように要求します。 ptr がゼロの場合、また
              は len がゼロ以下の場合は、バッファなし ( unbuffered  )
              状 態を要求します。派生クラス版では、要求を無視するよう
              に選択できます。要求を受け付ける場合は sbuf の ア ド レ
              ス、それ以外の場合は EOF を返さなければなりません。基底
              クラス版のデフォルトでは、確保領域がない場合に要求を 受
              け付けます。

         int i = sbuf.sync()
              streambuf をその実際の文字ストリームと同期させます。 派
              生 クラス版では、出力領域内のすべての文字をその最終的な
              宛先にフラッシュし、可能であれば入力バッファ内のすべ て
              の 文字をその入力元に戻さなければなりません。さらに、エ
              ラー時には EOF 、正常終了時にはゼロを返さなければなりま
              せ ん。基底クラス版のデフォルトでは、保留中の入力文字ま
              たは出力文字がない場合 ( in_avail() と out_waiting() が
              ともにゼロの場合) にゼロ、それ以外の場合は EOF を返しま
              す。

         int i = sbuf.underflow()
              この関数は入力領域が空の場合に呼び出され、入力用の文 字
              を  (あるソースから) 供給します。ただし、それ以外の場合
              に呼び出すこともできます。入力領域が空でない場合は、 先
              頭の文字だけを返し (get ポインタは進めません)、それ以外
              のことは行わないでください。入力領域が空の場合は、入 力
              領 域を新しく作成し、新しい入力データがあればそれを取得
              し、その先頭の文字を返さなければなりません。基底クラ ス
              版 のデフォルトの動作は未定義です。したがって、各派生ク
              ラスで独自の underflow を定義しなければなりません。

## 関連項目

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