smstream/memstream.hh

00001 /* -*- mode: c++; c-basic-offset: 4; -*- */
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     // Types:
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     // Constructors:
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       // Members:
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     // Types:
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      // Constructors/destructor:
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       // Members:
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

Generated on Sun Mar 8 19:20:52 2009 for dmt by  doxygen 1.5.4