home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / stlpt453.zip / STLport-4.5.3 / stlport / stl / _streambuf.h < prev    next >
C/C++ Source or Header  |  2002-01-18  |  20KB  |  527 lines

  1. /*
  2.  * Copyright (c) 1999
  3.  * Silicon Graphics Computer Systems, Inc.
  4.  *
  5.  * Copyright (c) 1999 
  6.  * Boris Fomitchev
  7.  *
  8.  * This material is provided "as is", with absolutely no warranty expressed
  9.  * or implied. Any use is at your own risk.
  10.  *
  11.  * Permission to use or copy this software for any purpose is hereby granted 
  12.  * without fee, provided the above notices are retained on all copies.
  13.  * Permission to modify the code and to distribute modified code is granted,
  14.  * provided the above notices are retained, and a notice that the code was
  15.  * modified is included with the above copyright notice.
  16.  *
  17.  */ 
  18. #ifndef _STLP_INTERNAL_STREAMBUF
  19. #define _STLP_INTERNAL_STREAMBUF
  20.  
  21. #ifndef _STLP_IOS_BASE_H
  22. #include <stl/_ios_base.h>      // Needed for ios_base bitfield members.
  23.                                 // <ios_base> includes <iosfwd>.
  24. #endif
  25.  
  26. #ifndef _STLP_STDIO_FILE_H
  27. #include <stl/_stdio_file.h>     // Declaration of struct FILE, and of
  28.                                 // functions to manipulate it.
  29. #endif
  30.  
  31. _STLP_BEGIN_NAMESPACE
  32.  
  33. //----------------------------------------------------------------------
  34. // Class basic_streambuf<>, the base class of the streambuf hierarchy.
  35.  
  36. // A basic_streambuf<> manages an input (get) area and an output (put)
  37. // area.  Each is described by three pointers: a beginning, an end, and a
  38. // current position.  basic_streambuf<> contains some very simple member
  39. // functions that manipulate those six pointers, but almost all of the real
  40. // functionality gets delegated to protected virtual member functions.
  41. // All of the public member functions are inline, and most of the protected
  42. // member functions are virtual.
  43.  
  44. // Although basic_streambuf<> is not abstract, it is useful only as a base
  45. // class.  Its virtual member functions have default definitions such that
  46. // reading from a basic_streambuf<> will always yield EOF, and writing to a
  47. // basic_streambuf<> will always fail.
  48.  
  49. // The second template parameter, _Traits, defaults to char_traits<_CharT>.
  50. // The default is declared in header <iosfwd>, and it isn't declared here
  51. // because C++ language rules do not allow it to be declared twice. 
  52.  
  53. template <class _CharT, class _Traits>
  54. class basic_streambuf
  55. {
  56.   friend class basic_istream<_CharT, _Traits>;
  57.   friend class basic_ostream<_CharT, _Traits>;
  58.  
  59. public:                         // Typedefs.
  60.   typedef _CharT                     char_type;
  61.   typedef typename _Traits::int_type int_type;
  62.   typedef typename _Traits::pos_type pos_type;
  63.   typedef typename _Traits::off_type off_type;
  64.   typedef _Traits                    traits_type;
  65.  
  66. private:                        // Data members.
  67.  
  68.   char_type* _M_gbegin;         // Beginning of get area
  69.   char_type* _M_gnext;          // Current position within the get area
  70.   char_type* _M_gend;           // End of get area
  71.  
  72.   char_type* _M_pbegin;         // Beginning of put area
  73.   char_type* _M_pnext;          // Current position within the put area
  74.   char_type* _M_pend;           // End of put area
  75.  
  76.   locale _M_locale;             // The streambuf's locale object
  77.  
  78. public:                         // Extension: locking, for thread safety.
  79.   _STLP_mutex _M_lock;
  80.  
  81. public:                         // Destructor.
  82.   virtual ~basic_streambuf();
  83.  
  84. protected:                      // The default constructor.
  85.   basic_streambuf();
  86.  
  87. protected:                      // Protected interface to the get area.
  88.   char_type* eback() const { return _M_gbegin; } // Beginning
  89.   char_type* gptr()  const { return _M_gnext; }  // Current position
  90.   char_type* egptr() const { return _M_gend; }   // End
  91.   
  92.   void gbump(int __n) { _M_gnext += __n; }
  93.   void setg(char_type* __gbegin, char_type* __gnext, char_type* __gend) {
  94.     _M_gbegin = __gbegin;
  95.     _M_gnext  = __gnext;
  96.     _M_gend   = __gend;
  97.   }
  98.  
  99. public:
  100.   // An alternate public interface to the above functions
  101.   // which allows us to avoid using templated friends which
  102.   // are not supported on some compilers.
  103.  
  104.   char_type* _M_eback() const { return eback(); }
  105.   char_type* _M_gptr()  const { return gptr(); }
  106.   char_type* _M_egptr() const { return egptr(); }
  107.   void _M_gbump(int __n)      { gbump(__n); }
  108.   void _M_setg(char_type* __gbegin, char_type* __gnext, char_type* __gend)
  109.     { setg(__gbegin, __gnext, __gend); }
  110.  
  111. protected:                      // Protected interface to the put area
  112.  
  113.   char_type* pbase() const { return _M_pbegin; } // Beginning
  114.   char_type* pptr()  const { return _M_pnext; }  // Current position
  115.   char_type* epptr() const { return _M_pend; }   // End
  116.  
  117.   void pbump(int __n) { _M_pnext += __n; }
  118.   void setp(char_type* __pbegin, char_type* __pend) {
  119.     _M_pbegin = __pbegin;
  120.     _M_pnext  = __pbegin;
  121.     _M_pend   = __pend;
  122.   }
  123.  
  124. protected:                      // Virtual buffer management functions.
  125.  
  126.   virtual basic_streambuf<_CharT, _Traits>* setbuf(char_type*, streamsize);
  127.  
  128.   // Alters the stream position, using an integer offset.  In this
  129.   // class seekoff does nothing; subclasses are expected to override it.
  130.   virtual pos_type seekoff(off_type, ios_base::seekdir,
  131.                            ios_base::openmode = ios_base::in | ios_base::out);
  132.  
  133.   // Alters the stream position, using a previously obtained streampos.  In
  134.   // this class seekpos does nothing; subclasses are expected to override it.
  135.   virtual pos_type
  136.   seekpos(pos_type, ios_base::openmode = ios_base::in | ios_base::out);
  137.  
  138.   // Synchronizes (i.e. flushes) the buffer.  All subclasses are expected to 
  139.   // override this virtual member function.
  140.   virtual int sync();
  141.  
  142.  
  143. public:                         // Buffer management.
  144.   basic_streambuf<_CharT, _Traits>* pubsetbuf(char_type* __s, streamsize __n) 
  145.     { return this->setbuf(__s, __n); }
  146.  
  147.   pos_type pubseekoff(off_type __offset, ios_base::seekdir __way,
  148.                       ios_base::openmode __mod = ios_base::in | ios_base::out)
  149.     { return this->seekoff(__offset, __way, __mod); }
  150.  
  151.   pos_type pubseekpos(pos_type __sp,
  152.                       ios_base::openmode __mod = ios_base::in | ios_base::out)
  153.     { return this->seekpos(__sp, __mod); }
  154.  
  155.   int pubsync() { return this->sync(); }
  156.  
  157. protected:                      // Virtual get area functions, as defined in
  158.                                 // 17.5.2.4.3 and 17.5.2.4.4 of the standard.
  159.   // Returns a lower bound on the number of characters that we can read,
  160.   // with underflow, before reaching end of file.  (-1 is a special value:
  161.   // it means that underflow will fail.)  Most subclasses should probably
  162.   // override this virtual member function.
  163.   virtual streamsize showmanyc();
  164.  
  165.   // Reads up to __n characters.  Return value is the number of 
  166.   // characters read.
  167.   virtual streamsize xsgetn(char_type* __s, streamsize __n);
  168.  
  169.   // Called when there is no read position, i.e. when gptr() is null
  170.   // or when gptr() >= egptr().  Subclasses are expected to override
  171.   // this virtual member function.
  172.   virtual int_type underflow();
  173.  
  174.   // Similar to underflow(), but used for unbuffered input.  Most 
  175.   // subclasses should probably override this virtual member function.
  176.   virtual int_type uflow();
  177.  
  178.   // Called when there is no putback position, i.e. when gptr() is null
  179.   // or when gptr() == eback().  All subclasses are expected to override
  180.   // this virtual member function.
  181.   virtual int_type pbackfail(int_type = traits_type::eof());
  182.  
  183. protected:                      // Virtual put area functions, as defined in
  184.                                 // 27.5.2.4.5 of the standard.
  185.  
  186.   // Writes up to __n characters.  Return value is the number of characters
  187.   // written.
  188.   virtual streamsize xsputn(const char_type* __s, streamsize __n);
  189.  
  190.   // Extension: writes up to __n copies of __c.  Return value is the number
  191.   // of characters written.
  192.   virtual streamsize _M_xsputnc(char_type __c, streamsize __n);
  193.  
  194.   // Called when there is no write position.  All subclasses are expected to
  195.   // override this virtual member function.
  196.   virtual int_type overflow(int_type = traits_type::eof());
  197.  
  198. public:                         // Public members for writing characters.
  199.   // Write a single character.
  200.   int_type sputc(char_type __c) {
  201.     return ((_M_pnext < _M_pend) ? _Traits::to_int_type(*_M_pnext++ = __c)
  202.       : this->overflow(_Traits::to_int_type(__c)));
  203.   }
  204.  
  205.   // Write __n characters.
  206.   streamsize sputn(const char_type* __s, streamsize __n)
  207.     { return this->xsputn(__s, __n); }
  208.  
  209.   // Extension: write __n copies of __c.
  210.   streamsize _M_sputnc(char_type __c, streamsize __n)
  211.     { return this->_M_xsputnc(__c, __n); }
  212.  
  213. private:                        // Helper functions.
  214.   int_type _M_snextc_aux();
  215.  
  216.  
  217. public:                         // Public members for reading characters.
  218.   streamsize in_avail() {
  219.     return (_M_gnext < _M_gend) ? (_M_gend - _M_gnext) : this->showmanyc();
  220.   }
  221.   
  222.   // Advance to the next character and return it.
  223.   int_type snextc() {
  224.     return ( _M_gend - _M_gnext > 1 ?
  225.              _Traits::to_int_type(*++_M_gnext) :
  226.              this->_M_snextc_aux());
  227.   }
  228.  
  229.   // Return the current character and advance to the next.
  230.   int_type sbumpc() {
  231.     return _M_gnext < _M_gend ? _Traits::to_int_type(*_M_gnext++) 
  232.       : this->uflow();
  233.   }
  234.   
  235.   // Return the current character without advancing to the next.
  236.   int_type sgetc() {
  237.     return _M_gnext < _M_gend ? _Traits::to_int_type(*_M_gnext) 
  238.       : this->underflow();
  239.   }
  240.   
  241.   streamsize sgetn(char_type* __s, streamsize __n)
  242.   { return this->xsgetn(__s, __n); }
  243.   
  244.   int_type sputbackc(char_type __c) {
  245.     return ((_M_gbegin < _M_gnext) && _Traits::eq(__c, *(_M_gnext - 1)))
  246.       ? _Traits::to_int_type(*--_M_gnext)
  247.       : this->pbackfail(_Traits::to_int_type(__c));
  248.   }
  249.   
  250.   int_type sungetc() {
  251.     return (_M_gbegin < _M_gnext)
  252.       ? _Traits::to_int_type(*--_M_gnext)
  253.       : this->pbackfail();
  254.   }
  255.  
  256. protected:                      // Virtual locale functions.
  257.  
  258.   // This is a hook, called by pubimbue() just before pubimbue()
  259.   // sets the streambuf's locale to __loc.  Note that imbue should
  260.   // not (and cannot, since it has no access to streambuf's private
  261.   // members) set the streambuf's locale itself.
  262.   virtual void imbue(const locale&);
  263.  
  264. public:                         // Locale-related functions.
  265.   locale pubimbue(const locale&);
  266.   locale getloc() const { return _M_locale; }
  267.  
  268. # ifndef _STLP_NO_ANACHRONISMS
  269.   void stossc() { this->sbumpc(); }
  270. # endif
  271. #if defined(__MVS__) || defined(__OS400__)
  272. private: // Data members.
  273.  
  274.   char_type* _M_gbegin; // Beginning of get area
  275.   char_type* _M_gnext; // Current position within the get area
  276.   char_type* _M_gend; // End of get area
  277.  
  278.   char_type* _M_pbegin; // Beginning of put area
  279.   char_type* _M_pnext; // Current position within the put area
  280.   char_type* _M_pend; // End of put area
  281. #endif
  282. };
  283.  
  284.  
  285. //----------------------------------------------------------------------
  286. // Specialization: basic_streambuf<char, char_traits<char> >
  287.  
  288. // We implement basic_streambuf<char, char_traits<char> > very differently
  289. // than the general basic_streambuf<> template.  The main reason for this
  290. // difference is a requirement in the C++ standard: the standard input
  291. // and output streams cin and cout are required by default to be synchronized
  292. // with the C library components stdin and stdout.  This means it must be
  293. // possible to synchronize a basic_streambuf<char> with a C buffer.
  294. //
  295. // There are two basic ways to do that.  First, the streambuf could be
  296. // unbuffered and delegate all buffering to stdio operations.  This
  297. // would be correct, but slow: it would require at least one virtual
  298. // function call for every character.  Second, the streambuf could use 
  299. // a C stdio FILE as its buffer.  
  300. //
  301. // We choose the latter option.  Every streambuf has pointers to two
  302. // FILE objects, one for the get area and one for the put area.  Ordinarily
  303. // it just uses a FILE object as a convenient way to package the three
  304. // get/put area pointers.  If a basic_streambuf<char> is synchronized with
  305. // a stdio stream, though, then the pointers are to a FILE object that's
  306. // also used by the C library.
  307. //
  308. // The header <stl/_stdio_file.h> encapsulates the implementation details
  309. // of struct FILE.  It contains low-level inline functions that convert
  310. // between whe FILE's internal representation and the three-pointer 
  311. // representation that basic_streambuf<> needs.
  312.  
  313. _STLP_TEMPLATE_NULL 
  314. class _STLP_CLASS_DECLSPEC basic_streambuf<char, char_traits<char> >
  315. {
  316.   friend class basic_istream<char, char_traits<char> >;
  317.   friend class basic_ostream<char, char_traits<char> >;
  318. public:                         // Typedefs.
  319.   typedef char                        char_type;
  320.   typedef char_traits<char>::int_type int_type;
  321.   typedef char_traits<char>::pos_type pos_type;
  322.   typedef char_traits<char>::off_type off_type;
  323.   typedef char_traits<char>           traits_type;
  324.  
  325. private:                        // Data members.
  326.  
  327.   FILE* _M_get;                 // Reference to the get area
  328.   FILE* _M_put;                 // Reference to the put area
  329.  
  330. #if defined(__hpux)
  331.   _FILEX  _M_default_get;          // Get area, unless we're syncing with stdio.
  332.   _FILEX  _M_default_put;          // Put area, unless we're syncing with stdio.
  333. #else
  334.   FILE  _M_default_get;          // Get area, unless we're syncing with stdio.
  335.   FILE  _M_default_put;          // Put area, unless we're syncing with stdio.
  336. #endif
  337.  
  338.   locale _M_locale;
  339.  
  340. public:                         // Extension: locking, for thread safety.
  341.   _STLP_mutex _M_lock;
  342.  
  343. public:                         // Destructor.
  344.   virtual ~basic_streambuf _STLP_PSPEC2(char, char_traits<char>) ();
  345.  
  346. protected:                      // Constructors.
  347.  
  348.   // The default constructor; defined here inline as some compilers require it
  349.   basic_streambuf _STLP_PSPEC2(char, char_traits<char>) ()
  350.     : _M_get(&_M_default_get),
  351.       _M_put(&_M_default_put), _M_locale()
  352.   {
  353.     // _M_lock._M_initialize();
  354.     _FILE_I_set(_M_get, 0, 0, 0);
  355.     _FILE_O_set(_M_put, 0, 0, 0);
  356.   }
  357.   
  358.   // Extension: a constructor for streambufs synchronized with C stdio files.
  359.   basic_streambuf _STLP_PSPEC2(char, char_traits<char>) (FILE* __get, FILE* __put);
  360.  
  361. protected:                      // Protected interface to the get area.
  362.   char_type* eback() const { return _FILE_I_begin(_M_get); }
  363.   char_type* gptr()  const { return _FILE_I_next(_M_get); }
  364.   char_type* egptr() const { return _FILE_I_end(_M_get); }
  365.   void gbump(int __n) { _FILE_I_bump(_M_get, __n); }
  366.   void setg(char_type* __gbegin, char_type* __gnext, char_type* __gend)
  367.     { _FILE_I_set(_M_get, __gbegin, __gnext, __gend); }
  368.  
  369. public:
  370.   // An alternate public interface to the above functions
  371.   // which allows us to avoid using templated friends which
  372.   // are not supported on some compilers.
  373.  
  374.   char_type* _M_eback() const { return _FILE_I_begin(_M_get); }
  375.   char_type* _M_gptr()  const { return _FILE_I_next(_M_get); }
  376.   char_type* _M_egptr() const { return _FILE_I_end(_M_get); }
  377.  
  378.   void _M_gbump(int __n) { _FILE_I_bump(_M_get, __n); }
  379.   void _M_setg(char_type* __gbegin, char_type* __gnext, char_type* __gend)
  380.     { _FILE_I_set(_M_get, __gbegin, __gnext, __gend); }
  381.  
  382. protected:                      // Protected interface to the put area
  383.   char_type* pbase() const { return _FILE_O_begin(_M_put); }
  384.   char_type* pptr()  const { return _FILE_O_next(_M_put); }
  385.   char_type* epptr() const { return _FILE_O_end(_M_put); }
  386.  
  387.   void pbump(int __n) { _FILE_O_bump(_M_put, __n); }
  388.   void setp(char_type* __pbegin, char_type* __pend)
  389.     { _FILE_O_set(_M_put, __pbegin, __pbegin, __pend); }
  390.  
  391. protected:                      // Virtual buffer-management functions.
  392.   virtual basic_streambuf<char, char_traits<char> >* setbuf(char_type*, streamsize);
  393.   virtual pos_type seekoff(off_type, ios_base::seekdir,
  394.                            ios_base::openmode = ios_base::in | ios_base::out);
  395.   virtual pos_type
  396.   seekpos(pos_type, ios_base::openmode = ios_base::in | ios_base::out);
  397.   virtual int sync();
  398.  
  399. public:                         // Buffer management.
  400.   basic_streambuf<char, char_traits<char> >* pubsetbuf(char_type* __s, streamsize __n) 
  401.     { return this->setbuf(__s, __n); }
  402.  
  403.   pos_type pubseekoff(off_type __offset, ios_base::seekdir __way,
  404.                       ios_base::openmode __mod = ios_base::in | ios_base::out)
  405.     { return this->seekoff(__offset, __way, __mod); }
  406.  
  407.   pos_type pubseekpos(pos_type __sp,
  408.                       ios_base::openmode __mod = ios_base::in | ios_base::out)
  409.     { return this->seekpos(__sp, __mod); }
  410.  
  411.   int pubsync() { return this->sync(); }
  412.  
  413. protected:                      // Virtual get area functions.
  414.   virtual streamsize showmanyc();
  415.   virtual streamsize xsgetn(char_type* __s, streamsize __n);
  416.   virtual int_type underflow();
  417.   virtual int_type uflow();
  418.   virtual int_type pbackfail(int_type __c = traits_type::eof());
  419.  
  420. protected:                      // Virtual put area functions.
  421.   virtual streamsize xsputn(const char_type* __s, streamsize __n);
  422.   virtual streamsize _M_xsputnc(char_type __c, streamsize __n);
  423.   virtual int_type overflow(int_type = traits_type::eof());
  424.  
  425. public:                         // Public members for writing characters.
  426.   // Write a single character.
  427.   int_type sputc(char_type __c) {
  428.     int_type __res;
  429.     if( _FILE_O_avail(_M_put) > 0 )
  430.     {
  431.         _FILE_O_postincr(_M_put) = __c;
  432.         __res = traits_type::to_int_type(__c);
  433.     }
  434.     else
  435.       __res = this->overflow(traits_type::to_int_type(__c));
  436.     return __res;
  437.   }
  438.  
  439.   // Write __n characters.
  440.   streamsize sputn(const char_type* __s, streamsize __n)
  441.     { return this->xsputn(__s, __n); }
  442.  
  443.   // Extension: write __n copies of __c.
  444.   streamsize _M_sputnc(char_type __c, streamsize __n)
  445.     { return this->_M_xsputnc(__c, __n); }
  446.  
  447. private:                        // Helper functions.
  448.   int_type _M_snextc_aux();
  449.  
  450. public:                         // Public members for reading characters.
  451.   streamsize in_avail()
  452.     { return _FILE_I_avail(_M_get) > 0 ? _FILE_I_avail(_M_get) 
  453.                                      : this->showmanyc(); }
  454.   
  455.   // Advance to the next character and return it.
  456.   int_type snextc() {
  457.     return _FILE_I_avail(_M_get) > 1
  458.       ? traits_type::to_int_type(_FILE_I_preincr(_M_get))
  459.       : this->_M_snextc_aux();
  460.   }
  461.  
  462.   // Return the current character and advance to the next.
  463.   int_type sbumpc() {
  464.     return _FILE_I_avail(_M_get) > 0
  465.       ? traits_type::to_int_type(_FILE_I_postincr(_M_get))
  466.       : this->uflow();
  467.   }
  468.  
  469.   // Return the current character without advancing to the next.
  470.   int_type sgetc() {
  471.     return _FILE_I_avail(_M_get) > 0
  472.       ? traits_type::to_int_type(*_FILE_I_next(_M_get))
  473.       : this->underflow();
  474.   }
  475.     
  476.   streamsize sgetn(char_type* __s, streamsize __n)
  477.     { return this->xsgetn(__s, __n); }
  478.  
  479.   int_type sputbackc(char_type __c) {
  480.     return _FILE_I_begin(_M_get) < _FILE_I_next(_M_get) &&
  481.            __c == *(_FILE_I_next(_M_get) - 1)
  482.       ? traits_type::to_int_type(_FILE_I_predecr(_M_get))
  483.       : this->pbackfail(traits_type::to_int_type(__c));
  484.   }
  485.  
  486.   int_type sungetc() {
  487.     return _FILE_I_begin(_M_get) < _FILE_I_next(_M_get)
  488.       ? traits_type::to_int_type(_FILE_I_predecr(_M_get))
  489.       : this->pbackfail();
  490.   }
  491.  
  492. protected:                      // Virtual locale functions.
  493.   virtual void imbue(const locale&);
  494.  
  495. public:                         // Locale-related functions.
  496.   locale pubimbue(const locale&);
  497.   locale getloc() const { return _M_locale; }
  498.  
  499. # ifndef _STLP_NO_ANACHRONISMS
  500. public:
  501.   void stossc() { this->sbumpc(); }
  502. # endif
  503.  
  504. #if defined(__MVS__) || defined(__OS400__)
  505. private: // Data members.
  506.  
  507.   char_type* _M_gbegin; // Beginning of get area
  508.   char_type* _M_gnext; // Current position within the get area
  509.   char_type* _M_gend; // End of get area
  510.  
  511.   char_type* _M_pbegin; // Beginning of put area
  512.   char_type* _M_pnext; // Current position within the put area
  513.   char_type* _M_pend; // End of put area
  514. #endif
  515.  
  516. };
  517. _STLP_END_NAMESPACE
  518.  
  519. # if defined (_STLP_EXPOSE_STREAM_IMPLEMENTATION) && !defined (_STLP_LINK_TIME_INSTANTIATION)
  520. #  include <stl/_streambuf.c>
  521. # endif
  522.  
  523. #endif
  524. // Local Variables:
  525. // mode:C++
  526. // End:
  527.