//--------------------------------------------------------------------------- /* 簡易streambuf Ver.1.0 by Gimite 市川 拡張が容易な出力用streambuf。simple_ostreambufの派生クラスを作り、文字列 を出力する仮想関数put()をオーバライドするだけで良い。put()は出力に成功す ればtrueを返すようにする。put()の定義は以下。 virtual bool put(const std::string& s); 拡張が容易な入力用streambuf。simple_istreambufの派生クラスを作り、次の1文 字を取得する仮想関数get()をオーバライドするだけで良い。get()は入力の終端 に達したらtraits_type::eof()を返すようにする。get()の定義は以下。 virtual int get(); 押し戻し(unget)を処理したければ仮想関数unget()をオーバライドする。 simple_ostreambuf、simple_istreambufは入出力のバッファリングを行わない。 */ //--------------------------------------------------------------------------- #ifndef GIMITE_simple_streambufH #define GIMITE_simple_streambufH //--------------------------------------------------------------------------- #include //streamsize #include //basic_streambuf #include //char_traits, basic_string //--------------------------------------------------------------------------- namespace gimite{ //--------------------------------------------------------------------------- template > class basic_simple_ostreambuf: public std::basic_streambuf { typedef std::basic_streambuf streambuf_type; typedef std::basic_string string_type; public: typedef streambuf_type::int_type int_type; typedef streambuf_type::char_type char_type; protected: //sを出力、成功ならtrue virtual bool put(const string_type& s)= 0; virtual int_type overflow(int_type c= traits::eof()){ if (traits::eq_int_type(c, traits::eof())) return c; else return put(string_type(1, c))? c:traits::eof(); } virtual std::streamsize xsputn(const char_type* s, std::streamsize n){ return put(string_type(s, n))? n:0; } }; typedef basic_simple_ostreambuf simple_ostreambuf; typedef basic_simple_ostreambuf simple_wostreambuf; //--------------------------------------------------------------------------- template > class basic_simple_istreambuf: public std::basic_streambuf { typedef std::basic_streambuf streambuf; public: typedef typename streambuf::int_type int_type; basic_simple_istreambuf(){ for (int i= 0; i<3; ++i) buffer_[i]= traits::eof(); } protected: //次の1文字を取得、無ければtraits_type::eof() virtual int_type get()= 0; //cを押し戻す、成功ならtrue virtual bool unget(charT c){return false;} //1文字読み出し、読み出し位置を進める virtual int_type uflow(){ int_type res= underflow(); buffer_[0]= buffer_[1]; buffer_[1]= buffer_[2]; buffer_[2]= traits::eof(); return res; } //1文字読み出す(読み出し位置を変えない) virtual int_type underflow(){ if (is_eof(buffer_[1])) buffer_[1]= get(); return buffer_[1]; } //バッファに1文字戻す virtual int_type pbackfail(int_type c= traits_type::eof()){ if (!is_eof(buffer_[2]) || (is_eof(buffer_[0]) && is_eof(c))) return traits::eof(); if (!is_eof(buffer_[1]) || !unget(is_eof(c)? buffer_[0]:c)){ buffer_[2]= buffer_[1]; buffer_[1]= is_eof(c)? buffer_[0]:c; } buffer_[0]= traits::eof(); return buffer_[1]; } virtual int showmanyc(){return -1;} private: int_type buffer_[3];//*1 bool is_eof(int_type c){return traits::eq_int_type(c, traits::eof());} }; //*1 0:取り出し済み文字 1:読み出し対象 2:その次に取り出す文字 typedef basic_simple_istreambuf simple_istreambuf; typedef basic_simple_istreambuf simple_wistreambuf; //--------------------------------------------------------------------------- }//namespace gimite //--------------------------------------------------------------------------- #endif