マニュアルページ 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 ライブラリの使
     用」