]>
Commit | Line | Data |
---|---|---|
54c1bf78 | 1 | // File based streams -*- C++ -*- |
de96ac46 | 2 | |
bd91a8c4 | 3 | // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, |
5b9daa7e | 4 | // 2006, 2007, 2008, 2009 |
ffe94f83 | 5 | // Free Software Foundation, Inc. |
de96ac46 BK |
6 | // |
7 | // This file is part of the GNU ISO C++ Library. This library is free | |
8 | // software; you can redistribute it and/or modify it under the | |
9 | // terms of the GNU General Public License as published by the | |
748086b7 | 10 | // Free Software Foundation; either version 3, or (at your option) |
de96ac46 BK |
11 | // any later version. |
12 | ||
13 | // This library is distributed in the hope that it will be useful, | |
14 | // but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | // GNU General Public License for more details. | |
17 | ||
748086b7 JJ |
18 | // Under Section 7 of GPL version 3, you are granted additional |
19 | // permissions described in the GCC Runtime Library Exception, version | |
20 | // 3.1, as published by the Free Software Foundation. | |
21 | ||
22 | // You should have received a copy of the GNU General Public License and | |
23 | // a copy of the GCC Runtime Library Exception along with this program; | |
24 | // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see | |
25 | // <http://www.gnu.org/licenses/>. | |
de96ac46 | 26 | |
ffe94f83 | 27 | /** @file fstream |
0aa06b18 | 28 | * This is a Standard C++ Library header. |
2f9d51b8 PE |
29 | */ |
30 | ||
143c27b0 BK |
31 | // |
32 | // ISO C++ 14882: 27.8 File-based streams | |
33 | // | |
34 | ||
1143680e SE |
35 | #ifndef _GLIBCXX_FSTREAM |
36 | #define _GLIBCXX_FSTREAM 1 | |
54c1bf78 BK |
37 | |
38 | #pragma GCC system_header | |
39 | ||
40 | #include <istream> | |
41 | #include <ostream> | |
84b31797 | 42 | #include <bits/codecvt.h> |
13c4b877 | 43 | #include <cstdio> // For BUFSIZ |
bd91a8c4 | 44 | #include <bits/basic_file.h> // For __basic_file, __c_lock |
13c4b877 PC |
45 | #ifdef __GXX_EXPERIMENTAL_CXX0X__ |
46 | #include <string> // For std::string overloads. | |
47 | #endif | |
54c1bf78 | 48 | |
3cbc7af0 BK |
49 | _GLIBCXX_BEGIN_NAMESPACE(std) |
50 | ||
840ceb34 PE |
51 | // [27.8.1.1] template class basic_filebuf |
52 | /** | |
53 | * @brief The actual work of input and output (for files). | |
5b9daa7e | 54 | * @ingroup io |
840ceb34 PE |
55 | * |
56 | * This class associates both its input and output sequence with an | |
57 | * external disk file, and maintains a joint file position for both | |
28dac70a | 58 | * sequences. Many of its semantics are described in terms of similar |
840ceb34 | 59 | * behavior in the Standard C Library's @c FILE streams. |
13c4b877 | 60 | */ |
5e93f39f PR |
61 | // Requirements on traits_type, specific to this class: |
62 | // traits_type::pos_type must be fpos<traits_type::state_type> | |
63 | // traits_type::off_type must be streamoff | |
84b31797 | 64 | // traits_type::state_type must be Assignable and DefaultConstructible, |
5e93f39f | 65 | // and traits_type::state_type() must be the initial state for codecvt. |
54c1bf78 BK |
66 | template<typename _CharT, typename _Traits> |
67 | class basic_filebuf : public basic_streambuf<_CharT, _Traits> | |
68 | { | |
69 | public: | |
70 | // Types: | |
71 | typedef _CharT char_type; | |
72 | typedef _Traits traits_type; | |
73 | typedef typename traits_type::int_type int_type; | |
74 | typedef typename traits_type::pos_type pos_type; | |
75 | typedef typename traits_type::off_type off_type; | |
fd58f127 | 76 | |
54c1bf78 BK |
77 | typedef basic_streambuf<char_type, traits_type> __streambuf_type; |
78 | typedef basic_filebuf<char_type, traits_type> __filebuf_type; | |
07814743 | 79 | typedef __basic_file<char> __file_type; |
54c1bf78 BK |
80 | typedef typename traits_type::state_type __state_type; |
81 | typedef codecvt<char_type, char, __state_type> __codecvt_type; | |
54c1bf78 BK |
82 | |
83 | friend class ios_base; // For sync_with_stdio. | |
84 | ||
6f48900c | 85 | protected: |
54c1bf78 | 86 | // Data Members: |
d3a193e3 BK |
87 | // MT lock inherited from libio or other low-level io library. |
88 | __c_lock _M_lock; | |
89 | ||
54c1bf78 | 90 | // External buffer. |
d3a193e3 | 91 | __file_type _M_file; |
54c1bf78 | 92 | |
4312e020 | 93 | /// Place to stash in || out || in | out settings for current filebuf. |
cd16e04b PC |
94 | ios_base::openmode _M_mode; |
95 | ||
5e93f39f | 96 | // Beginning state type for codecvt. |
fd58f127 | 97 | __state_type _M_state_beg; |
54c1bf78 | 98 | |
5e93f39f PR |
99 | // During output, the state that corresponds to pptr(), |
100 | // during input, the state that corresponds to egptr() and | |
101 | // _M_ext_next. | |
5e93f39f PR |
102 | __state_type _M_state_cur; |
103 | ||
104 | // Not used for output. During input, the state that corresponds | |
105 | // to eback() and _M_ext_buf. | |
5e93f39f PR |
106 | __state_type _M_state_last; |
107 | ||
4312e020 | 108 | /// Pointer to the beginning of internal buffer. |
479a1811 PC |
109 | char_type* _M_buf; |
110 | ||
f10eea7b | 111 | /** |
f10eea7b PC |
112 | * Actual size of internal buffer. This number is equal to the size |
113 | * of the put area + 1 position, reserved for the overflow char of | |
114 | * a full area. | |
13c4b877 | 115 | */ |
f10eea7b PC |
116 | size_t _M_buf_size; |
117 | ||
5cdd50a5 | 118 | // Set iff _M_buf is allocated memory from _M_allocate_internal_buffer. |
54c1bf78 | 119 | bool _M_buf_allocated; |
71b46021 | 120 | |
a8cad3e1 | 121 | /** |
13c4b877 | 122 | * _M_reading == false && _M_writing == false for 'uncommitted' mode; |
a8cad3e1 PC |
123 | * _M_reading == true for 'read' mode; |
124 | * _M_writing == true for 'write' mode; | |
125 | * | |
126 | * NB: _M_reading == true && _M_writing == true is unused. | |
13c4b877 | 127 | */ |
71b46021 PC |
128 | bool _M_reading; |
129 | bool _M_writing; | |
130 | ||
45aca21f PC |
131 | //@{ |
132 | /** | |
45aca21f PC |
133 | * Necessary bits for putback buffer management. |
134 | * | |
135 | * @note pbacks of over one character are not currently supported. | |
13c4b877 PC |
136 | */ |
137 | char_type _M_pback; | |
45aca21f PC |
138 | char_type* _M_pback_cur_save; |
139 | char_type* _M_pback_end_save; | |
13c4b877 | 140 | bool _M_pback_init; |
45aca21f PC |
141 | //@} |
142 | ||
0cd1de6f BK |
143 | // Cached codecvt facet. |
144 | const __codecvt_type* _M_codecvt; | |
145 | ||
f1813b69 | 146 | /** |
f1813b69 PR |
147 | * Buffer for external characters. Used for input when |
148 | * codecvt::always_noconv() == false. When valid, this corresponds | |
149 | * to eback(). | |
13c4b877 | 150 | */ |
f1813b69 PR |
151 | char* _M_ext_buf; |
152 | ||
153 | /** | |
f1813b69 | 154 | * Size of buffer held by _M_ext_buf. |
13c4b877 | 155 | */ |
f1813b69 PR |
156 | streamsize _M_ext_buf_size; |
157 | ||
158 | /** | |
f1813b69 PR |
159 | * Pointers into the buffer held by _M_ext_buf that delimit a |
160 | * subsequence of bytes that have been read but not yet converted. | |
161 | * When valid, _M_ext_next corresponds to egptr(). | |
13c4b877 | 162 | */ |
f1813b69 PR |
163 | const char* _M_ext_next; |
164 | char* _M_ext_end; | |
165 | ||
6623b2f2 | 166 | /** |
6623b2f2 PC |
167 | * Initializes pback buffers, and moves normal buffers to safety. |
168 | * Assumptions: | |
169 | * _M_in_cur has already been moved back | |
13c4b877 | 170 | */ |
45aca21f | 171 | void |
aa438e8f | 172 | _M_create_pback() |
45aca21f PC |
173 | { |
174 | if (!_M_pback_init) | |
175 | { | |
71b46021 PC |
176 | _M_pback_cur_save = this->gptr(); |
177 | _M_pback_end_save = this->egptr(); | |
002bd606 | 178 | this->setg(&_M_pback, &_M_pback, &_M_pback + 1); |
45aca21f PC |
179 | _M_pback_init = true; |
180 | } | |
181 | } | |
182 | ||
6623b2f2 | 183 | /** |
6623b2f2 PC |
184 | * Deactivates pback buffer contents, and restores normal buffer. |
185 | * Assumptions: | |
186 | * The pback buffer has only moved forward. | |
13c4b877 | 187 | */ |
45aca21f | 188 | void |
aa438e8f | 189 | _M_destroy_pback() throw() |
45aca21f PC |
190 | { |
191 | if (_M_pback_init) | |
192 | { | |
193 | // Length _M_in_cur moved in the pback buffer. | |
71b46021 | 194 | _M_pback_cur_save += this->gptr() != this->eback(); |
a8e3a00f | 195 | this->setg(_M_buf, _M_pback_cur_save, _M_pback_end_save); |
45aca21f PC |
196 | _M_pback_init = false; |
197 | } | |
198 | } | |
199 | ||
54c1bf78 BK |
200 | public: |
201 | // Constructors/destructor: | |
840ceb34 PE |
202 | /** |
203 | * @brief Does not open any files. | |
204 | * | |
205 | * The default constructor initializes the parent class using its | |
206 | * own default ctor. | |
13c4b877 | 207 | */ |
54c1bf78 BK |
208 | basic_filebuf(); |
209 | ||
840ceb34 PE |
210 | /** |
211 | * @brief The destructor closes the file first. | |
13c4b877 | 212 | */ |
fd58f127 PE |
213 | virtual |
214 | ~basic_filebuf() | |
cc5112c9 | 215 | { this->close(); } |
54c1bf78 BK |
216 | |
217 | // Members: | |
840ceb34 PE |
218 | /** |
219 | * @brief Returns true if the external file is open. | |
13c4b877 | 220 | */ |
fd58f127 | 221 | bool |
85a5f64e PC |
222 | is_open() const throw() |
223 | { return _M_file.is_open(); } | |
fd58f127 | 224 | |
840ceb34 PE |
225 | /** |
226 | * @brief Opens an external file. | |
227 | * @param s The name of the file. | |
228 | * @param mode The open mode flags. | |
229 | * @return @c this on success, NULL on failure | |
230 | * | |
231 | * If a file is already open, this function immediately fails. | |
232 | * Otherwise it tries to open the file named @a s using the flags | |
233 | * given in @a mode. | |
234 | * | |
9735f6ba FP |
235 | * Table 92, adapted here, gives the relation between openmode |
236 | * combinations and the equivalent fopen() flags. | |
ec01f292 PC |
237 | * (NB: lines app, in|out|app, in|app, binary|app, binary|in|out|app, |
238 | * and binary|in|app per DR 596) | |
9735f6ba FP |
239 | * +---------------------------------------------------------+ |
240 | * | ios_base Flag combination stdio equivalent | | |
241 | * |binary in out trunc app | | |
242 | * +---------------------------------------------------------+ | |
243 | * | + "w" | | |
244 | * | + + "a" | | |
ec01f292 | 245 | * | + "a" | |
9735f6ba FP |
246 | * | + + "w" | |
247 | * | + "r" | | |
248 | * | + + "r+" | | |
249 | * | + + + "w+" | | |
250 | * | + + + "a+" | | |
ec01f292 | 251 | * | + + "a+" | |
9735f6ba FP |
252 | * +---------------------------------------------------------+ |
253 | * | + + "wb" | | |
254 | * | + + + "ab" | | |
ec01f292 | 255 | * | + + "ab" | |
9735f6ba FP |
256 | * | + + + "wb" | |
257 | * | + + "rb" | | |
258 | * | + + + "r+b" | | |
259 | * | + + + + "w+b" | | |
260 | * | + + + + "a+b" | | |
ec01f292 | 261 | * | + + + "a+b" | |
9735f6ba FP |
262 | * +---------------------------------------------------------+ |
263 | */ | |
fd58f127 | 264 | __filebuf_type* |
54c1bf78 | 265 | open(const char* __s, ios_base::openmode __mode); |
fd58f127 | 266 | |
13c4b877 PC |
267 | #ifdef __GXX_EXPERIMENTAL_CXX0X__ |
268 | /** | |
269 | * @brief Opens an external file. | |
270 | * @param s The name of the file. | |
271 | * @param mode The open mode flags. | |
272 | * @return @c this on success, NULL on failure | |
273 | */ | |
274 | __filebuf_type* | |
275 | open(const std::string& __s, ios_base::openmode __mode) | |
276 | { return open(__s.c_str(), __mode); } | |
277 | #endif | |
278 | ||
840ceb34 PE |
279 | /** |
280 | * @brief Closes the currently associated file. | |
281 | * @return @c this on success, NULL on failure | |
282 | * | |
283 | * If no file is currently open, this function immediately fails. | |
284 | * | |
285 | * If a "put buffer area" exists, @c overflow(eof) is called to flush | |
286 | * all the characters. The file is then closed. | |
287 | * | |
288 | * If any operations fail, this function also fails. | |
13c4b877 | 289 | */ |
fd58f127 | 290 | __filebuf_type* |
d05f74f1 | 291 | close(); |
54c1bf78 BK |
292 | |
293 | protected: | |
fd58f127 | 294 | void |
54c1bf78 BK |
295 | _M_allocate_internal_buffer(); |
296 | ||
fd58f127 | 297 | void |
a1796d12 | 298 | _M_destroy_internal_buffer() throw(); |
54c1bf78 | 299 | |
840ceb34 | 300 | // [27.8.1.4] overridden virtual functions |
fd58f127 | 301 | virtual streamsize |
07814743 | 302 | showmanyc(); |
fd58f127 PE |
303 | |
304 | // Stroustrup, 1998, p. 628 | |
54c1bf78 | 305 | // underflow() and uflow() functions are called to get the next |
28dac70a | 306 | // character from the real input source when the buffer is empty. |
54c1bf78 | 307 | // Buffered input uses underflow() |
5066927d | 308 | |
fd58f127 | 309 | virtual int_type |
cd16e04b | 310 | underflow(); |
54c1bf78 | 311 | |
fd58f127 | 312 | virtual int_type |
54c1bf78 BK |
313 | pbackfail(int_type __c = _Traits::eof()); |
314 | ||
54c1bf78 BK |
315 | // Stroustrup, 1998, p 648 |
316 | // The overflow() function is called to transfer characters to the | |
317 | // real output destination when the buffer is full. A call to | |
318 | // overflow(c) outputs the contents of the buffer plus the | |
319 | // character c. | |
fd58f127 | 320 | // 27.5.2.4.5 |
54c1bf78 | 321 | // Consume some sequence of the characters in the pending sequence. |
002bd606 BK |
322 | virtual int_type |
323 | overflow(int_type __c = _Traits::eof()); | |
fd58f127 | 324 | |
07814743 BK |
325 | // Convert internal byte sequence to external, char-based |
326 | // sequence via codecvt. | |
6e81c6f4 BK |
327 | bool |
328 | _M_convert_to_external(char_type*, streamsize); | |
07814743 | 329 | |
840ceb34 PE |
330 | /** |
331 | * @brief Manipulates the buffer. | |
332 | * @param s Pointer to a buffer area. | |
333 | * @param n Size of @a s. | |
334 | * @return @c this | |
335 | * | |
336 | * If no file has been opened, and both @a s and @a n are zero, then | |
337 | * the stream becomes unbuffered. Otherwise, @c s is used as a | |
338 | * buffer; see | |
a40fff0e | 339 | * http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt11ch25s02.html |
840ceb34 | 340 | * for more. |
13c4b877 | 341 | */ |
fd58f127 | 342 | virtual __streambuf_type* |
54c1bf78 | 343 | setbuf(char_type* __s, streamsize __n); |
fd58f127 PE |
344 | |
345 | virtual pos_type | |
54c1bf78 BK |
346 | seekoff(off_type __off, ios_base::seekdir __way, |
347 | ios_base::openmode __mode = ios_base::in | ios_base::out); | |
348 | ||
fd58f127 | 349 | virtual pos_type |
54c1bf78 BK |
350 | seekpos(pos_type __pos, |
351 | ios_base::openmode __mode = ios_base::in | ios_base::out); | |
352 | ||
1a139c59 | 353 | // Common code for seekoff and seekpos |
1a139c59 | 354 | pos_type |
5e93f39f | 355 | _M_seek(off_type __off, ios_base::seekdir __way, __state_type __state); |
1a139c59 | 356 | |
fd58f127 | 357 | virtual int |
5e93f39f | 358 | sync(); |
fd58f127 PE |
359 | |
360 | virtual void | |
54c1bf78 BK |
361 | imbue(const locale& __loc); |
362 | ||
fd58f127 | 363 | virtual streamsize |
c56e3d82 | 364 | xsgetn(char_type* __s, streamsize __n); |
fd58f127 PE |
365 | |
366 | virtual streamsize | |
bda243ec | 367 | xsputn(const char_type* __s, streamsize __n); |
fd58f127 | 368 | |
5e93f39f | 369 | // Flushes output buffer, then writes unshift sequence. |
5e93f39f PR |
370 | bool |
371 | _M_terminate_output(); | |
5066927d | 372 | |
6623b2f2 | 373 | /** |
6623b2f2 PC |
374 | * This function sets the pointers of the internal buffer, both get |
375 | * and put areas. Typically: | |
376 | * | |
377 | * __off == egptr() - eback() upon underflow/uflow ('read' mode); | |
378 | * __off == 0 upon overflow ('write' mode); | |
379 | * __off == -1 upon open, setbuf, seekoff/pos ('uncommitted' mode). | |
13c4b877 | 380 | * |
6623b2f2 PC |
381 | * NB: epptr() - pbase() == _M_buf_size - 1, since _M_buf_size |
382 | * reflects the actual allocated memory and the last cell is reserved | |
383 | * for the overflow char of a full put area. | |
13c4b877 | 384 | */ |
98ce9d06 PC |
385 | void |
386 | _M_set_buffer(streamsize __off) | |
387 | { | |
a8e3a00f BK |
388 | const bool __testin = _M_mode & ios_base::in; |
389 | const bool __testout = _M_mode & ios_base::out; | |
f10eea7b | 390 | |
71b46021 | 391 | if (__testin && __off > 0) |
a8e3a00f | 392 | this->setg(_M_buf, _M_buf, _M_buf + __off); |
71b46021 | 393 | else |
a8e3a00f | 394 | this->setg(_M_buf, _M_buf, _M_buf); |
71b46021 | 395 | |
a8e3a00f BK |
396 | if (__testout && __off == 0 && _M_buf_size > 1 ) |
397 | this->setp(_M_buf, _M_buf + _M_buf_size - 1); | |
71b46021 PC |
398 | else |
399 | this->setp(NULL, NULL); | |
98ce9d06 | 400 | } |
54c1bf78 BK |
401 | }; |
402 | ||
840ceb34 | 403 | // [27.8.1.5] Template class basic_ifstream |
fd58f127 | 404 | /** |
840ceb34 | 405 | * @brief Controlling input for files. |
5b9daa7e | 406 | * @ingroup io |
840ceb34 PE |
407 | * |
408 | * This class supports reading from named files, using the inherited | |
409 | * functions from std::basic_istream. To control the associated | |
410 | * sequence, an instance of std::basic_filebuf is used, which this page | |
411 | * refers to as @c sb. | |
13c4b877 | 412 | */ |
54c1bf78 BK |
413 | template<typename _CharT, typename _Traits> |
414 | class basic_ifstream : public basic_istream<_CharT, _Traits> | |
415 | { | |
416 | public: | |
417 | // Types: | |
418 | typedef _CharT char_type; | |
419 | typedef _Traits traits_type; | |
420 | typedef typename traits_type::int_type int_type; | |
421 | typedef typename traits_type::pos_type pos_type; | |
422 | typedef typename traits_type::off_type off_type; | |
423 | ||
424 | // Non-standard types: | |
425 | typedef basic_filebuf<char_type, traits_type> __filebuf_type; | |
426 | typedef basic_istream<char_type, traits_type> __istream_type; | |
fd58f127 | 427 | |
54c1bf78 BK |
428 | private: |
429 | __filebuf_type _M_filebuf; | |
430 | ||
431 | public: | |
840ceb34 PE |
432 | // Constructors/Destructors: |
433 | /** | |
434 | * @brief Default constructor. | |
435 | * | |
436 | * Initializes @c sb using its default constructor, and passes | |
437 | * @c &sb to the base class initializer. Does not open any files | |
438 | * (you haven't given it a filename to open). | |
13c4b877 | 439 | */ |
d29cc32f | 440 | basic_ifstream() : __istream_type(), _M_filebuf() |
54c1bf78 BK |
441 | { this->init(&_M_filebuf); } |
442 | ||
fd58f127 | 443 | /** |
840ceb34 PE |
444 | * @brief Create an input file stream. |
445 | * @param s Null terminated string specifying the filename. | |
fd58f127 PE |
446 | * @param mode Open file in specified mode (see std::ios_base). |
447 | * | |
840ceb34 PE |
448 | * @c ios_base::in is automatically included in @a mode. |
449 | * | |
fd58f127 PE |
450 | * Tip: When using std::string to hold the filename, you must use |
451 | * .c_str() before passing it to this constructor. | |
13c4b877 | 452 | */ |
fd58f127 | 453 | explicit |
54c1bf78 | 454 | basic_ifstream(const char* __s, ios_base::openmode __mode = ios_base::in) |
d29cc32f | 455 | : __istream_type(), _M_filebuf() |
fd58f127 PE |
456 | { |
457 | this->init(&_M_filebuf); | |
458 | this->open(__s, __mode); | |
54c1bf78 | 459 | } |
fd58f127 | 460 | |
13c4b877 PC |
461 | #ifdef __GXX_EXPERIMENTAL_CXX0X__ |
462 | /** | |
463 | * @brief Create an input file stream. | |
464 | * @param s std::string specifying the filename. | |
465 | * @param mode Open file in specified mode (see std::ios_base). | |
466 | * | |
467 | * @c ios_base::in is automatically included in @a mode. | |
468 | */ | |
469 | explicit | |
470 | basic_ifstream(const std::string& __s, | |
471 | ios_base::openmode __mode = ios_base::in) | |
472 | : __istream_type(), _M_filebuf() | |
473 | { | |
474 | this->init(&_M_filebuf); | |
475 | this->open(__s, __mode); | |
476 | } | |
477 | #endif | |
478 | ||
840ceb34 PE |
479 | /** |
480 | * @brief The destructor does nothing. | |
481 | * | |
482 | * The file is closed by the filebuf object, not the formatting | |
483 | * stream. | |
13c4b877 | 484 | */ |
54c1bf78 BK |
485 | ~basic_ifstream() |
486 | { } | |
487 | ||
488 | // Members: | |
fd58f127 | 489 | /** |
840ceb34 PE |
490 | * @brief Accessing the underlying buffer. |
491 | * @return The current basic_filebuf buffer. | |
492 | * | |
493 | * This hides both signatures of std::basic_ios::rdbuf(). | |
13c4b877 | 494 | */ |
fd58f127 PE |
495 | __filebuf_type* |
496 | rdbuf() const | |
54c1bf78 BK |
497 | { return const_cast<__filebuf_type*>(&_M_filebuf); } |
498 | ||
840ceb34 PE |
499 | /** |
500 | * @brief Wrapper to test for an open file. | |
501 | * @return @c rdbuf()->is_open() | |
13c4b877 | 502 | */ |
fd58f127 | 503 | bool |
85a5f64e PC |
504 | is_open() |
505 | { return _M_filebuf.is_open(); } | |
506 | ||
507 | // _GLIBCXX_RESOLVE_LIB_DEFECTS | |
508 | // 365. Lack of const-qualification in clause 27 | |
509 | bool | |
510 | is_open() const | |
511 | { return _M_filebuf.is_open(); } | |
54c1bf78 | 512 | |
840ceb34 PE |
513 | /** |
514 | * @brief Opens an external file. | |
515 | * @param s The name of the file. | |
516 | * @param mode The open mode flags. | |
517 | * | |
518 | * Calls @c std::basic_filebuf::open(s,mode|in). If that function | |
519 | * fails, @c failbit is set in the stream's error state. | |
520 | * | |
521 | * Tip: When using std::string to hold the filename, you must use | |
522 | * .c_str() before passing it to this constructor. | |
13c4b877 | 523 | */ |
fd58f127 | 524 | void |
54c1bf78 | 525 | open(const char* __s, ios_base::openmode __mode = ios_base::in) |
fd58f127 | 526 | { |
b988dfc5 | 527 | if (!_M_filebuf.open(__s, __mode | ios_base::in)) |
fd58f127 | 528 | this->setstate(ios_base::failbit); |
7a59efae PC |
529 | else |
530 | // _GLIBCXX_RESOLVE_LIB_DEFECTS | |
531 | // 409. Closing an fstream should clear error state | |
532 | this->clear(); | |
54c1bf78 BK |
533 | } |
534 | ||
13c4b877 PC |
535 | #ifdef __GXX_EXPERIMENTAL_CXX0X__ |
536 | /** | |
537 | * @brief Opens an external file. | |
538 | * @param s The name of the file. | |
539 | * @param mode The open mode flags. | |
540 | * | |
541 | * Calls @c std::basic_filebuf::open(s,mode|in). If that function | |
542 | * fails, @c failbit is set in the stream's error state. | |
543 | */ | |
544 | void | |
545 | open(const std::string& __s, ios_base::openmode __mode = ios_base::in) | |
546 | { | |
547 | if (!_M_filebuf.open(__s, __mode | ios_base::in)) | |
548 | this->setstate(ios_base::failbit); | |
549 | else | |
550 | // _GLIBCXX_RESOLVE_LIB_DEFECTS | |
551 | // 409. Closing an fstream should clear error state | |
552 | this->clear(); | |
553 | } | |
554 | #endif | |
555 | ||
840ceb34 PE |
556 | /** |
557 | * @brief Close the file. | |
558 | * | |
559 | * Calls @c std::basic_filebuf::close(). If that function | |
560 | * fails, @c failbit is set in the stream's error state. | |
13c4b877 | 561 | */ |
fd58f127 | 562 | void |
07814743 | 563 | close() |
fd58f127 | 564 | { |
54c1bf78 | 565 | if (!_M_filebuf.close()) |
fd58f127 | 566 | this->setstate(ios_base::failbit); |
54c1bf78 BK |
567 | } |
568 | }; | |
569 | ||
fd58f127 | 570 | |
840ceb34 | 571 | // [27.8.1.8] Template class basic_ofstream |
fd58f127 | 572 | /** |
840ceb34 | 573 | * @brief Controlling output for files. |
5b9daa7e | 574 | * @ingroup io |
840ceb34 PE |
575 | * |
576 | * This class supports reading from named files, using the inherited | |
577 | * functions from std::basic_ostream. To control the associated | |
578 | * sequence, an instance of std::basic_filebuf is used, which this page | |
579 | * refers to as @c sb. | |
13c4b877 | 580 | */ |
54c1bf78 BK |
581 | template<typename _CharT, typename _Traits> |
582 | class basic_ofstream : public basic_ostream<_CharT,_Traits> | |
583 | { | |
584 | public: | |
585 | // Types: | |
586 | typedef _CharT char_type; | |
587 | typedef _Traits traits_type; | |
588 | typedef typename traits_type::int_type int_type; | |
589 | typedef typename traits_type::pos_type pos_type; | |
590 | typedef typename traits_type::off_type off_type; | |
591 | ||
592 | // Non-standard types: | |
593 | typedef basic_filebuf<char_type, traits_type> __filebuf_type; | |
594 | typedef basic_ostream<char_type, traits_type> __ostream_type; | |
fd58f127 | 595 | |
54c1bf78 BK |
596 | private: |
597 | __filebuf_type _M_filebuf; | |
598 | ||
599 | public: | |
600 | // Constructors: | |
840ceb34 PE |
601 | /** |
602 | * @brief Default constructor. | |
603 | * | |
604 | * Initializes @c sb using its default constructor, and passes | |
605 | * @c &sb to the base class initializer. Does not open any files | |
606 | * (you haven't given it a filename to open). | |
13c4b877 | 607 | */ |
d29cc32f | 608 | basic_ofstream(): __ostream_type(), _M_filebuf() |
54c1bf78 | 609 | { this->init(&_M_filebuf); } |
fd58f127 PE |
610 | |
611 | /** | |
840ceb34 PE |
612 | * @brief Create an output file stream. |
613 | * @param s Null terminated string specifying the filename. | |
fd58f127 PE |
614 | * @param mode Open file in specified mode (see std::ios_base). |
615 | * | |
840ceb34 PE |
616 | * @c ios_base::out|ios_base::trunc is automatically included in |
617 | * @a mode. | |
618 | * | |
fd58f127 PE |
619 | * Tip: When using std::string to hold the filename, you must use |
620 | * .c_str() before passing it to this constructor. | |
13c4b877 | 621 | */ |
fd58f127 PE |
622 | explicit |
623 | basic_ofstream(const char* __s, | |
54c1bf78 | 624 | ios_base::openmode __mode = ios_base::out|ios_base::trunc) |
d29cc32f | 625 | : __ostream_type(), _M_filebuf() |
fd58f127 PE |
626 | { |
627 | this->init(&_M_filebuf); | |
628 | this->open(__s, __mode); | |
54c1bf78 BK |
629 | } |
630 | ||
13c4b877 PC |
631 | #ifdef __GXX_EXPERIMENTAL_CXX0X__ |
632 | /** | |
633 | * @brief Create an output file stream. | |
634 | * @param s std::string specifying the filename. | |
635 | * @param mode Open file in specified mode (see std::ios_base). | |
636 | * | |
637 | * @c ios_base::out|ios_base::trunc is automatically included in | |
638 | * @a mode. | |
639 | */ | |
640 | explicit | |
641 | basic_ofstream(const std::string& __s, | |
642 | ios_base::openmode __mode = ios_base::out|ios_base::trunc) | |
643 | : __ostream_type(), _M_filebuf() | |
644 | { | |
645 | this->init(&_M_filebuf); | |
646 | this->open(__s, __mode); | |
647 | } | |
648 | #endif | |
649 | ||
840ceb34 PE |
650 | /** |
651 | * @brief The destructor does nothing. | |
652 | * | |
653 | * The file is closed by the filebuf object, not the formatting | |
654 | * stream. | |
13c4b877 | 655 | */ |
54c1bf78 BK |
656 | ~basic_ofstream() |
657 | { } | |
658 | ||
659 | // Members: | |
fd58f127 | 660 | /** |
840ceb34 PE |
661 | * @brief Accessing the underlying buffer. |
662 | * @return The current basic_filebuf buffer. | |
663 | * | |
664 | * This hides both signatures of std::basic_ios::rdbuf(). | |
13c4b877 | 665 | */ |
fd58f127 | 666 | __filebuf_type* |
07814743 | 667 | rdbuf() const |
54c1bf78 | 668 | { return const_cast<__filebuf_type*>(&_M_filebuf); } |
fd58f127 PE |
669 | |
670 | /** | |
840ceb34 PE |
671 | * @brief Wrapper to test for an open file. |
672 | * @return @c rdbuf()->is_open() | |
13c4b877 | 673 | */ |
fd58f127 | 674 | bool |
85a5f64e PC |
675 | is_open() |
676 | { return _M_filebuf.is_open(); } | |
677 | ||
678 | // _GLIBCXX_RESOLVE_LIB_DEFECTS | |
679 | // 365. Lack of const-qualification in clause 27 | |
680 | bool | |
681 | is_open() const | |
682 | { return _M_filebuf.is_open(); } | |
54c1bf78 | 683 | |
fd58f127 | 684 | /** |
840ceb34 PE |
685 | * @brief Opens an external file. |
686 | * @param s The name of the file. | |
687 | * @param mode The open mode flags. | |
688 | * | |
689 | * Calls @c std::basic_filebuf::open(s,mode|out|trunc). If that | |
690 | * function fails, @c failbit is set in the stream's error state. | |
fd58f127 PE |
691 | * |
692 | * Tip: When using std::string to hold the filename, you must use | |
693 | * .c_str() before passing it to this constructor. | |
13c4b877 | 694 | */ |
fd58f127 PE |
695 | void |
696 | open(const char* __s, | |
54c1bf78 | 697 | ios_base::openmode __mode = ios_base::out | ios_base::trunc) |
fd58f127 | 698 | { |
54c1bf78 | 699 | if (!_M_filebuf.open(__s, __mode | ios_base::out)) |
fd58f127 | 700 | this->setstate(ios_base::failbit); |
7a59efae PC |
701 | else |
702 | // _GLIBCXX_RESOLVE_LIB_DEFECTS | |
703 | // 409. Closing an fstream should clear error state | |
704 | this->clear(); | |
54c1bf78 BK |
705 | } |
706 | ||
13c4b877 PC |
707 | #ifdef __GXX_EXPERIMENTAL_CXX0X__ |
708 | /** | |
709 | * @brief Opens an external file. | |
710 | * @param s The name of the file. | |
711 | * @param mode The open mode flags. | |
712 | * | |
713 | * Calls @c std::basic_filebuf::open(s,mode|out|trunc). If that | |
714 | * function fails, @c failbit is set in the stream's error state. | |
715 | */ | |
716 | void | |
717 | open(const std::string& __s, | |
718 | ios_base::openmode __mode = ios_base::out | ios_base::trunc) | |
719 | { | |
720 | if (!_M_filebuf.open(__s, __mode | ios_base::out)) | |
721 | this->setstate(ios_base::failbit); | |
722 | else | |
723 | // _GLIBCXX_RESOLVE_LIB_DEFECTS | |
724 | // 409. Closing an fstream should clear error state | |
725 | this->clear(); | |
726 | } | |
727 | #endif | |
728 | ||
840ceb34 PE |
729 | /** |
730 | * @brief Close the file. | |
731 | * | |
732 | * Calls @c std::basic_filebuf::close(). If that function | |
733 | * fails, @c failbit is set in the stream's error state. | |
13c4b877 | 734 | */ |
fd58f127 | 735 | void |
07814743 | 736 | close() |
fd58f127 | 737 | { |
54c1bf78 | 738 | if (!_M_filebuf.close()) |
fd58f127 | 739 | this->setstate(ios_base::failbit); |
54c1bf78 BK |
740 | } |
741 | }; | |
742 | ||
743 | ||
840ceb34 | 744 | // [27.8.1.11] Template class basic_fstream |
fd58f127 | 745 | /** |
28dac70a | 746 | * @brief Controlling input and output for files. |
5b9daa7e | 747 | * @ingroup io |
840ceb34 PE |
748 | * |
749 | * This class supports reading from and writing to named files, using | |
750 | * the inherited functions from std::basic_iostream. To control the | |
751 | * associated sequence, an instance of std::basic_filebuf is used, which | |
752 | * this page refers to as @c sb. | |
13c4b877 | 753 | */ |
54c1bf78 BK |
754 | template<typename _CharT, typename _Traits> |
755 | class basic_fstream : public basic_iostream<_CharT, _Traits> | |
756 | { | |
757 | public: | |
758 | // Types: | |
759 | typedef _CharT char_type; | |
760 | typedef _Traits traits_type; | |
761 | typedef typename traits_type::int_type int_type; | |
762 | typedef typename traits_type::pos_type pos_type; | |
763 | typedef typename traits_type::off_type off_type; | |
764 | ||
765 | // Non-standard types: | |
766 | typedef basic_filebuf<char_type, traits_type> __filebuf_type; | |
767 | typedef basic_ios<char_type, traits_type> __ios_type; | |
768 | typedef basic_iostream<char_type, traits_type> __iostream_type; | |
769 | ||
770 | private: | |
771 | __filebuf_type _M_filebuf; | |
fd58f127 | 772 | |
54c1bf78 BK |
773 | public: |
774 | // Constructors/destructor: | |
840ceb34 PE |
775 | /** |
776 | * @brief Default constructor. | |
777 | * | |
778 | * Initializes @c sb using its default constructor, and passes | |
779 | * @c &sb to the base class initializer. Does not open any files | |
780 | * (you haven't given it a filename to open). | |
13c4b877 | 781 | */ |
54c1bf78 | 782 | basic_fstream() |
d29cc32f | 783 | : __iostream_type(), _M_filebuf() |
54c1bf78 BK |
784 | { this->init(&_M_filebuf); } |
785 | ||
fd58f127 | 786 | /** |
840ceb34 PE |
787 | * @brief Create an input/output file stream. |
788 | * @param s Null terminated string specifying the filename. | |
fd58f127 PE |
789 | * @param mode Open file in specified mode (see std::ios_base). |
790 | * | |
791 | * Tip: When using std::string to hold the filename, you must use | |
792 | * .c_str() before passing it to this constructor. | |
13c4b877 | 793 | */ |
fd58f127 | 794 | explicit |
54c1bf78 BK |
795 | basic_fstream(const char* __s, |
796 | ios_base::openmode __mode = ios_base::in | ios_base::out) | |
797 | : __iostream_type(NULL), _M_filebuf() | |
fd58f127 PE |
798 | { |
799 | this->init(&_M_filebuf); | |
800 | this->open(__s, __mode); | |
54c1bf78 | 801 | } |
fd58f127 | 802 | |
13c4b877 PC |
803 | #ifdef __GXX_EXPERIMENTAL_CXX0X__ |
804 | /** | |
805 | * @brief Create an input/output file stream. | |
806 | * @param s Null terminated string specifying the filename. | |
807 | * @param mode Open file in specified mode (see std::ios_base). | |
808 | */ | |
809 | explicit | |
810 | basic_fstream(const std::string& __s, | |
811 | ios_base::openmode __mode = ios_base::in | ios_base::out) | |
812 | : __iostream_type(NULL), _M_filebuf() | |
813 | { | |
814 | this->init(&_M_filebuf); | |
815 | this->open(__s, __mode); | |
816 | } | |
817 | #endif | |
818 | ||
840ceb34 PE |
819 | /** |
820 | * @brief The destructor does nothing. | |
821 | * | |
822 | * The file is closed by the filebuf object, not the formatting | |
823 | * stream. | |
13c4b877 | 824 | */ |
54c1bf78 BK |
825 | ~basic_fstream() |
826 | { } | |
fd58f127 | 827 | |
54c1bf78 | 828 | // Members: |
fd58f127 | 829 | /** |
840ceb34 PE |
830 | * @brief Accessing the underlying buffer. |
831 | * @return The current basic_filebuf buffer. | |
832 | * | |
833 | * This hides both signatures of std::basic_ios::rdbuf(). | |
13c4b877 | 834 | */ |
fd58f127 | 835 | __filebuf_type* |
07814743 | 836 | rdbuf() const |
54c1bf78 BK |
837 | { return const_cast<__filebuf_type*>(&_M_filebuf); } |
838 | ||
fd58f127 | 839 | /** |
840ceb34 PE |
840 | * @brief Wrapper to test for an open file. |
841 | * @return @c rdbuf()->is_open() | |
13c4b877 | 842 | */ |
fd58f127 | 843 | bool |
85a5f64e PC |
844 | is_open() |
845 | { return _M_filebuf.is_open(); } | |
846 | ||
847 | // _GLIBCXX_RESOLVE_LIB_DEFECTS | |
848 | // 365. Lack of const-qualification in clause 27 | |
849 | bool | |
850 | is_open() const | |
851 | { return _M_filebuf.is_open(); } | |
54c1bf78 | 852 | |
fd58f127 | 853 | /** |
840ceb34 PE |
854 | * @brief Opens an external file. |
855 | * @param s The name of the file. | |
856 | * @param mode The open mode flags. | |
857 | * | |
858 | * Calls @c std::basic_filebuf::open(s,mode). If that | |
859 | * function fails, @c failbit is set in the stream's error state. | |
fd58f127 PE |
860 | * |
861 | * Tip: When using std::string to hold the filename, you must use | |
862 | * .c_str() before passing it to this constructor. | |
13c4b877 | 863 | */ |
fd58f127 PE |
864 | void |
865 | open(const char* __s, | |
54c1bf78 | 866 | ios_base::openmode __mode = ios_base::in | ios_base::out) |
fd58f127 | 867 | { |
54c1bf78 | 868 | if (!_M_filebuf.open(__s, __mode)) |
43be7fe7 | 869 | this->setstate(ios_base::failbit); |
7a59efae PC |
870 | else |
871 | // _GLIBCXX_RESOLVE_LIB_DEFECTS | |
872 | // 409. Closing an fstream should clear error state | |
873 | this->clear(); | |
54c1bf78 BK |
874 | } |
875 | ||
13c4b877 PC |
876 | #ifdef __GXX_EXPERIMENTAL_CXX0X__ |
877 | /** | |
878 | * @brief Opens an external file. | |
879 | * @param s The name of the file. | |
880 | * @param mode The open mode flags. | |
881 | * | |
882 | * Calls @c std::basic_filebuf::open(s,mode). If that | |
883 | * function fails, @c failbit is set in the stream's error state. | |
884 | */ | |
885 | void | |
886 | open(const std::string& __s, | |
887 | ios_base::openmode __mode = ios_base::in | ios_base::out) | |
888 | { | |
889 | if (!_M_filebuf.open(__s, __mode)) | |
890 | this->setstate(ios_base::failbit); | |
891 | else | |
892 | // _GLIBCXX_RESOLVE_LIB_DEFECTS | |
893 | // 409. Closing an fstream should clear error state | |
894 | this->clear(); | |
895 | } | |
896 | #endif | |
897 | ||
840ceb34 PE |
898 | /** |
899 | * @brief Close the file. | |
900 | * | |
901 | * Calls @c std::basic_filebuf::close(). If that function | |
902 | * fails, @c failbit is set in the stream's error state. | |
13c4b877 | 903 | */ |
fd58f127 | 904 | void |
07814743 | 905 | close() |
fd58f127 | 906 | { |
54c1bf78 | 907 | if (!_M_filebuf.close()) |
43be7fe7 | 908 | this->setstate(ios_base::failbit); |
54c1bf78 BK |
909 | } |
910 | }; | |
3cbc7af0 BK |
911 | |
912 | _GLIBCXX_END_NAMESPACE | |
54c1bf78 | 913 | |
5f697f7a | 914 | #ifndef _GLIBCXX_EXPORT_TEMPLATE |
54c1bf78 | 915 | # include <bits/fstream.tcc> |
725dc051 | 916 | #endif |
54c1bf78 | 917 | |
1143680e | 918 | #endif /* _GLIBCXX_FSTREAM */ |