#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 クラスは、実際のバッファークラスを派生させる、基本的なバッファークラス機能を定義します。このパブリック (public) インタフェースは、どのストリームクラスでもそのバッファー関連の関数を実行するために呼び出す必要がある関数を表します。型のオブジェクトを作成することは期待されません。それよりも、バッファーオブジェクトは、streambuf から派生したクラス型にする必要があります。そのような派生に必要な保護された (protected) インタフェースについては、 sbufprot (3CC4) を参照してください。
streambuf をマルチスレッド安全 (MT-安全) にする、つまりマルチスレッド環境で正しく機能できるようにするため、各パブリック (public) メンバー関数でロックが使用されています。パフォーマンスが重要なシングルスレッドアプリケーションで使用するために、ロックを使用しない代替の一連のパブリック (public) メンバー関数が導入されました。これらのメンバー関数は、接尾辞 _unlocked を追加して、元の関数と同じ名前を共有しています。MT-非安全である以外、これらのメンバー関数は同一の機能を持ちます。
クラス streambuf は抽象バッファークラスをサポートします。これは、論理的に文字のシーケンスと、格納やフェッチが行われる次の文字の位置を定義する 1 つまたは 2 つのポインタで構成されます。入力 (または出力) のみを目的にしたバッファークラスは、get (または put) ポインタのみを持ちます。入力と出力の両方を目的にしたバッファークラスは両方のポインタを持ちます。
get ポインタと put ポインタは、シーケンス内の文字の間を指していると理解してください。入力バッファーから次にフェッチされる文字は、get ポインタの直後の文字です。出力ストリームに配置される次の文字は、put ポインタの直後に格納されます。ポインタは、シーケンスの先頭では先頭の文字の直前を指し、シーケンスの終端では最後の文字の直後を指します。
基盤のデバイスが異なるため、さまざまな方法のさまざまな種類のバッファー (予約領域とも呼ばれる) が存在することがあります。strstreambuf などのキューのようなバッファー (ssbuf(3cc4) を参照) は独立した get ポインタと put ポインタを持ちます。strstreambuf はメモリー内文字配列であり、任意の場所での格納とフェッチをサポートしています。filebuf (filebuf3cc4() を参照) などの ファイルのようなバッファー は、get および put 操作のどちらも許可できますが、実質上 1 つのポインタしかありません。次の get または putは、常に現在の位置になります。(実際には 2 つのポインタが存在する場合もありますが、それらは常に同じ位置を指します)。
streambuf は文字の配列をバッファーとして使用し、空の入力バッファーに入力したり、いっぱいの出力バッファーをフラッシュしたりするために、仮想関数を呼び出します。(詳細については sbufprot(3cc4) を参照してください。)最大限の効率性のため、格納、フェッチ、ポインタ操作関数は通常インラインです。それらを次で説明します。
この関数は get ポインタの後ろの文字を返すか、または get ポインタがシーケンスの終端にある場合は EOF を返します。その名前に関係なく、この関数は get ポインタを移動しません。
この関数は get ポインタの位置を 1 つ進め、get ポインタの新しい位置の後ろの文字を返します。この関数の呼び出しの前または後に、get ポインタがシーケンスの終端にある (使用可能な文字がない) 場合、この関数は EOF を返します。例: 入力バッファーはこのように見えるとします。
abc|def
ここで「|」は get ポインタの位置をマークします。この関数は get ポインタを進め、「e」を返します。
この関数はおそらく「sgetc」と呼ばれていたはずです。get ポインタの位置を 1 つ進め、通過した文字を返します。get ポインタが現在シーケンスの終端にある場合、この関数は EOF を返します。
この関数は get ポインタの位置を 1 つ進め、何も返しません。sgetc は先読みを行うため、sgetc と stossc を組み合わせて使用して、書き戻しを使用せずにスキャナを実装できます。
この関数は、get ポインタに続く次の len 文字を取得し、ptr が指す char 配列にコピーします。get ポインタを最後にフェッチした文字の後ろに進めます。残っている文字が len より少ない場合は、得られる数だけ取得します。フェッチした文字数を返します。
この関数は get ポインタを 1 文字戻し、その新しい位置に c を挿入しようとします。基盤のバッファーメカニズムによっては、ポインタを戻すことができなかったり、その位置に c を格納できなかったりする場合があります。したがって、c が get ポインタの直前にある文字と同じでない場合、関数の効果は不確実です。基盤のメカニズムによっては、この関数は外部のデバイスと再同期する必要がある場合があります。この関数は書き戻しの試みが失敗した場合、EOF を返します。失敗を引き起こす要因は、実際のバッファークラスの詳細によって異なりますが、すでにデバイスの先頭にあることなどが含まれる可能性があります。
この関数は get 領域ですぐに利用可能な文字の数を返します。エラーなく、外部のどのデバイスにもアクセスせずに、i 文字を確実にフェッチできます。
この関数は、put ポインタの直後に c を格納し、ポインタの位置を 1 つ進め、シーケンスを拡張する可能性があります。c またはエラー時は EOF を返します。エラーを発生させる要因は、実際の派生バッファークラスによって異なります。
ptr が指している位置から、put ポインタの後ろに正確に len 文字を格納し、put ポインタを最後の文字の直後に進めます。格納された文字の数を返しますが、これは len になるはずです。格納された文字数が len より少ないことは、何らかのエラーを示します。
この関数は put 領域内の文字数、つまり、最終的な出力先への出力が保留されている文字の数を返します。
この関数は mode に設定されているビットに従って、get ポインタや put ポインタを移動します。mode に ios::in が設定されている場合、get ポインタが移動され、mode に ios::out が設定されている場合、put ポインタが移動されます。移動する距離は符号付きの数量の off です。dir に可能な値は
ストリームの先頭から off バイト移動します。
現在の位置から off バイト移動します。
ストリームの終端から off バイト移動します。
この関数は新しい位置、または要求されたとおりにストリームを位置決めできなかった場合は EOF を返します。注: すべてのストリームが位置決めをサポートしているわけではありません。注: 返された位置 (streampos 型の) は算術演算のサブジェクトとしないで、「マジック」値として扱ってください。
この関数は mode に設定されているビットに従って、get ポインタや put ポインタを位置 pos に移動します。mode に ios::in が設定されている場合、get ポインタが移動され、mode に ios::out が設定されている場合、put ポインタが移動されます。pos の値は、seekoff または seekpos の以前の呼び出しによって返されたものであるべきですが、従来の意味を持つ 2 つの特殊な値があります。
(streampos)0 - the beginning of the stream; (streampos)EOF - error indicator.
この関数は streambuf をその実際の文字のストリームと同期させます。詳細は、特定の派生バッファークラスによって異なります。一般に、put 領域内のすべての文字をそれらの最終的な出力先にフラッシュし、可能であれば、入力バッファー内のすべての文字をそれらの入力元に戻します。これは一般に、in_avail() と out_waiting() がともに sync のあとにゼロを返すことを意味します。この関数は、エラー時に EOF、成功時にゼロを返します。
この関数は論理的には保護された (protected) インタフェースに属していますが、元のストリームパッケージとの互換性のためにパブリック (public) インタフェースに置かれています。この関数は、ptr が指す位置から始まる len バイトの配列をバッファー領域として使用するように試みます。ptr をゼロに、または len をゼロ以下に設定することは、バッファーなし状態を要求します。派生クラスの詳細によっては、この要求を受け入れられない場合があります。この関数は、成功時 streambuf へのポインタ、要求を受け入れることができた場合はゼロを返します。
ios (3CC4) , ios.intro (3CC4) , sbufprot (3CC4)
『C++ ライブラリリファレンス』の第 3 章「従来型の iostream ライブラリ」および第 4 章「マルチスレッド環境での従来型の iostreams ライブラリの使用」