_streambuf.h

00001 /*
00002  * Copyright (c) 1999
00003  * Silicon Graphics Computer Systems, Inc.
00004  *
00005  * Copyright (c) 1999 
00006  * Boris Fomitchev
00007  *
00008  * This material is provided "as is", with absolutely no warranty expressed
00009  * or implied. Any use is at your own risk.
00010  *
00011  * Permission to use or copy this software for any purpose is hereby granted 
00012  * without fee, provided the above notices are retained on all copies.
00013  * Permission to modify the code and to distribute modified code is granted,
00014  * provided the above notices are retained, and a notice that the code was
00015  * modified is included with the above copyright notice.
00016  *
00017  */ 
00018 #ifndef _STLP_INTERNAL_STREAMBUF
00019 #define _STLP_INTERNAL_STREAMBUF
00020 
00021 #ifndef _STLP_IOS_BASE_H
00022 #include <stl/_ios_base.h>      // Needed for ios_base bitfield members.
00023                                 // <ios_base> includes <iosfwd>.
00024 #endif
00025 
00026 #ifndef _STLP_STDIO_FILE_H
00027 #include <stl/_stdio_file.h>     // Declaration of struct FILE, and of
00028                                 // functions to manipulate it.
00029 #endif
00030 
00031 _STLP_BEGIN_NAMESPACE
00032 
00033 //----------------------------------------------------------------------
00034 // Class basic_streambuf<>, the base class of the streambuf hierarchy.
00035 
00036 // A basic_streambuf<> manages an input (get) area and an output (put)
00037 // area.  Each is described by three pointers: a beginning, an end, and a
00038 // current position.  basic_streambuf<> contains some very simple member
00039 // functions that manipulate those six pointers, but almost all of the real
00040 // functionality gets delegated to protected virtual member functions.
00041 // All of the public member functions are inline, and most of the protected
00042 // member functions are virtual.
00043 
00044 // Although basic_streambuf<> is not abstract, it is useful only as a base
00045 // class.  Its virtual member functions have default definitions such that
00046 // reading from a basic_streambuf<> will always yield EOF, and writing to a
00047 // basic_streambuf<> will always fail.
00048 
00049 // The second template parameter, _Traits, defaults to char_traits<_CharT>.
00050 // The default is declared in header <iosfwd>, and it isn't declared here
00051 // because C++ language rules do not allow it to be declared twice. 
00052 
00053 template <class _CharT, class _Traits>
00054 class basic_streambuf
00055 {
00056   friend class basic_istream<_CharT, _Traits>;
00057   friend class basic_ostream<_CharT, _Traits>;
00058 
00059 public:                         // Typedefs.
00060   typedef _CharT                     char_type;
00061   typedef typename _Traits::int_type int_type;
00062   typedef typename _Traits::pos_type pos_type;
00063   typedef typename _Traits::off_type off_type;
00064   typedef _Traits                    traits_type;
00065 
00066 private:                        // Data members.
00067 
00068   char_type* _M_gbegin;         // Beginning of get area
00069   char_type* _M_gnext;          // Current position within the get area
00070   char_type* _M_gend;           // End of get area
00071 
00072   char_type* _M_pbegin;         // Beginning of put area
00073   char_type* _M_pnext;          // Current position within the put area
00074   char_type* _M_pend;           // End of put area
00075 
00076   locale _M_locale;             // The streambuf's locale object
00077 
00078 public:                         // Extension: locking, for thread safety.
00079   _STLP_mutex _M_lock;
00080 
00081 public:                         // Destructor.
00082   virtual ~basic_streambuf();
00083 
00084 protected:                      // The default constructor.
00085   basic_streambuf();
00086 
00087 protected:                      // Protected interface to the get area.
00088   char_type* eback() const { return _M_gbegin; } // Beginning
00089   char_type* gptr()  const { return _M_gnext; }  // Current position
00090   char_type* egptr() const { return _M_gend; }   // End
00091   
00092   void gbump(int __n) { _M_gnext += __n; }
00093   void setg(char_type* __gbegin, char_type* __gnext, char_type* __gend) {
00094     _M_gbegin = __gbegin;
00095     _M_gnext  = __gnext;
00096     _M_gend   = __gend;
00097   }
00098 
00099 public:
00100   // An alternate public interface to the above functions
00101   // which allows us to avoid using templated friends which
00102   // are not supported on some compilers.
00103 
00104   char_type* _M_eback() const { return eback(); }
00105   char_type* _M_gptr()  const { return gptr(); }
00106   char_type* _M_egptr() const { return egptr(); }
00107   void _M_gbump(int __n)      { gbump(__n); }
00108   void _M_setg(char_type* __gbegin, char_type* __gnext, char_type* __gend)
00109     { setg(__gbegin, __gnext, __gend); }
00110 
00111 protected:                      // Protected interface to the put area
00112 
00113   char_type* pbase() const { return _M_pbegin; } // Beginning
00114   char_type* pptr()  const { return _M_pnext; }  // Current position
00115   char_type* epptr() const { return _M_pend; }   // End
00116 
00117   void pbump(int __n) { _M_pnext += __n; }
00118   void setp(char_type* __pbegin, char_type* __pend) {
00119     _M_pbegin = __pbegin;
00120     _M_pnext  = __pbegin;
00121     _M_pend   = __pend;
00122   }
00123 
00124 protected:                      // Virtual buffer management functions.
00125 
00126   virtual basic_streambuf<_CharT, _Traits>* setbuf(char_type*, streamsize);
00127 
00128   // Alters the stream position, using an integer offset.  In this
00129   // class seekoff does nothing; subclasses are expected to override it.
00130   virtual pos_type seekoff(off_type, ios_base::seekdir,
00131                            ios_base::openmode = ios_base::in | ios_base::out);
00132 
00133   // Alters the stream position, using a previously obtained streampos.  In
00134   // this class seekpos does nothing; subclasses are expected to override it.
00135   virtual pos_type
00136   seekpos(pos_type, ios_base::openmode = ios_base::in | ios_base::out);
00137 
00138   // Synchronizes (i.e. flushes) the buffer.  All subclasses are expected to 
00139   // override this virtual member function.
00140   virtual int sync();
00141 
00142 
00143 public:                         // Buffer management.
00144   basic_streambuf<_CharT, _Traits>* pubsetbuf(char_type* __s, streamsize __n) 
00145     { return this->setbuf(__s, __n); }
00146 
00147   pos_type pubseekoff(off_type __offset, ios_base::seekdir __way,
00148                       ios_base::openmode __mod = ios_base::in | ios_base::out)
00149     { return this->seekoff(__offset, __way, __mod); }
00150 
00151   pos_type pubseekpos(pos_type __sp,
00152                       ios_base::openmode __mod = ios_base::in | ios_base::out)
00153     { return this->seekpos(__sp, __mod); }
00154 
00155   int pubsync() { return this->sync(); }
00156 
00157 protected:                      // Virtual get area functions, as defined in
00158                                 // 17.5.2.4.3 and 17.5.2.4.4 of the standard.
00159   // Returns a lower bound on the number of characters that we can read,
00160   // with underflow, before reaching end of file.  (-1 is a special value:
00161   // it means that underflow will fail.)  Most subclasses should probably
00162   // override this virtual member function.
00163   virtual streamsize showmanyc();
00164 
00165   // Reads up to __n characters.  Return value is the number of 
00166   // characters read.
00167   virtual streamsize xsgetn(char_type* __s, streamsize __n);
00168 
00169   // Called when there is no read position, i.e. when gptr() is null
00170   // or when gptr() >= egptr().  Subclasses are expected to override
00171   // this virtual member function.
00172   virtual int_type underflow();
00173 
00174   // Similar to underflow(), but used for unbuffered input.  Most 
00175   // subclasses should probably override this virtual member function.
00176   virtual int_type uflow();
00177 
00178   // Called when there is no putback position, i.e. when gptr() is null
00179   // or when gptr() == eback().  All subclasses are expected to override
00180   // this virtual member function.
00181   virtual int_type pbackfail(int_type = traits_type::eof());
00182 
00183 protected:                      // Virtual put area functions, as defined in
00184                                 // 27.5.2.4.5 of the standard.
00185 
00186   // Writes up to __n characters.  Return value is the number of characters
00187   // written.
00188   virtual streamsize xsputn(const char_type* __s, streamsize __n);
00189 
00190   // Extension: writes up to __n copies of __c.  Return value is the number
00191   // of characters written.
00192   virtual streamsize _M_xsputnc(char_type __c, streamsize __n);
00193 
00194   // Called when there is no write position.  All subclasses are expected to
00195   // override this virtual member function.
00196   virtual int_type overflow(int_type = traits_type::eof());
00197 
00198 public:                         // Public members for writing characters.
00199   // Write a single character.
00200   int_type sputc(char_type __c) {
00201     return ((_M_pnext < _M_pend) ? _Traits::to_int_type(*_M_pnext++ = __c)
00202       : this->overflow(_Traits::to_int_type(__c)));
00203   }
00204 
00205   // Write __n characters.
00206   streamsize sputn(const char_type* __s, streamsize __n)
00207     { return this->xsputn(__s, __n); }
00208 
00209   // Extension: write __n copies of __c.
00210   streamsize _M_sputnc(char_type __c, streamsize __n)
00211     { return this->_M_xsputnc(__c, __n); }
00212 
00213 private:                        // Helper functions.
00214   int_type _M_snextc_aux();
00215 
00216 
00217 public:                         // Public members for reading characters.
00218   streamsize in_avail() {
00219     return (_M_gnext < _M_gend) ? (_M_gend - _M_gnext) : this->showmanyc();
00220   }
00221   
00222   // Advance to the next character and return it.
00223   int_type snextc() {
00224         return ( _M_gend - _M_gnext > 1 ?
00225              _Traits::to_int_type(*++_M_gnext) :
00226              this->_M_snextc_aux());
00227   }
00228 
00229   // Return the current character and advance to the next.
00230   int_type sbumpc() {
00231     return _M_gnext < _M_gend ? _Traits::to_int_type(*_M_gnext++) 
00232       : this->uflow();
00233   }
00234   
00235   // Return the current character without advancing to the next.
00236   int_type sgetc() {
00237     return _M_gnext < _M_gend ? _Traits::to_int_type(*_M_gnext) 
00238       : this->underflow();
00239   }
00240   
00241   streamsize sgetn(char_type* __s, streamsize __n)
00242   { return this->xsgetn(__s, __n); }
00243   
00244   int_type sputbackc(char_type __c) {
00245     return ((_M_gbegin < _M_gnext) && _Traits::eq(__c, *(_M_gnext - 1)))
00246       ? _Traits::to_int_type(*--_M_gnext)
00247       : this->pbackfail(_Traits::to_int_type(__c));
00248   }
00249   
00250   int_type sungetc() {
00251     return (_M_gbegin < _M_gnext)
00252       ? _Traits::to_int_type(*--_M_gnext)
00253       : this->pbackfail();
00254   }
00255 
00256 protected:                      // Virtual locale functions.
00257 
00258   // This is a hook, called by pubimbue() just before pubimbue()
00259   // sets the streambuf's locale to __loc.  Note that imbue should
00260   // not (and cannot, since it has no access to streambuf's private
00261   // members) set the streambuf's locale itself.
00262   virtual void imbue(const locale&);
00263 
00264 public:                         // Locale-related functions.
00265   locale pubimbue(const locale&);
00266   locale getloc() const { return _M_locale; }
00267 
00268 # ifndef _STLP_NO_ANACHRONISMS
00269   void stossc() { this->sbumpc(); }
00270 # endif
00271 #if defined(__MVS__) || defined(__OS400__)
00272 private: // Data members.
00273 
00274   char_type* _M_gbegin; // Beginning of get area
00275   char_type* _M_gnext; // Current position within the get area
00276   char_type* _M_gend; // End of get area
00277 
00278   char_type* _M_pbegin; // Beginning of put area
00279   char_type* _M_pnext; // Current position within the put area
00280   char_type* _M_pend; // End of put area
00281 #endif
00282 };
00283 
00284 
00285 //----------------------------------------------------------------------
00286 // Specialization: basic_streambuf<char, char_traits<char> >
00287 
00288 // We implement basic_streambuf<char, char_traits<char> > very differently
00289 // than the general basic_streambuf<> template.  The main reason for this
00290 // difference is a requirement in the C++ standard: the standard input
00291 // and output streams cin and cout are required by default to be synchronized
00292 // with the C library components stdin and stdout.  This means it must be
00293 // possible to synchronize a basic_streambuf<char> with a C buffer.
00294 //
00295 // There are two basic ways to do that.  First, the streambuf could be
00296 // unbuffered and delegate all buffering to stdio operations.  This
00297 // would be correct, but slow: it would require at least one virtual
00298 // function call for every character.  Second, the streambuf could use 
00299 // a C stdio FILE as its buffer.  
00300 //
00301 // We choose the latter option.  Every streambuf has pointers to two
00302 // FILE objects, one for the get area and one for the put area.  Ordinarily
00303 // it just uses a FILE object as a convenient way to package the three
00304 // get/put area pointers.  If a basic_streambuf<char> is synchronized with
00305 // a stdio stream, though, then the pointers are to a FILE object that's
00306 // also used by the C library.
00307 //
00308 // The header <stl/_stdio_file.h> encapsulates the implementation details
00309 // of struct FILE.  It contains low-level inline functions that convert
00310 // between whe FILE's internal representation and the three-pointer 
00311 // representation that basic_streambuf<> needs.
00312 
00313 _STLP_TEMPLATE_NULL 
00314 class _STLP_CLASS_DECLSPEC basic_streambuf<char, char_traits<char> >
00315 {
00316   friend class basic_istream<char, char_traits<char> >;
00317   friend class basic_ostream<char, char_traits<char> >;
00318 public:                         // Typedefs.
00319   typedef char                        char_type;
00320   typedef char_traits<char>::int_type int_type;
00321   typedef char_traits<char>::pos_type pos_type;
00322   typedef char_traits<char>::off_type off_type;
00323   typedef char_traits<char>           traits_type;
00324 
00325 private:                        // Data members.
00326 
00327   FILE& _M_get;                 // Reference to the get area
00328   FILE& _M_put;                 // Reference to the put area
00329 
00330 #if defined(__hpux)
00331   _FILEX  _M_default_get;          // Get area, unless we're syncing with stdio.
00332   _FILEX  _M_default_put;          // Put area, unless we're syncing with stdio.
00333 #else
00334   FILE  _M_default_get;          // Get area, unless we're syncing with stdio.
00335   FILE  _M_default_put;          // Put area, unless we're syncing with stdio.
00336 #endif
00337 
00338   locale _M_locale;
00339 
00340 public:                         // Extension: locking, for thread safety.
00341   _STLP_mutex _M_lock;
00342 
00343 public:                         // Destructor.
00344   virtual ~basic_streambuf _STLP_PSPEC2(char, char_traits<char>) ();
00345 
00346 protected:                      // Constructors.
00347 
00348   // The default constructor.
00349   basic_streambuf _STLP_PSPEC2(char, char_traits<char>) ()
00350 # if defined(__MVS__) || defined(__OS400__)
00351  : _M_get(_M_default_get),
00352                _M_put(_M_default_put), _M_locale()
00353                {
00354                // _M_lock._M_initialize();
00355 
00356                _FILE_I_set(_M_get, 0, 0, 0);
00357                _FILE_O_set(_M_put, 0, 0, 0);
00358                }
00359 # else
00360 ;
00361 # endif
00362 
00363   // Extension: a constructor for streambufs synchronized with C stdio files.
00364   basic_streambuf _STLP_PSPEC2(char, char_traits<char>) (FILE* __get, FILE* __put);
00365 
00366 protected:                      // Protected interface to the get area.
00367   char_type* eback() const { return _FILE_I_begin(_M_get); }
00368   char_type* gptr()  const { return _FILE_I_next(_M_get); }
00369   char_type* egptr() const { return _FILE_I_end(_M_get); }
00370   void gbump(int __n) { _FILE_I_bump(_M_get, __n); }
00371   void setg(char_type* __gbegin, char_type* __gnext, char_type* __gend)
00372     { _FILE_I_set(_M_get, __gbegin, __gnext, __gend); }
00373 
00374 public:
00375   // An alternate public interface to the above functions
00376   // which allows us to avoid using templated friends which
00377   // are not supported on some compilers.
00378 
00379   char_type* _M_eback() const { return _FILE_I_begin(_M_get); }
00380   char_type* _M_gptr()  const { return _FILE_I_next(_M_get); }
00381   char_type* _M_egptr() const { return _FILE_I_end(_M_get); }
00382 
00383   void _M_gbump(int __n) { _FILE_I_bump(_M_get, __n); }
00384   void _M_setg(char_type* __gbegin, char_type* __gnext, char_type* __gend)
00385     { _FILE_I_set(_M_get, __gbegin, __gnext, __gend); }
00386 
00387 protected:                      // Protected interface to the put area
00388   char_type* pbase() const { return _FILE_O_begin(_M_put); }
00389   char_type* pptr()  const { return _FILE_O_next(_M_put); }
00390   char_type* epptr() const { return _FILE_O_end(_M_put); }
00391 
00392   void pbump(int __n) { _FILE_O_bump(_M_put, __n); }
00393   void setp(char_type* __pbegin, char_type* __pend)
00394     { _FILE_O_set(_M_put, __pbegin, __pbegin, __pend); }
00395 
00396 protected:                      // Virtual buffer-management functions.
00397   virtual basic_streambuf<char, char_traits<char> >* setbuf(char_type*, streamsize);
00398   virtual pos_type seekoff(off_type, ios_base::seekdir,
00399                            ios_base::openmode = ios_base::in | ios_base::out);
00400   virtual pos_type
00401   seekpos(pos_type, ios_base::openmode = ios_base::in | ios_base::out);
00402   virtual int sync();
00403 
00404 public:                         // Buffer management.
00405   basic_streambuf<char, char_traits<char> >* pubsetbuf(char_type* __s, streamsize __n) 
00406     { return this->setbuf(__s, __n); }
00407 
00408   pos_type pubseekoff(off_type __offset, ios_base::seekdir __way,
00409                       ios_base::openmode __mod = ios_base::in | ios_base::out)
00410     { return this->seekoff(__offset, __way, __mod); }
00411 
00412   pos_type pubseekpos(pos_type __sp,
00413                       ios_base::openmode __mod = ios_base::in | ios_base::out)
00414     { return this->seekpos(__sp, __mod); }
00415 
00416   int pubsync() { return this->sync(); }
00417 
00418 protected:                      // Virtual get area functions.
00419   virtual streamsize showmanyc();
00420   virtual streamsize xsgetn(char_type* __s, streamsize __n);
00421   virtual int_type underflow();
00422   virtual int_type uflow();
00423   virtual int_type pbackfail(int_type __c = traits_type::eof());
00424 
00425 protected:                      // Virtual put area functions.
00426   virtual streamsize xsputn(const char_type* __s, streamsize __n);
00427   virtual streamsize _M_xsputnc(char_type __c, streamsize __n);
00428   virtual int_type overflow(int_type = traits_type::eof());
00429 
00430 public:                         // Public members for writing characters.
00431   // Write a single character.
00432   int_type sputc(char_type __c) {
00433     int_type __res;
00434         if( _FILE_O_avail(_M_put) > 0 )
00435         {
00436                 _FILE_O_postincr(_M_put) = __c;
00437                 __res = traits_type::to_int_type(__c);
00438         }
00439         else
00440       __res = this->overflow(traits_type::to_int_type(__c));
00441     return __res;
00442   }
00443 
00444   // Write __n characters.
00445   streamsize sputn(const char_type* __s, streamsize __n)
00446     { return this->xsputn(__s, __n); }
00447 
00448   // Extension: write __n copies of __c.
00449   streamsize _M_sputnc(char_type __c, streamsize __n)
00450     { return this->_M_xsputnc(__c, __n); }
00451 
00452 private:                        // Helper functions.
00453   int_type _M_snextc_aux();
00454 
00455 public:                         // Public members for reading characters.
00456   streamsize in_avail()
00457     { return _FILE_I_avail(_M_get) > 0 ? _FILE_I_avail(_M_get) 
00458                                      : this->showmanyc(); }
00459   
00460   // Advance to the next character and return it.
00461   int_type snextc() {
00462     return _FILE_I_avail(_M_get) > 1
00463       ? traits_type::to_int_type(_FILE_I_preincr(_M_get))
00464       : this->_M_snextc_aux();
00465   }
00466 
00467   // Return the current character and advance to the next.
00468   int_type sbumpc() {
00469     return _FILE_I_avail(_M_get) > 0
00470       ? traits_type::to_int_type(_FILE_I_postincr(_M_get))
00471       : this->uflow();
00472   }
00473 
00474   // Return the current character without advancing to the next.
00475   int_type sgetc() {
00476     return _FILE_I_avail(_M_get) > 0
00477       ? traits_type::to_int_type(*_FILE_I_next(_M_get))
00478       : this->underflow();
00479   }
00480     
00481   streamsize sgetn(char_type* __s, streamsize __n)
00482     { return this->xsgetn(__s, __n); }
00483 
00484   int_type sputbackc(char_type __c) {
00485     return _FILE_I_begin(_M_get) < _FILE_I_next(_M_get) &&
00486            __c == *(_FILE_I_next(_M_get) - 1)
00487       ? traits_type::to_int_type(_FILE_I_predecr(_M_get))
00488       : this->pbackfail(traits_type::to_int_type(__c));
00489   }
00490 
00491   int_type sungetc() {
00492     return _FILE_I_begin(_M_get) < _FILE_I_next(_M_get)
00493       ? traits_type::to_int_type(_FILE_I_predecr(_M_get))
00494       : this->pbackfail();
00495   }
00496 
00497 protected:                      // Virtual locale functions.
00498   virtual void imbue(const locale&);
00499 
00500 public:                         // Locale-related functions.
00501   locale pubimbue(const locale&);
00502   locale getloc() const { return _M_locale; }
00503 
00504 # ifndef _STLP_NO_ANACHRONISMS
00505 public:
00506   void stossc() { this->sbumpc(); }
00507 # endif
00508 
00509 #if defined(__MVS__) || defined(__OS400__)
00510 private: // Data members.
00511 
00512   char_type* _M_gbegin; // Beginning of get area
00513   char_type* _M_gnext; // Current position within the get area
00514   char_type* _M_gend; // End of get area
00515 
00516   char_type* _M_pbegin; // Beginning of put area
00517   char_type* _M_pnext; // Current position within the put area
00518   char_type* _M_pend; // End of put area
00519 #endif
00520 
00521 };
00522 _STLP_END_NAMESPACE
00523 
00524 # if defined (_STLP_EXPOSE_STREAM_IMPLEMENTATION) && !defined (_STLP_LINK_TIME_INSTANTIATION)
00525 #  include <stl/_streambuf.c>
00526 # endif
00527 
00528 #endif
00529 // Local Variables:
00530 // mode:C++
00531 // End:

Generated on Mon Jun 5 10:20:47 2006 for Intelligence.kdevelop by  doxygen 1.4.6