2002-01-04 Benjamin Kosnik <bkoz@redhat.com>
[official-gcc.git] / libstdc++-v3 / include / std / fstream
blob350a691d68ce9d24d4804f7288b7ab14ed9ac754
1 // File based streams -*- C++ -*-
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.
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.
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.
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.
31 // ISO C++ 14882: 27.8  File-based streams
34 /** @file std_fstream.h
35  *  This is an internal header file, included by other library headers.
36  *  You should not attempt to use it directly.
37  */
39 #ifndef _CPP_FSTREAM
40 #define _CPP_FSTREAM    1
42 #pragma GCC system_header
44 #include <istream>
45 #include <ostream>
46 #include <bits/basic_file.h>
47 #include <locale>       // For codecvt
48 #include <bits/gthr.h>
50 namespace std 
52   template<typename _CharT, typename _Traits>
53     class basic_filebuf : public basic_streambuf<_CharT, _Traits>
54     {
55     public:
56       // Types:
57       typedef _CharT                                    char_type;
58       typedef _Traits                                   traits_type;
59       typedef typename traits_type::int_type            int_type;
60       typedef typename traits_type::pos_type            pos_type;
61       typedef typename traits_type::off_type            off_type;
62       
63       // Non-standard Types:
64       typedef basic_streambuf<char_type, traits_type>   __streambuf_type;
65       typedef basic_filebuf<char_type, traits_type>     __filebuf_type;
66       typedef __basic_file<char_type>                   __file_type;
67       typedef typename traits_type::state_type          __state_type;
68       typedef codecvt<char_type, char, __state_type>    __codecvt_type;
69       typedef typename __codecvt_type::result           __res_type;
70       typedef ctype<char_type>                          __ctype_type;
72       friend class ios_base; // For sync_with_stdio.
74     private:
75       // Data Members:
76       // External buffer.
77       __file_type*              _M_file;
79       // Current and beginning state type for codecvt.
80       __state_type              _M_state_cur;
81       __state_type              _M_state_beg;   
83       // MT lock inherited from libio or other low-level io library.
84       __c_lock                  _M_lock;
86       // Set iff _M_buf is allocated memory from _M_allocate_internal_buffer..
87       bool                      _M_buf_allocated;
89       // XXX Needed? 
90       bool                      _M_last_overflowed;  
91   
92     public:
93       // Constructors/destructor:
94       basic_filebuf();
96       // Non-standard ctor:
97       basic_filebuf(__c_file_type* __f, ios_base::openmode __mode, 
98                     int_type __s = static_cast<int_type>(BUFSIZ));
100       // Non-standard member:
101       int
102       fd();
104       virtual 
105       ~basic_filebuf() 
106       { 
107         this->close();
108         _M_last_overflowed = false;
109       }
111       // Members:
112       bool 
113       is_open(void) const { return _M_file ? _M_file->is_open() : false; }
114     
115       __filebuf_type* 
116       open(const char* __s, ios_base::openmode __mode);
117     
118       __filebuf_type* 
119       close(void);
121     protected:
122       void 
123       _M_allocate_internal_buffer();
125       void 
126       _M_destroy_internal_buffer();
128       void 
129       _M_allocate_pback_buffer();
131       // Create __file_type object and initialize it properly.
132       void
133       _M_allocate_file();
135       // Overridden virtual functions:
136       virtual streamsize 
137       showmanyc(void);
138    
139       // Stroustrup, 1998, p. 628 
140       // underflow() and uflow() functions are called to get the next
141       // charater from the real input source when the buffer is empty.
142       // Buffered input uses underflow()
143       virtual int_type 
144       underflow(void);
146       virtual int_type 
147       pbackfail(int_type __c = _Traits::eof());
149       // NB: For what the standard expects of the overflow function,
150       // see _M_really_overflow(), below. Because basic_streambuf's
151       // sputc/sputn call overflow directly, and the complications of
152       // this implementation's setting of the initial pointers all
153       // equal to _M_buf when initializing, it seems essential to have
154       // this in actuality be a helper function that checks for the
155       // eccentricities of this implementation, and then call
156       // overflow() if indeed the buffer is full.
157       virtual int_type 
158       overflow(int_type __c = _Traits::eof());
160       // Stroustrup, 1998, p 648
161       // The overflow() function is called to transfer characters to the
162       // real output destination when the buffer is full. A call to
163       // overflow(c) outputs the contents of the buffer plus the
164       // character c.
165       // 27.5.2.4.5 
166       // Consume some sequence of the characters in the pending sequence.
167       int_type 
168       _M_really_overflow(int_type __c = _Traits::eof());
169     
170       virtual __streambuf_type* 
171       setbuf(char_type* __s, streamsize __n);
172     
173       virtual pos_type 
174       seekoff(off_type __off, ios_base::seekdir __way,
175               ios_base::openmode __mode = ios_base::in | ios_base::out);
177       virtual pos_type 
178       seekpos(pos_type __pos,
179               ios_base::openmode __mode = ios_base::in | ios_base::out);
181       virtual int 
182       sync(void)
183       {
184         bool __testput = _M_out_cur && _M_out_beg < _M_out_end;
185         if (__testput)
186           {
187             // Make sure that libio resyncs its idea of the file position
188             // with the external file.
189             _M_file->sync();
191             // Need to restore current position. This interpreted as
192             // the position of the external byte sequence (_M_file)
193             // plus the offset in the current internal buffer
194             // (_M_out_beg - _M_out_cur)
195             streamoff __cur = _M_file->seekoff(0, ios_base::cur);
196             off_type __off = _M_out_cur - _M_out_beg;
197             _M_really_overflow();
198             _M_file->seekpos(__cur + __off);
199           }
200         _M_last_overflowed = false;     
201         return 0;
202       }
203       
204       virtual void 
205       imbue(const locale& __loc);
207       virtual streamsize 
208       xsgetn(char_type* __s, streamsize __n)
209       {
210         streamsize __ret = 0;
211         // Clear out pback buffer before going on to the real deal...
212         if (_M_pback_init)
213           {
214             while (__ret < __n && _M_in_cur < _M_in_end)
215               {
216                 *__s = *_M_in_cur;
217                 ++__ret;
218                 ++__s;
219                 ++_M_in_cur;
220               }
221             _M_pback_destroy();
222           }
223         if (__ret < __n)
224           __ret += __streambuf_type::xsgetn(__s, __n - __ret);
225         return __ret;
226       }
228       virtual streamsize 
229       xsputn(const char_type* __s, streamsize __n)
230       {
231         _M_pback_destroy();
232         return __streambuf_type::xsputn(__s, __n);
233       }
234        
235       void
236       _M_output_unshift();
237     };
240   // 27.8.1.5  Template class basic_ifstream
241   template<typename _CharT, typename _Traits>
242     class basic_ifstream : public basic_istream<_CharT, _Traits>
243     {
244     public:
245       // Types:
246       typedef _CharT                                    char_type;
247       typedef _Traits                                   traits_type;
248       typedef typename traits_type::int_type            int_type;
249       typedef typename traits_type::pos_type            pos_type;
250       typedef typename traits_type::off_type            off_type;
252       // Non-standard types:
253       typedef basic_filebuf<char_type, traits_type>     __filebuf_type;
254       typedef basic_istream<char_type, traits_type>     __istream_type;
255     
256     private:
257       __filebuf_type    _M_filebuf;
259     public:
260      // Constructors/Destructors:
261       basic_ifstream()
262       : __istream_type(NULL), _M_filebuf()
263       { this->init(&_M_filebuf); }
265       explicit 
266       basic_ifstream(const char* __s, ios_base::openmode __mode = ios_base::in)
267       : __istream_type(NULL), _M_filebuf()
268       { 
269         this->init(&_M_filebuf); 
270         this->open(__s, __mode); 
271       }
272     
273       ~basic_ifstream()
274       { }
276       // Members:
277       __filebuf_type* 
278       rdbuf() const 
279       { return const_cast<__filebuf_type*>(&_M_filebuf); }
281       bool 
282       is_open(void) { return _M_filebuf.is_open(); }
284       void 
285       open(const char* __s, ios_base::openmode __mode = ios_base::in)
286       { 
287         if (_M_filebuf.open(__s, __mode | ios_base::in) == NULL)
288           this->setstate(ios_base::failbit); 
289       }
291       void 
292       close(void)
293       { 
294         if (!_M_filebuf.close())
295           this->setstate(ios_base::failbit);    
296       }
297     };
299   
300   // 27.8.1.8  Template class basic_ofstream
301   template<typename _CharT, typename _Traits>
302     class basic_ofstream : public basic_ostream<_CharT,_Traits>
303     {
304     public:
305       // Types:
306       typedef _CharT                                    char_type;
307       typedef _Traits                                   traits_type;
308       typedef typename traits_type::int_type            int_type;
309       typedef typename traits_type::pos_type            pos_type;
310       typedef typename traits_type::off_type            off_type;
312       // Non-standard types:
313       typedef basic_filebuf<char_type, traits_type>     __filebuf_type;
314       typedef basic_ostream<char_type, traits_type>     __ostream_type;
315       
316     private:
317       __filebuf_type    _M_filebuf;
319     public:
320       // Constructors:
321       basic_ofstream()
322       : __ostream_type(NULL), _M_filebuf()
323       { this->init(&_M_filebuf); }
324       
325       explicit 
326       basic_ofstream(const char* __s, 
327                      ios_base::openmode __mode = ios_base::out|ios_base::trunc)
328       : __ostream_type(NULL), _M_filebuf()
329       { 
330         this->init(&_M_filebuf); 
331         this->open(__s, __mode); 
332       }
334       ~basic_ofstream()
335       { }
337       // Members:
338       __filebuf_type* 
339       rdbuf(void) const
340       { return const_cast<__filebuf_type*>(&_M_filebuf); }
342       bool 
343       is_open(void) { return _M_filebuf.is_open(); }
345       void 
346       open(const char* __s, 
347            ios_base::openmode __mode = ios_base::out | ios_base::trunc)
348       { 
349         if (!_M_filebuf.open(__s, __mode | ios_base::out))
350           this->setstate(ios_base::failbit); 
351       }
353       void 
354       close(void)
355       { 
356         if (!_M_filebuf.close())
357           setstate(ios_base::failbit); 
358       }
359     };
362   // 27.8.1.11  Template class basic_fstream
363   template<typename _CharT, typename _Traits>
364     class basic_fstream : public basic_iostream<_CharT, _Traits>
365     {
366     public:
367       // Types:
368       typedef _CharT                                    char_type;
369       typedef _Traits                                   traits_type;
370       typedef typename traits_type::int_type            int_type;
371       typedef typename traits_type::pos_type            pos_type;
372       typedef typename traits_type::off_type            off_type;
374       // Non-standard types:
375       typedef basic_filebuf<char_type, traits_type>     __filebuf_type;
376       typedef basic_ios<char_type, traits_type>         __ios_type;
377       typedef basic_iostream<char_type, traits_type>    __iostream_type;
379     private:
380       __filebuf_type    _M_filebuf;
381       
382     public:
383       // Constructors/destructor:
384       basic_fstream()
385       : __iostream_type(NULL), _M_filebuf()
386       { this->init(&_M_filebuf); }
388       explicit 
389       basic_fstream(const char* __s,
390                     ios_base::openmode __mode = ios_base::in | ios_base::out)
391       : __iostream_type(NULL), _M_filebuf()
392       { 
393         this->init(&_M_filebuf); 
394         this->open(__s, __mode); 
395       }
397       ~basic_fstream()
398       { }
399     
400       // Members:
401       __filebuf_type* 
402       rdbuf(void) const 
403       { return const_cast<__filebuf_type*>(&_M_filebuf); }
405       bool 
406       is_open(void) { return _M_filebuf.is_open(); }
408       void 
409       open(const char* __s, 
410            ios_base::openmode __mode = ios_base::in | ios_base::out)
411       { 
412         if (!_M_filebuf.open(__s, __mode))
413           setstate(ios_base::failbit); 
414       }
416       void 
417       close(void)
418       { 
419         if (!_M_filebuf.close())
420           setstate(ios_base::failbit); 
421       }
422     };
423 } // namespace std
426 #ifdef _GLIBCPP_NO_TEMPLATE_EXPORT
427 # define export
428 #ifdef  _GLIBCPP_FULLY_COMPLIANT_HEADERS
429 # include <bits/fstream.tcc>
430 #endif
431 #endif
433 #endif