a04ddf098dd1cdc81b7e2a05b445b2f26a9486e2
[gcc.git] / libstdc++-v3 / include / std / fstream
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 /** @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 */
38
39 #ifndef _CPP_FSTREAM
40 #define _CPP_FSTREAM 1
41
42 #pragma GCC system_header
43
44 #include <istream>
45 #include <ostream>
46 #include <bits/basic_file.h>
47 #include <locale> // For codecvt
48 #include <bits/gthr.h>
49
50 namespace std
51 {
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;
71
72 friend class ios_base; // For sync_with_stdio.
73
74 private:
75 // Data Members:
76 // External buffer.
77 __file_type* _M_file;
78
79 // Current and beginning state type for codecvt.
80 __state_type _M_state_cur;
81 __state_type _M_state_beg;
82
83 // MT lock inherited from libio or other low-level io library.
84 __c_lock _M_lock;
85
86 // Set iff _M_buf is allocated memory from _M_allocate_internal_buffer..
87 bool _M_buf_allocated;
88
89 // XXX Needed?
90 bool _M_last_overflowed;
91
92 public:
93 // Constructors/destructor:
94 basic_filebuf();
95
96 // Non-standard ctor:
97 basic_filebuf(__c_file_type* __f, ios_base::openmode __mode,
98 int_type __s = static_cast<int_type>(BUFSIZ));
99
100 // Non-standard member:
101 int
102 fd();
103
104 virtual
105 ~basic_filebuf()
106 {
107 this->close();
108 _M_last_overflowed = false;
109 }
110
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);
120
121 protected:
122 void
123 _M_allocate_internal_buffer();
124
125 void
126 _M_destroy_internal_buffer();
127
128 void
129 _M_allocate_pback_buffer();
130
131 // Create __file_type object and initialize it properly.
132 void
133 _M_allocate_file();
134
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);
145
146 virtual int_type
147 pbackfail(int_type __c = _Traits::eof());
148
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());
159
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);
176
177 virtual pos_type
178 seekpos(pos_type __pos,
179 ios_base::openmode __mode = ios_base::in | ios_base::out);
180
181 virtual int
182 sync(void)
183 {
184 bool __testput = _M_out_cur && _M_out_beg < _M_out_end;
185
186 // Make sure that the internal buffer resyncs its idea of
187 // the file position with the external file.
188 if (__testput && !_M_file->sync())
189 {
190 // Need to restore current position. This interpreted as
191 // the position of the external byte sequence (_M_file)
192 // plus the offset in the current internal buffer
193 // (_M_out_beg - _M_out_cur)
194 streamoff __cur = _M_file->seekoff(0, ios_base::cur);
195 off_type __off = _M_out_cur - _M_out_beg;
196 _M_really_overflow();
197 _M_file->seekpos(__cur + __off);
198 }
199 _M_last_overflowed = false;
200 return 0;
201 }
202
203 virtual void
204 imbue(const locale& __loc);
205
206 virtual streamsize
207 xsgetn(char_type* __s, streamsize __n)
208 {
209 streamsize __ret = 0;
210 // Clear out pback buffer before going on to the real deal...
211 if (_M_pback_init)
212 {
213 while (__ret < __n && _M_in_cur < _M_in_end)
214 {
215 *__s = *_M_in_cur;
216 ++__ret;
217 ++__s;
218 ++_M_in_cur;
219 }
220 _M_pback_destroy();
221 }
222 if (__ret < __n)
223 __ret += __streambuf_type::xsgetn(__s, __n - __ret);
224 return __ret;
225 }
226
227 virtual streamsize
228 xsputn(const char_type* __s, streamsize __n)
229 {
230 _M_pback_destroy();
231 return __streambuf_type::xsputn(__s, __n);
232 }
233
234 void
235 _M_output_unshift();
236 };
237
238
239 // 27.8.1.5 Template class basic_ifstream
240 template<typename _CharT, typename _Traits>
241 class basic_ifstream : public basic_istream<_CharT, _Traits>
242 {
243 public:
244 // Types:
245 typedef _CharT char_type;
246 typedef _Traits traits_type;
247 typedef typename traits_type::int_type int_type;
248 typedef typename traits_type::pos_type pos_type;
249 typedef typename traits_type::off_type off_type;
250
251 // Non-standard types:
252 typedef basic_filebuf<char_type, traits_type> __filebuf_type;
253 typedef basic_istream<char_type, traits_type> __istream_type;
254
255 private:
256 __filebuf_type _M_filebuf;
257
258 public:
259 // Constructors/Destructors:
260 basic_ifstream()
261 : __istream_type(NULL), _M_filebuf()
262 { this->init(&_M_filebuf); }
263
264 explicit
265 basic_ifstream(const char* __s, ios_base::openmode __mode = ios_base::in)
266 : __istream_type(NULL), _M_filebuf()
267 {
268 this->init(&_M_filebuf);
269 this->open(__s, __mode);
270 }
271
272 ~basic_ifstream()
273 { }
274
275 // Members:
276 __filebuf_type*
277 rdbuf() const
278 { return const_cast<__filebuf_type*>(&_M_filebuf); }
279
280 bool
281 is_open(void) { return _M_filebuf.is_open(); }
282
283 void
284 open(const char* __s, ios_base::openmode __mode = ios_base::in)
285 {
286 if (_M_filebuf.open(__s, __mode | ios_base::in) == NULL)
287 this->setstate(ios_base::failbit);
288 }
289
290 void
291 close(void)
292 {
293 if (!_M_filebuf.close())
294 this->setstate(ios_base::failbit);
295 }
296 };
297
298
299 // 27.8.1.8 Template class basic_ofstream
300 template<typename _CharT, typename _Traits>
301 class basic_ofstream : public basic_ostream<_CharT,_Traits>
302 {
303 public:
304 // Types:
305 typedef _CharT char_type;
306 typedef _Traits traits_type;
307 typedef typename traits_type::int_type int_type;
308 typedef typename traits_type::pos_type pos_type;
309 typedef typename traits_type::off_type off_type;
310
311 // Non-standard types:
312 typedef basic_filebuf<char_type, traits_type> __filebuf_type;
313 typedef basic_ostream<char_type, traits_type> __ostream_type;
314
315 private:
316 __filebuf_type _M_filebuf;
317
318 public:
319 // Constructors:
320 basic_ofstream()
321 : __ostream_type(NULL), _M_filebuf()
322 { this->init(&_M_filebuf); }
323
324 explicit
325 basic_ofstream(const char* __s,
326 ios_base::openmode __mode = ios_base::out|ios_base::trunc)
327 : __ostream_type(NULL), _M_filebuf()
328 {
329 this->init(&_M_filebuf);
330 this->open(__s, __mode);
331 }
332
333 ~basic_ofstream()
334 { }
335
336 // Members:
337 __filebuf_type*
338 rdbuf(void) const
339 { return const_cast<__filebuf_type*>(&_M_filebuf); }
340
341 bool
342 is_open(void) { return _M_filebuf.is_open(); }
343
344 void
345 open(const char* __s,
346 ios_base::openmode __mode = ios_base::out | ios_base::trunc)
347 {
348 if (!_M_filebuf.open(__s, __mode | ios_base::out))
349 this->setstate(ios_base::failbit);
350 }
351
352 void
353 close(void)
354 {
355 if (!_M_filebuf.close())
356 this->setstate(ios_base::failbit);
357 }
358 };
359
360
361 // 27.8.1.11 Template class basic_fstream
362 template<typename _CharT, typename _Traits>
363 class basic_fstream : public basic_iostream<_CharT, _Traits>
364 {
365 public:
366 // Types:
367 typedef _CharT char_type;
368 typedef _Traits traits_type;
369 typedef typename traits_type::int_type int_type;
370 typedef typename traits_type::pos_type pos_type;
371 typedef typename traits_type::off_type off_type;
372
373 // Non-standard types:
374 typedef basic_filebuf<char_type, traits_type> __filebuf_type;
375 typedef basic_ios<char_type, traits_type> __ios_type;
376 typedef basic_iostream<char_type, traits_type> __iostream_type;
377
378 private:
379 __filebuf_type _M_filebuf;
380
381 public:
382 // Constructors/destructor:
383 basic_fstream()
384 : __iostream_type(NULL), _M_filebuf()
385 { this->init(&_M_filebuf); }
386
387 explicit
388 basic_fstream(const char* __s,
389 ios_base::openmode __mode = ios_base::in | ios_base::out)
390 : __iostream_type(NULL), _M_filebuf()
391 {
392 this->init(&_M_filebuf);
393 this->open(__s, __mode);
394 }
395
396 ~basic_fstream()
397 { }
398
399 // Members:
400 __filebuf_type*
401 rdbuf(void) const
402 { return const_cast<__filebuf_type*>(&_M_filebuf); }
403
404 bool
405 is_open(void) { return _M_filebuf.is_open(); }
406
407 void
408 open(const char* __s,
409 ios_base::openmode __mode = ios_base::in | ios_base::out)
410 {
411 if (!_M_filebuf.open(__s, __mode))
412 setstate(ios_base::failbit);
413 }
414
415 void
416 close(void)
417 {
418 if (!_M_filebuf.close())
419 setstate(ios_base::failbit);
420 }
421 };
422 } // namespace std
423
424
425 #ifdef _GLIBCPP_NO_TEMPLATE_EXPORT
426 # define export
427 #ifdef _GLIBCPP_FULLY_COMPLIANT_HEADERS
428 # include <bits/fstream.tcc>
429 #endif
430 #endif
431
432 #endif
433