Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. // File based streams -*- C++ -*-
  2.  
  3. // Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
  4. //
  5. // This file is part of the GNU ISO C++ Library.  This library is free
  6. // software; you can redistribute it and/or modify it under the
  7. // terms of the GNU General Public License as published by the
  8. // Free Software Foundation; either version 2, or (at your option)
  9. // any later version.
  10.  
  11. // This library is distributed in the hope that it will be useful,
  12. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. // GNU General Public License for more details.
  15.  
  16. // You should have received a copy of the GNU General Public License along
  17. // with this library; see the file COPYING.  If not, write to the Free
  18. // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
  19. // USA.
  20.  
  21. // As a special exception, you may use this file as part of a free software
  22. // library without restriction.  Specifically, if other files instantiate
  23. // templates or use macros or inline functions from this file, or you compile
  24. // this file and link it with other files to produce an executable, this
  25. // file does not by itself cause the resulting executable to be covered by
  26. // the GNU General Public License.  This exception does not however
  27. // invalidate any other reasons why the executable file might be covered by
  28. // the GNU General Public License.
  29.  
  30. //
  31. // ISO C++ 14882: 27.8  File-based streams
  32. //
  33.  
  34. #ifndef _CPP_FSTREAM
  35. #define _CPP_FSTREAM    1
  36.  
  37. #pragma GCC system_header
  38.  
  39. #include <bits/std_istream.h>
  40. #include <bits/std_ostream.h>
  41. #include <bits/basic_file.h>
  42. #include <bits/std_locale.h>    // For codecvt
  43. #include <bits/gthr.h>
  44.  
  45. namespace std
  46. {
  47.   template<typename _CharT, typename _Traits>
  48.     class basic_filebuf : public basic_streambuf<_CharT, _Traits>
  49.     {
  50.     public:
  51.       // Types:
  52.       typedef _CharT                                    char_type;
  53.       typedef _Traits                                   traits_type;
  54.       typedef typename traits_type::int_type            int_type;
  55.       typedef typename traits_type::pos_type            pos_type;
  56.       typedef typename traits_type::off_type            off_type;
  57.      
  58.       // Non-standard Types:
  59.       typedef basic_streambuf<char_type, traits_type>   __streambuf_type;
  60.       typedef basic_filebuf<char_type, traits_type>     __filebuf_type;
  61.       typedef __basic_file<char_type>                   __file_type;
  62.       typedef typename traits_type::state_type          __state_type;
  63.       typedef codecvt<char_type, char, __state_type>    __codecvt_type;
  64.       typedef typename __codecvt_type::result           __res_type;
  65.       typedef ctype<char_type>                          __ctype_type;
  66.  
  67.       friend class ios_base; // For sync_with_stdio.
  68.  
  69.     private:
  70.       // Data Members:
  71.       // External buffer.
  72.       __file_type*              _M_file;
  73.  
  74.       // Current and beginning state type for codecvt.
  75.       __state_type              _M_state_cur;
  76.       __state_type              _M_state_beg;  
  77.  
  78.       // MT lock inherited from libio or other low-level io library.
  79.       __c_lock                  _M_lock;
  80.  
  81.       // Set iff _M_buf is allocated memory from _M_allocate_internal_buffer..
  82.       bool                      _M_buf_allocated;
  83.  
  84.       // XXX Needed?
  85.       bool                      _M_last_overflowed;  
  86.  
  87.     public:
  88.       // Constructors/destructor:
  89.       basic_filebuf();
  90.  
  91.       // Non-standard ctor:
  92.       basic_filebuf(__c_file_type* __f, ios_base::openmode __mode,
  93.                     int_type __s = static_cast<int_type>(BUFSIZ));
  94.  
  95.       virtual
  96.       ~basic_filebuf()
  97.       {
  98.         this->close();
  99.         _M_last_overflowed = false;
  100.       }
  101.  
  102.       // Members:
  103.       bool
  104.       is_open(void) const { return _M_file ? _M_file->is_open() : false; }
  105.    
  106.       __filebuf_type*
  107.       open(const char* __s, ios_base::openmode __mode);
  108.    
  109.       __filebuf_type*
  110.       close(void);
  111.  
  112.     protected:
  113.       void
  114.       _M_allocate_internal_buffer();
  115.  
  116.       void
  117.       _M_destroy_internal_buffer();
  118.  
  119.       void
  120.       _M_allocate_pback_buffer();
  121.  
  122.       // Create __file_type object and initialize it properly.
  123.       void
  124.       _M_allocate_file();
  125.  
  126.       // Overridden virtual functions:
  127.       virtual streamsize
  128.       showmanyc(void);
  129.    
  130.       // Stroustrup, 1998, p. 628
  131.       // underflow() and uflow() functions are called to get the next
  132.       // charater from the real input source when the buffer is empty.
  133.       // Buffered input uses underflow()
  134.       virtual int_type
  135.       underflow(void);
  136.  
  137.       virtual int_type
  138.       pbackfail(int_type __c = _Traits::eof());
  139.  
  140.       // NB: For what the standard expects of the overflow function,
  141.       // see _M_really_overflow(), below. Because basic_streambuf's
  142.       // sputc/sputn call overflow directly, and the complications of
  143.       // this implementation's setting of the initial pointers all
  144.       // equal to _M_buf when initializing, it seems essential to have
  145.       // this in actuality be a helper function that checks for the
  146.       // eccentricities of this implementation, and then call
  147.       // overflow() if indeed the buffer is full.
  148.       virtual int_type
  149.       overflow(int_type __c = _Traits::eof());
  150.  
  151.       // Stroustrup, 1998, p 648
  152.       // The overflow() function is called to transfer characters to the
  153.       // real output destination when the buffer is full. A call to
  154.       // overflow(c) outputs the contents of the buffer plus the
  155.       // character c.
  156.       // 27.5.2.4.5
  157.       // Consume some sequence of the characters in the pending sequence.
  158.       int_type
  159.       _M_really_overflow(int_type __c = _Traits::eof());
  160.    
  161.       virtual __streambuf_type*
  162.       setbuf(char_type* __s, streamsize __n);
  163.    
  164.       virtual pos_type
  165.       seekoff(off_type __off, ios_base::seekdir __way,
  166.               ios_base::openmode __mode = ios_base::in | ios_base::out);
  167.  
  168.       virtual pos_type
  169.       seekpos(pos_type __pos,
  170.               ios_base::openmode __mode = ios_base::in | ios_base::out);
  171.  
  172.       virtual int
  173.       sync(void)
  174.       {
  175.         bool __testput = _M_out_cur && _M_out_beg < _M_out_end;
  176.         if (__testput)
  177.           {
  178.             // Make sure that libio resyncs its idea of the file position
  179.             // with the external file.
  180.             _M_file->sync();
  181.  
  182.             // Need to restore current position. This interpreted as
  183.             // the position of the external byte sequence (_M_file)
  184.             // plus the offset in the current internal buffer
  185.             // (_M_out_beg - _M_out_cur)
  186.             streamoff __cur = _M_file->seekoff(0, ios_base::cur);
  187.             off_type __off = _M_out_cur - _M_out_beg;
  188.             _M_really_overflow();
  189.             _M_file->seekpos(__cur + __off);
  190.           }
  191.         _M_last_overflowed = false;    
  192.         return 0;
  193.       }
  194.      
  195.       virtual void
  196.       imbue(const locale& __loc);
  197.  
  198.       virtual streamsize
  199.       xsgetn(char_type* __s, streamsize __n)
  200.       {
  201.         streamsize __ret = 0;
  202.         // Clear out pback buffer before going on to the real deal...
  203.         if (_M_pback_init)
  204.           {
  205.             while (__ret < __n && _M_in_cur < _M_in_end)
  206.               {
  207.                 *__s = *_M_in_cur;
  208.                 ++__ret;
  209.                 ++__s;
  210.                 ++_M_in_cur;
  211.               }
  212.             _M_pback_destroy();
  213.           }
  214.         if (__ret < __n)
  215.           __ret += __streambuf_type::xsgetn(__s, __n - __ret);
  216.         return __ret;
  217.       }
  218.  
  219.       virtual streamsize
  220.       xsputn(const char_type* __s, streamsize __n)
  221.       {
  222.         _M_pback_destroy();
  223.         return __streambuf_type::xsputn(__s, __n);
  224.       }
  225.        
  226.       void
  227.       _M_output_unshift();
  228.     };
  229.  
  230.  
  231.   // 27.8.1.5  Template class basic_ifstream
  232.   template<typename _CharT, typename _Traits>
  233.     class basic_ifstream : public basic_istream<_CharT, _Traits>
  234.     {
  235.     public:
  236.       // Types:
  237.       typedef _CharT                                    char_type;
  238.       typedef _Traits                                   traits_type;
  239.       typedef typename traits_type::int_type            int_type;
  240.       typedef typename traits_type::pos_type            pos_type;
  241.       typedef typename traits_type::off_type            off_type;
  242.  
  243.       // Non-standard types:
  244.       typedef basic_filebuf<char_type, traits_type>     __filebuf_type;
  245.       typedef basic_istream<char_type, traits_type>     __istream_type;
  246.    
  247.     private:
  248.       __filebuf_type    _M_filebuf;
  249.  
  250.     public:
  251.      // Constructors/Destructors:
  252.       basic_ifstream()
  253.       : __istream_type(NULL), _M_filebuf()
  254.       { this->init(&_M_filebuf); }
  255.  
  256.       explicit
  257.       basic_ifstream(const char* __s, ios_base::openmode __mode = ios_base::in)
  258.       : __istream_type(NULL), _M_filebuf()
  259.       {
  260.         this->init(&_M_filebuf);
  261.         this->open(__s, __mode);
  262.       }
  263.    
  264.       ~basic_ifstream()
  265.       { }
  266.  
  267.       // Members:
  268.       __filebuf_type*
  269.       rdbuf() const
  270.       { return const_cast<__filebuf_type*>(&_M_filebuf); }
  271.  
  272.       bool
  273.       is_open(void) { return _M_filebuf.is_open(); }
  274.  
  275.       void
  276.       open(const char* __s, ios_base::openmode __mode = ios_base::in)
  277.       {
  278.         if (_M_filebuf.open(__s, __mode | ios_base::in) == NULL)
  279.           this->setstate(ios_base::failbit);
  280.       }
  281.  
  282.       void
  283.       close(void)
  284.       {
  285.         if (!_M_filebuf.close())
  286.           this->setstate(ios_base::failbit);   
  287.       }
  288.     };
  289.  
  290.  
  291.   // 27.8.1.8  Template class basic_ofstream
  292.   template<typename _CharT, typename _Traits>
  293.     class basic_ofstream : public basic_ostream<_CharT,_Traits>
  294.     {
  295.     public:
  296.       // Types:
  297.       typedef _CharT                                    char_type;
  298.       typedef _Traits                                   traits_type;
  299.       typedef typename traits_type::int_type            int_type;
  300.       typedef typename traits_type::pos_type            pos_type;
  301.       typedef typename traits_type::off_type            off_type;
  302.  
  303.       // Non-standard types:
  304.       typedef basic_filebuf<char_type, traits_type>     __filebuf_type;
  305.       typedef basic_ostream<char_type, traits_type>     __ostream_type;
  306.      
  307.     private:
  308.       __filebuf_type    _M_filebuf;
  309.  
  310.     public:
  311.       // Constructors:
  312.       basic_ofstream()
  313.       : __ostream_type(NULL), _M_filebuf()
  314.       { this->init(&_M_filebuf); }
  315.      
  316.       explicit
  317.       basic_ofstream(const char* __s,
  318.                      ios_base::openmode __mode = ios_base::out|ios_base::trunc)
  319.       : __ostream_type(NULL), _M_filebuf()
  320.       {
  321.         this->init(&_M_filebuf);
  322.         this->open(__s, __mode);
  323.       }
  324.  
  325.       ~basic_ofstream()
  326.       { }
  327.  
  328.       // Members:
  329.       __filebuf_type*
  330.       rdbuf(void) const
  331.       { return const_cast<__filebuf_type*>(&_M_filebuf); }
  332.  
  333.       bool
  334.       is_open(void) { return _M_filebuf.is_open(); }
  335.  
  336.       void
  337.       open(const char* __s,
  338.            ios_base::openmode __mode = ios_base::out | ios_base::trunc)
  339.       {
  340.         if (!_M_filebuf.open(__s, __mode | ios_base::out))
  341.           this->setstate(ios_base::failbit);
  342.       }
  343.  
  344.       void
  345.       close(void)
  346.       {
  347.         if (!_M_filebuf.close())
  348.           setstate(ios_base::failbit);
  349.       }
  350.     };
  351.  
  352.  
  353.   // 27.8.1.11  Template class basic_fstream
  354.   template<typename _CharT, typename _Traits>
  355.     class basic_fstream : public basic_iostream<_CharT, _Traits>
  356.     {
  357.     public:
  358.       // Types:
  359.       typedef _CharT                                    char_type;
  360.       typedef _Traits                                   traits_type;
  361.       typedef typename traits_type::int_type            int_type;
  362.       typedef typename traits_type::pos_type            pos_type;
  363.       typedef typename traits_type::off_type            off_type;
  364.  
  365.       // Non-standard types:
  366.       typedef basic_filebuf<char_type, traits_type>     __filebuf_type;
  367.       typedef basic_ios<char_type, traits_type>         __ios_type;
  368.       typedef basic_iostream<char_type, traits_type>    __iostream_type;
  369.  
  370.     private:
  371.       __filebuf_type    _M_filebuf;
  372.      
  373.     public:
  374.       // Constructors/destructor:
  375.       basic_fstream()
  376.       : __iostream_type(NULL), _M_filebuf()
  377.       { this->init(&_M_filebuf); }
  378.  
  379.       explicit
  380.       basic_fstream(const char* __s,
  381.                     ios_base::openmode __mode = ios_base::in | ios_base::out)
  382.       : __iostream_type(NULL), _M_filebuf()
  383.       {
  384.         this->init(&_M_filebuf);
  385.         this->open(__s, __mode);
  386.       }
  387.  
  388.       ~basic_fstream()
  389.       { }
  390.    
  391.       // Members:
  392.       __filebuf_type*
  393.       rdbuf(void) const
  394.       { return const_cast<__filebuf_type*>(&_M_filebuf); }
  395.  
  396.       bool
  397.       is_open(void) { return _M_filebuf.is_open(); }
  398.  
  399.       void
  400.       open(const char* __s,
  401.            ios_base::openmode __mode = ios_base::in | ios_base::out)
  402.       {
  403.         if (!_M_filebuf.open(__s, __mode))
  404.           setstate(ios_base::failbit);
  405.       }
  406.  
  407.       void
  408.       close(void)
  409.       {
  410.         if (!_M_filebuf.close())
  411.           setstate(ios_base::failbit);
  412.       }
  413.     };
  414. } // namespace std
  415.  
  416.  
  417. #ifdef _GLIBCPP_NO_TEMPLATE_EXPORT
  418. # define export
  419. #ifdef  _GLIBCPP_FULLY_COMPLIANT_HEADERS
  420. # include <bits/fstream.tcc>
  421. #endif
  422. #endif
  423.  
  424. #endif 
  425.  
  426.