00001
00002 #ifndef MEMSTREAM_HH
00003 #define MEMSTREAM_HH
00004
00005 #include <iostream>
00006 #include <streambuf>
00007
00014 template<typename _CharT, typename _Traits = std::char_traits<_CharT> >
00015 class basic_membuf : public std::basic_streambuf< _CharT, _Traits >
00016 {
00017 public:
00019 typedef _CharT char_type;
00021 typedef _Traits traits_type;
00023 typedef typename traits_type::int_type int_type;
00025 typedef typename traits_type::pos_type pos_type;
00027 typedef typename traits_type::off_type off_type;
00029 typedef std::basic_streambuf<char_type, traits_type> _streambuf_type;
00030
00031 public:
00036 basic_membuf(std::ios_base::openmode __mode = std::ios_base::out);
00037
00044 basic_membuf(char_type* buf, int_type len,
00045 std::ios_base::openmode __mode = std::ios_base::out);
00046
00050 virtual ~basic_membuf(void) {sync();}
00051
00052 protected:
00056 virtual int_type underflow(void);
00057
00061 virtual int_type overflow(void) {return traits_type::eof();}
00062
00066 virtual int_type pbackfail(int_type c) {return traits_type::eof();}
00067
00071 virtual pos_type seekoff(off_type off, std::ios_base::seekdir way,
00072 std::ios_base::openmode mode);
00073
00077 virtual pos_type seekpos(pos_type sp, std::ios_base::openmode mode);
00078
00082 virtual basic_membuf<_CharT,_Traits>* setbuf(char_type* buf, int_type len);
00083
00089 virtual int sync(void) {return 0;}
00090
00091 private:
00092 std::ios_base::openmode _M_mode;
00093 char_type* mBuf;
00094 int_type mLen;
00095 };
00096
00097 template<typename _CharT, typename _Traits>
00098 inline
00099 basic_membuf<_CharT, _Traits>::basic_membuf(std::ios_base::openmode __mode)
00100 : mBuf(0), mLen(0)
00101 {
00102 _M_mode = __mode;
00103 }
00104
00105 template<typename _CharT, typename _Traits>
00106 inline
00107 basic_membuf<_CharT, _Traits>::basic_membuf(char_type* buf, int_type len,
00108 std::ios_base::openmode __mode)
00109 {
00110 _M_mode = __mode;
00111 setbuf(buf, len);
00112 }
00113
00114
00115 template<typename _CharT, typename _Traits>
00116 inline typename basic_membuf<_CharT, _Traits>::int_type
00117 basic_membuf<_CharT, _Traits>::underflow(void) {
00118 if (this->gptr() < this->egptr()) return traits_type::to_int_type(*this->gptr());
00119 return traits_type::eof();
00120 }
00121
00122 template<typename _CharT, typename _Traits>
00123 inline basic_membuf<_CharT, _Traits>*
00124 basic_membuf<_CharT, _Traits>::setbuf(char_type* buf, int_type len)
00125 {
00126 mBuf = buf;
00127 mLen = len;
00128 if ((_M_mode & std::ios_base::in )!=0) this->setg(mBuf, mBuf, mBuf+mLen);
00129 if ((_M_mode & std::ios_base::out)!=0) this->setp(mBuf, mBuf + mLen);
00130 return this;
00131 }
00132
00133 template<typename _CharT, typename _Traits>
00134 inline typename basic_membuf<_CharT, _Traits>::pos_type
00135 basic_membuf<_CharT, _Traits>::seekoff(off_type off,
00136 std::ios_base::seekdir way,
00137 std::ios_base::openmode mode) {
00138 off_type ret(-1);
00139 bool in_mode = (std::ios_base::in & _M_mode & mode) != 0;
00140 bool out_mode = (std::ios_base::out & _M_mode & mode) != 0;
00141 if (way == std::ios_base::beg) {
00142 ret = 0;
00143 } else if (way == std::ios_base::cur) {
00144 if (out_mode) ret = this->pptr() - mBuf;
00145 if ( in_mode) ret = this->gptr() - mBuf;
00146 } else if (way == std::ios_base::end) {
00147 ret = mLen;
00148 }
00149 if (ret != off_type(-1)) {
00150 ret += off;
00151 if (!(ret >= 0 && ret <= mLen)) ret = off_type(-1);
00152 }
00153 if (ret != off_type(-1)) {
00154 if ( in_mode) this->setg(mBuf, mBuf+ret, mBuf+mLen);
00155 if (out_mode) {
00156 this->setp(mBuf, mBuf + mLen);
00157 this->pbump(ret);
00158 }
00159 }
00160 return pos_type(ret);
00161 }
00162
00163 template<typename _CharT, typename _Traits>
00164 inline typename basic_membuf<_CharT, _Traits>::pos_type
00165 basic_membuf<_CharT, _Traits>::seekpos(pos_type sp,
00166 std::ios_base::openmode mode) {
00167 return seekoff(off_type(sp), std::ios_base::beg, mode);
00168 }
00169
00176 template<typename _CharT, typename _Traits = std::char_traits<_CharT> >
00177 class basic_imemstream : public std::basic_istream<_CharT, _Traits>
00178 {
00179 public:
00180
00182 typedef _CharT char_type;
00184 typedef _Traits traits_type;
00186 typedef typename traits_type::int_type int_type;
00188 typedef typename traits_type::pos_type pos_type;
00190 typedef typename traits_type::off_type off_type;
00192 typedef basic_membuf<_CharT, _Traits> __membuf_type;
00194 typedef std::basic_istream<char_type, traits_type> __istream_type;
00195
00196 private:
00197 __membuf_type _M_membuf;
00198
00199 public:
00200
00203 explicit
00204 basic_imemstream(std::ios_base::openmode __mode = std::ios_base::in)
00205 : __istream_type(NULL)
00206 { this->init(&_M_membuf); }
00207
00210 basic_imemstream(const char_type* __buf, int_type __len,
00211 std::ios_base::openmode __mode = std::ios_base::in)
00212 : __istream_type(NULL),
00213 _M_membuf(const_cast<char_type*>(__buf), __len, __mode)
00214 { this->init(&_M_membuf); }
00215
00219 ~basic_imemstream()
00220 { }
00221
00222
00227 __membuf_type* rdbuf() const
00228 { return const_cast<__membuf_type*>(&_M_membuf); }
00229 };
00230
00231
00238 template <typename _CharT, typename _Traits = std::char_traits<_CharT> >
00239 class basic_omemstream : public std::basic_ostream<_CharT, _Traits>
00240 {
00241 public:
00242
00244 typedef _CharT char_type;
00246 typedef _Traits traits_type;
00247
00249 typedef typename traits_type::int_type int_type;
00250
00252 typedef typename traits_type::pos_type pos_type;
00253
00255 typedef typename traits_type::off_type off_type;
00256
00258 typedef basic_membuf<_CharT, _Traits> __membuf_type;
00259
00261 typedef std::basic_ostream<char_type, traits_type> __ostream_type;
00262
00263 private:
00264 __membuf_type _M_membuf;
00265
00266 public:
00267
00270 explicit
00271 basic_omemstream(std::ios_base::openmode __mode = std::ios_base::out)
00272 : __ostream_type(NULL), _M_membuf(__mode | std::ios_base::out)
00273 { this->init(&_M_membuf); }
00274
00278 basic_omemstream(char_type* __buf, int_type __len,
00279 std::ios_base::openmode __mode = std::ios_base::out)
00280 : __ostream_type(NULL), _M_membuf(__buf, __len, __mode | std::ios_base::out)
00281 { this->init(&_M_membuf); }
00282
00283
00286 ~basic_omemstream()
00287 { }
00288
00289
00294 __membuf_type*
00295 rdbuf() const
00296 { return const_cast<__membuf_type*>(&_M_membuf); }
00297 };
00298
00299 typedef basic_imemstream<char> imemstream;
00300 typedef basic_omemstream<char> omemstream;
00301
00302 #endif