std_fstream.h revision 132720
197403Sobrien// File based streams -*- C++ -*- 297403Sobrien 3110614Skan// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003 497403Sobrien// Free Software Foundation, Inc. 597403Sobrien// 697403Sobrien// This file is part of the GNU ISO C++ Library. This library is free 797403Sobrien// software; you can redistribute it and/or modify it under the 897403Sobrien// terms of the GNU General Public License as published by the 997403Sobrien// Free Software Foundation; either version 2, or (at your option) 1097403Sobrien// any later version. 1197403Sobrien 1297403Sobrien// This library is distributed in the hope that it will be useful, 1397403Sobrien// but WITHOUT ANY WARRANTY; without even the implied warranty of 1497403Sobrien// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1597403Sobrien// GNU General Public License for more details. 1697403Sobrien 1797403Sobrien// You should have received a copy of the GNU General Public License along 1897403Sobrien// with this library; see the file COPYING. If not, write to the Free 1997403Sobrien// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 2097403Sobrien// USA. 2197403Sobrien 2297403Sobrien// As a special exception, you may use this file as part of a free software 2397403Sobrien// library without restriction. Specifically, if other files instantiate 2497403Sobrien// templates or use macros or inline functions from this file, or you compile 2597403Sobrien// this file and link it with other files to produce an executable, this 2697403Sobrien// file does not by itself cause the resulting executable to be covered by 2797403Sobrien// the GNU General Public License. This exception does not however 2897403Sobrien// invalidate any other reasons why the executable file might be covered by 2997403Sobrien// the GNU General Public License. 3097403Sobrien 3197403Sobrien// 3297403Sobrien// ISO C++ 14882: 27.8 File-based streams 3397403Sobrien// 3497403Sobrien 3597403Sobrien/** @file fstream 3697403Sobrien * This is a Standard C++ Library header. You should @c #include this header 3797403Sobrien * in your programs, rather than any of the "st[dl]_*.h" implementation files. 3897403Sobrien */ 3997403Sobrien 40132720Skan#ifndef _GLIBCXX_FSTREAM 41132720Skan#define _GLIBCXX_FSTREAM 1 4297403Sobrien 4397403Sobrien#pragma GCC system_header 4497403Sobrien 4597403Sobrien#include <istream> 4697403Sobrien#include <ostream> 4797403Sobrien#include <locale> // For codecvt 48132720Skan#include <cstdio> // For SEEK_SET, SEEK_CUR, SEEK_END, BUFSIZ 4997403Sobrien#include <bits/basic_file.h> 5097403Sobrien#include <bits/gthr.h> 5197403Sobrien 5297403Sobriennamespace std 5397403Sobrien{ 54117397Skan // [27.8.1.1] template class basic_filebuf 55117397Skan /** 56117397Skan * @brief The actual work of input and output (for files). 57117397Skan * 58117397Skan * This class associates both its input and output sequence with an 59117397Skan * external disk file, and maintains a joint file position for both 60117397Skan * sequences. Many of its sematics are described in terms of similar 61117397Skan * behavior in the Standard C Library's @c FILE streams. 62117397Skan */ 63132720Skan // Requirements on traits_type, specific to this class: 64132720Skan // traits_type::pos_type must be fpos<traits_type::state_type> 65132720Skan // traits_type::off_type must be streamoff 66132720Skan // traits_type::state_type must be Assignable and DefaultConstructable, 67132720Skan // and traits_type::state_type() must be the initial state for codecvt. 6897403Sobrien template<typename _CharT, typename _Traits> 6997403Sobrien class basic_filebuf : public basic_streambuf<_CharT, _Traits> 7097403Sobrien { 7197403Sobrien public: 7297403Sobrien // Types: 7397403Sobrien typedef _CharT char_type; 7497403Sobrien typedef _Traits traits_type; 7597403Sobrien typedef typename traits_type::int_type int_type; 7697403Sobrien typedef typename traits_type::pos_type pos_type; 7797403Sobrien typedef typename traits_type::off_type off_type; 7897403Sobrien 79117397Skan //@{ 80117397Skan /** 81117397Skan * @if maint 82117397Skan * @doctodo 83117397Skan * @endif 84117397Skan */ 8597403Sobrien typedef basic_streambuf<char_type, traits_type> __streambuf_type; 8697403Sobrien typedef basic_filebuf<char_type, traits_type> __filebuf_type; 8797403Sobrien typedef __basic_file<char> __file_type; 8897403Sobrien typedef typename traits_type::state_type __state_type; 8997403Sobrien typedef codecvt<char_type, char, __state_type> __codecvt_type; 90117397Skan //@} 9197403Sobrien 9297403Sobrien friend class ios_base; // For sync_with_stdio. 9397403Sobrien 9497403Sobrien protected: 9597403Sobrien // Data Members: 9697403Sobrien // MT lock inherited from libio or other low-level io library. 97117397Skan /** 98117397Skan * @if maint 99117397Skan * @doctodo 100117397Skan * @endif 101117397Skan */ 10297403Sobrien __c_lock _M_lock; 10397403Sobrien 10497403Sobrien // External buffer. 105117397Skan /** 106117397Skan * @if maint 107117397Skan * @doctodo 108117397Skan * @endif 109117397Skan */ 11097403Sobrien __file_type _M_file; 11197403Sobrien 112117397Skan /** 113117397Skan * @if maint 114132720Skan * Place to stash in || out || in | out settings for current filebuf. 115132720Skan * @endif 116132720Skan */ 117132720Skan ios_base::openmode _M_mode; 118132720Skan 119132720Skan // Beginning state type for codecvt. 120132720Skan /** 121132720Skan * @if maint 122117397Skan * @doctodo 123117397Skan * @endif 124117397Skan */ 12597403Sobrien __state_type _M_state_beg; 12697403Sobrien 127132720Skan // During output, the state that corresponds to pptr(), 128132720Skan // during input, the state that corresponds to egptr() and 129132720Skan // _M_ext_next. 130132720Skan /** 131132720Skan * @if maint 132132720Skan * @doctodo 133132720Skan * @endif 134132720Skan */ 135132720Skan __state_type _M_state_cur; 136132720Skan 137132720Skan // Not used for output. During input, the state that corresponds 138132720Skan // to eback() and _M_ext_buf. 139132720Skan /** 140132720Skan * @if maint 141132720Skan * @doctodo 142132720Skan * @endif 143132720Skan */ 144132720Skan __state_type _M_state_last; 145132720Skan 146132720Skan /** 147132720Skan * @if maint 148132720Skan * Pointer to the beginning of internal buffer. 149132720Skan * @endif 150132720Skan */ 151132720Skan char_type* _M_buf; 152132720Skan 153132720Skan /** 154132720Skan * @if maint 155132720Skan * Actual size of internal buffer. This number is equal to the size 156132720Skan * of the put area + 1 position, reserved for the overflow char of 157132720Skan * a full area. 158132720Skan * @endif 159132720Skan */ 160132720Skan size_t _M_buf_size; 161132720Skan 16297403Sobrien // Set iff _M_buf is allocated memory from _M_allocate_internal_buffer. 163117397Skan /** 164117397Skan * @if maint 165117397Skan * @doctodo 166117397Skan * @endif 167117397Skan */ 16897403Sobrien bool _M_buf_allocated; 16997403Sobrien 170117397Skan /** 171117397Skan * @if maint 172132720Skan * _M_reading == false && _M_writing == false for 'uncommitted' mode; 173132720Skan * _M_reading == true for 'read' mode; 174132720Skan * _M_writing == true for 'write' mode; 175132720Skan * 176132720Skan * NB: _M_reading == true && _M_writing == true is unused. 177117397Skan * @endif 178132720Skan */ 179132720Skan bool _M_reading; 180132720Skan bool _M_writing; 181132720Skan 182132720Skan //@{ 183132720Skan /** 184132720Skan * @if maint 185132720Skan * Necessary bits for putback buffer management. 186132720Skan * 187132720Skan * @note pbacks of over one character are not currently supported. 188132720Skan * @endif 189117397Skan */ 190132720Skan char_type _M_pback; 191132720Skan char_type* _M_pback_cur_save; 192132720Skan char_type* _M_pback_end_save; 193132720Skan bool _M_pback_init; 194132720Skan //@} 19597403Sobrien 196132720Skan // Cached codecvt facet. 197132720Skan const __codecvt_type* _M_codecvt; 198132720Skan 199132720Skan /** 200132720Skan * @if maint 201132720Skan * Buffer for external characters. Used for input when 202132720Skan * codecvt::always_noconv() == false. When valid, this corresponds 203132720Skan * to eback(). 204132720Skan * @endif 205132720Skan */ 206132720Skan char* _M_ext_buf; 207132720Skan 208132720Skan /** 209132720Skan * @if maint 210132720Skan * Size of buffer held by _M_ext_buf. 211132720Skan * @endif 212132720Skan */ 213132720Skan streamsize _M_ext_buf_size; 214132720Skan 215132720Skan /** 216132720Skan * @if maint 217132720Skan * Pointers into the buffer held by _M_ext_buf that delimit a 218132720Skan * subsequence of bytes that have been read but not yet converted. 219132720Skan * When valid, _M_ext_next corresponds to egptr(). 220132720Skan * @endif 221132720Skan */ 222132720Skan const char* _M_ext_next; 223132720Skan char* _M_ext_end; 224132720Skan 225132720Skan /** 226132720Skan * @if maint 227132720Skan * Initializes pback buffers, and moves normal buffers to safety. 228132720Skan * Assumptions: 229132720Skan * _M_in_cur has already been moved back 230132720Skan * @endif 231132720Skan */ 232132720Skan void 233132720Skan _M_create_pback() 234132720Skan { 235132720Skan if (!_M_pback_init) 236132720Skan { 237132720Skan _M_pback_cur_save = this->gptr(); 238132720Skan _M_pback_end_save = this->egptr(); 239132720Skan this->setg(&_M_pback, &_M_pback, &_M_pback + 1); 240132720Skan _M_pback_init = true; 241132720Skan } 242132720Skan } 243132720Skan 244132720Skan /** 245132720Skan * @if maint 246132720Skan * Deactivates pback buffer contents, and restores normal buffer. 247132720Skan * Assumptions: 248132720Skan * The pback buffer has only moved forward. 249132720Skan * @endif 250132720Skan */ 251132720Skan void 252132720Skan _M_destroy_pback() throw() 253132720Skan { 254132720Skan if (_M_pback_init) 255132720Skan { 256132720Skan // Length _M_in_cur moved in the pback buffer. 257132720Skan _M_pback_cur_save += this->gptr() != this->eback(); 258132720Skan this->setg(this->_M_buf, _M_pback_cur_save, _M_pback_end_save); 259132720Skan _M_pback_init = false; 260132720Skan } 261132720Skan } 262132720Skan 26397403Sobrien public: 26497403Sobrien // Constructors/destructor: 265117397Skan /** 266117397Skan * @brief Does not open any files. 267117397Skan * 268117397Skan * The default constructor initializes the parent class using its 269117397Skan * own default ctor. 270117397Skan */ 27197403Sobrien basic_filebuf(); 27297403Sobrien 273117397Skan /** 274117397Skan * @brief The destructor closes the file first. 275117397Skan */ 27697403Sobrien virtual 27797403Sobrien ~basic_filebuf() 278132720Skan { this->close(); } 27997403Sobrien 28097403Sobrien // Members: 281117397Skan /** 282117397Skan * @brief Returns true if the external file is open. 283117397Skan */ 28497403Sobrien bool 285117397Skan is_open() const throw() { return _M_file.is_open(); } 28697403Sobrien 287117397Skan /** 288117397Skan * @brief Opens an external file. 289117397Skan * @param s The name of the file. 290117397Skan * @param mode The open mode flags. 291117397Skan * @return @c this on success, NULL on failure 292117397Skan * 293117397Skan * If a file is already open, this function immediately fails. 294117397Skan * Otherwise it tries to open the file named @a s using the flags 295117397Skan * given in @a mode. 296117397Skan * 297117397Skan * [Table 92 gives the relation between openmode combinations and the 298117397Skan * equivalent fopen() flags, but the table has not been copied yet.] 299117397Skan */ 30097403Sobrien __filebuf_type* 30197403Sobrien open(const char* __s, ios_base::openmode __mode); 30297403Sobrien 303117397Skan /** 304117397Skan * @brief Closes the currently associated file. 305117397Skan * @return @c this on success, NULL on failure 306117397Skan * 307117397Skan * If no file is currently open, this function immediately fails. 308117397Skan * 309117397Skan * If a "put buffer area" exists, @c overflow(eof) is called to flush 310117397Skan * all the characters. The file is then closed. 311117397Skan * 312117397Skan * If any operations fail, this function also fails. 313117397Skan */ 31497403Sobrien __filebuf_type* 315117397Skan close() throw(); 31697403Sobrien 31797403Sobrien protected: 318117397Skan /** 319117397Skan * @if maint 320117397Skan * @doctodo 321117397Skan * @endif 322117397Skan */ 32397403Sobrien void 32497403Sobrien _M_allocate_internal_buffer(); 32597403Sobrien 326117397Skan /** 327117397Skan * @if maint 328117397Skan * @doctodo 329117397Skan * @endif 330117397Skan */ 33197403Sobrien void 332117397Skan _M_destroy_internal_buffer() throw(); 33397403Sobrien 334117397Skan // [27.8.1.4] overridden virtual functions 335117397Skan // [documentation is inherited] 33697403Sobrien virtual streamsize 33797403Sobrien showmanyc(); 33897403Sobrien 33997403Sobrien // Stroustrup, 1998, p. 628 34097403Sobrien // underflow() and uflow() functions are called to get the next 34197403Sobrien // charater from the real input source when the buffer is empty. 34297403Sobrien // Buffered input uses underflow() 34397403Sobrien 344117397Skan // [documentation is inherited] 34597403Sobrien virtual int_type 346110614Skan underflow(); 34797403Sobrien 348117397Skan // [documentation is inherited] 34997403Sobrien virtual int_type 35097403Sobrien pbackfail(int_type __c = _Traits::eof()); 35197403Sobrien 35297403Sobrien // Stroustrup, 1998, p 648 35397403Sobrien // The overflow() function is called to transfer characters to the 35497403Sobrien // real output destination when the buffer is full. A call to 35597403Sobrien // overflow(c) outputs the contents of the buffer plus the 35697403Sobrien // character c. 35797403Sobrien // 27.5.2.4.5 35897403Sobrien // Consume some sequence of the characters in the pending sequence. 359117397Skan /** 360117397Skan * @if maint 361117397Skan * @doctodo 362117397Skan * @endif 363117397Skan */ 364132720Skan virtual int_type 365132720Skan overflow(int_type __c = _Traits::eof()); 36697403Sobrien 36797403Sobrien // Convert internal byte sequence to external, char-based 36897403Sobrien // sequence via codecvt. 369117397Skan /** 370117397Skan * @if maint 371117397Skan * @doctodo 372117397Skan * @endif 373117397Skan */ 374132720Skan bool 375132720Skan _M_convert_to_external(char_type*, streamsize); 37697403Sobrien 377117397Skan /** 378117397Skan * @brief Manipulates the buffer. 379117397Skan * @param s Pointer to a buffer area. 380117397Skan * @param n Size of @a s. 381117397Skan * @return @c this 382117397Skan * 383117397Skan * If no file has been opened, and both @a s and @a n are zero, then 384117397Skan * the stream becomes unbuffered. Otherwise, @c s is used as a 385117397Skan * buffer; see 386117397Skan * http://gcc.gnu.org/onlinedocs/libstdc++/27_io/howto.html#2 387117397Skan * for more. 388117397Skan */ 38997403Sobrien virtual __streambuf_type* 39097403Sobrien setbuf(char_type* __s, streamsize __n); 39197403Sobrien 392117397Skan // [documentation is inherited] 39397403Sobrien virtual pos_type 39497403Sobrien seekoff(off_type __off, ios_base::seekdir __way, 39597403Sobrien ios_base::openmode __mode = ios_base::in | ios_base::out); 39697403Sobrien 397117397Skan // [documentation is inherited] 39897403Sobrien virtual pos_type 39997403Sobrien seekpos(pos_type __pos, 40097403Sobrien ios_base::openmode __mode = ios_base::in | ios_base::out); 40197403Sobrien 402132720Skan // Common code for seekoff and seekpos 403132720Skan /** 404132720Skan * @if maint 405132720Skan * @doctodo 406132720Skan * @endif 407132720Skan */ 408132720Skan pos_type 409132720Skan _M_seek(off_type __off, ios_base::seekdir __way, __state_type __state); 410132720Skan 411117397Skan // [documentation is inherited] 41297403Sobrien virtual int 413132720Skan sync(); 41497403Sobrien 415117397Skan // [documentation is inherited] 41697403Sobrien virtual void 41797403Sobrien imbue(const locale& __loc); 41897403Sobrien 419117397Skan // [documentation is inherited] 42097403Sobrien virtual streamsize 42197403Sobrien xsgetn(char_type* __s, streamsize __n) 42297403Sobrien { 423132720Skan // Clear out pback buffer before going on to the real deal... 42497403Sobrien streamsize __ret = 0; 425132720Skan if (this->_M_pback_init) 42697403Sobrien { 427132720Skan if (__n && this->gptr() == this->eback()) 42897403Sobrien { 429132720Skan *__s++ = *this->gptr(); 430132720Skan this->gbump(1); 431132720Skan __ret = 1; 43297403Sobrien } 433132720Skan _M_destroy_pback(); 43497403Sobrien } 43597403Sobrien if (__ret < __n) 43697403Sobrien __ret += __streambuf_type::xsgetn(__s, __n - __ret); 43797403Sobrien return __ret; 43897403Sobrien } 43997403Sobrien 440117397Skan // [documentation is inherited] 44197403Sobrien virtual streamsize 442132720Skan xsputn(const char_type* __s, streamsize __n); 44397403Sobrien 444132720Skan // Flushes output buffer, then writes unshift sequence. 445117397Skan /** 446117397Skan * @if maint 447117397Skan * @doctodo 448117397Skan * @endif 449117397Skan */ 450132720Skan bool 451132720Skan _M_terminate_output(); 45297403Sobrien 453117397Skan /** 454132720Skan * @if maint 455132720Skan * This function sets the pointers of the internal buffer, both get 456132720Skan * and put areas. Typically: 457132720Skan * 458132720Skan * __off == egptr() - eback() upon underflow/uflow ('read' mode); 459132720Skan * __off == 0 upon overflow ('write' mode); 460132720Skan * __off == -1 upon open, setbuf, seekoff/pos ('uncommitted' mode). 461132720Skan * 462132720Skan * NB: epptr() - pbase() == _M_buf_size - 1, since _M_buf_size 463132720Skan * reflects the actual allocated memory and the last cell is reserved 464132720Skan * for the overflow char of a full put area. 465117397Skan * @endif 466117397Skan */ 46797403Sobrien void 468132720Skan _M_set_buffer(streamsize __off) 46997403Sobrien { 470132720Skan const bool __testin = this->_M_mode & ios_base::in; 471132720Skan const bool __testout = this->_M_mode & ios_base::out; 472132720Skan 473132720Skan if (__testin && __off > 0) 474132720Skan this->setg(this->_M_buf, this->_M_buf, this->_M_buf + __off); 475132720Skan else 476132720Skan this->setg(this->_M_buf, this->_M_buf, this->_M_buf); 47797403Sobrien 478132720Skan if (__testout && __off == 0 && this->_M_buf_size > 1 ) 479132720Skan this->setp(this->_M_buf, this->_M_buf + this->_M_buf_size - 1); 480132720Skan else 481132720Skan this->setp(NULL, NULL); 48297403Sobrien } 48397403Sobrien }; 48497403Sobrien 485117397Skan // [27.8.1.5] Template class basic_ifstream 48697403Sobrien /** 487117397Skan * @brief Controlling input for files. 488117397Skan * 489117397Skan * This class supports reading from named files, using the inherited 490117397Skan * functions from std::basic_istream. To control the associated 491117397Skan * sequence, an instance of std::basic_filebuf is used, which this page 492117397Skan * refers to as @c sb. 49397403Sobrien */ 49497403Sobrien template<typename _CharT, typename _Traits> 49597403Sobrien class basic_ifstream : public basic_istream<_CharT, _Traits> 49697403Sobrien { 49797403Sobrien public: 49897403Sobrien // Types: 49997403Sobrien typedef _CharT char_type; 50097403Sobrien typedef _Traits traits_type; 50197403Sobrien typedef typename traits_type::int_type int_type; 50297403Sobrien typedef typename traits_type::pos_type pos_type; 50397403Sobrien typedef typename traits_type::off_type off_type; 50497403Sobrien 50597403Sobrien // Non-standard types: 50697403Sobrien typedef basic_filebuf<char_type, traits_type> __filebuf_type; 50797403Sobrien typedef basic_istream<char_type, traits_type> __istream_type; 50897403Sobrien 50997403Sobrien private: 510117397Skan /** 511117397Skan * @if maint 512117397Skan * @doctodo 513117397Skan * @endif 514117397Skan */ 51597403Sobrien __filebuf_type _M_filebuf; 51697403Sobrien 51797403Sobrien public: 518117397Skan // Constructors/Destructors: 519117397Skan /** 520117397Skan * @brief Default constructor. 521117397Skan * 522117397Skan * Initializes @c sb using its default constructor, and passes 523117397Skan * @c &sb to the base class initializer. Does not open any files 524117397Skan * (you haven't given it a filename to open). 525117397Skan */ 526132720Skan basic_ifstream() : __istream_type(), _M_filebuf() 52797403Sobrien { this->init(&_M_filebuf); } 52897403Sobrien 52997403Sobrien /** 530117397Skan * @brief Create an input file stream. 531117397Skan * @param s Null terminated string specifying the filename. 53297403Sobrien * @param mode Open file in specified mode (see std::ios_base). 53397403Sobrien * 534117397Skan * @c ios_base::in is automatically included in @a mode. 535117397Skan * 53697403Sobrien * Tip: When using std::string to hold the filename, you must use 53797403Sobrien * .c_str() before passing it to this constructor. 53897403Sobrien */ 53997403Sobrien explicit 54097403Sobrien basic_ifstream(const char* __s, ios_base::openmode __mode = ios_base::in) 541132720Skan : __istream_type(), _M_filebuf() 54297403Sobrien { 54397403Sobrien this->init(&_M_filebuf); 54497403Sobrien this->open(__s, __mode); 54597403Sobrien } 54697403Sobrien 547117397Skan /** 548117397Skan * @brief The destructor does nothing. 549117397Skan * 550117397Skan * The file is closed by the filebuf object, not the formatting 551117397Skan * stream. 552117397Skan */ 55397403Sobrien ~basic_ifstream() 55497403Sobrien { } 55597403Sobrien 55697403Sobrien // Members: 55797403Sobrien /** 558117397Skan * @brief Accessing the underlying buffer. 559117397Skan * @return The current basic_filebuf buffer. 560117397Skan * 561117397Skan * This hides both signatures of std::basic_ios::rdbuf(). 56297403Sobrien */ 56397403Sobrien __filebuf_type* 56497403Sobrien rdbuf() const 56597403Sobrien { return const_cast<__filebuf_type*>(&_M_filebuf); } 56697403Sobrien 567117397Skan /** 568117397Skan * @brief Wrapper to test for an open file. 569117397Skan * @return @c rdbuf()->is_open() 570117397Skan */ 57197403Sobrien bool 57297403Sobrien is_open() { return _M_filebuf.is_open(); } 57397403Sobrien 574117397Skan /** 575117397Skan * @brief Opens an external file. 576117397Skan * @param s The name of the file. 577117397Skan * @param mode The open mode flags. 578117397Skan * 579117397Skan * Calls @c std::basic_filebuf::open(s,mode|in). If that function 580117397Skan * fails, @c failbit is set in the stream's error state. 581117397Skan * 582117397Skan * Tip: When using std::string to hold the filename, you must use 583117397Skan * .c_str() before passing it to this constructor. 584117397Skan */ 58597403Sobrien void 58697403Sobrien open(const char* __s, ios_base::openmode __mode = ios_base::in) 58797403Sobrien { 58897403Sobrien if (!_M_filebuf.open(__s, __mode | ios_base::in)) 58997403Sobrien this->setstate(ios_base::failbit); 59097403Sobrien } 59197403Sobrien 592117397Skan /** 593117397Skan * @brief Close the file. 594117397Skan * 595117397Skan * Calls @c std::basic_filebuf::close(). If that function 596117397Skan * fails, @c failbit is set in the stream's error state. 597117397Skan */ 59897403Sobrien void 59997403Sobrien close() 60097403Sobrien { 60197403Sobrien if (!_M_filebuf.close()) 60297403Sobrien this->setstate(ios_base::failbit); 60397403Sobrien } 60497403Sobrien }; 60597403Sobrien 60697403Sobrien 607117397Skan // [27.8.1.8] Template class basic_ofstream 60897403Sobrien /** 609117397Skan * @brief Controlling output for files. 610117397Skan * 611117397Skan * This class supports reading from named files, using the inherited 612117397Skan * functions from std::basic_ostream. To control the associated 613117397Skan * sequence, an instance of std::basic_filebuf is used, which this page 614117397Skan * refers to as @c sb. 61597403Sobrien */ 61697403Sobrien template<typename _CharT, typename _Traits> 61797403Sobrien class basic_ofstream : public basic_ostream<_CharT,_Traits> 61897403Sobrien { 61997403Sobrien public: 62097403Sobrien // Types: 62197403Sobrien typedef _CharT char_type; 62297403Sobrien typedef _Traits traits_type; 62397403Sobrien typedef typename traits_type::int_type int_type; 62497403Sobrien typedef typename traits_type::pos_type pos_type; 62597403Sobrien typedef typename traits_type::off_type off_type; 62697403Sobrien 62797403Sobrien // Non-standard types: 62897403Sobrien typedef basic_filebuf<char_type, traits_type> __filebuf_type; 62997403Sobrien typedef basic_ostream<char_type, traits_type> __ostream_type; 63097403Sobrien 63197403Sobrien private: 632117397Skan /** 633117397Skan * @if maint 634117397Skan * @doctodo 635117397Skan * @endif 636117397Skan */ 63797403Sobrien __filebuf_type _M_filebuf; 63897403Sobrien 63997403Sobrien public: 64097403Sobrien // Constructors: 641117397Skan /** 642117397Skan * @brief Default constructor. 643117397Skan * 644117397Skan * Initializes @c sb using its default constructor, and passes 645117397Skan * @c &sb to the base class initializer. Does not open any files 646117397Skan * (you haven't given it a filename to open). 647117397Skan */ 648132720Skan basic_ofstream(): __ostream_type(), _M_filebuf() 64997403Sobrien { this->init(&_M_filebuf); } 65097403Sobrien 65197403Sobrien /** 652117397Skan * @brief Create an output file stream. 653117397Skan * @param s Null terminated string specifying the filename. 65497403Sobrien * @param mode Open file in specified mode (see std::ios_base). 65597403Sobrien * 656117397Skan * @c ios_base::out|ios_base::trunc is automatically included in 657117397Skan * @a mode. 658117397Skan * 65997403Sobrien * Tip: When using std::string to hold the filename, you must use 66097403Sobrien * .c_str() before passing it to this constructor. 66197403Sobrien */ 66297403Sobrien explicit 66397403Sobrien basic_ofstream(const char* __s, 66497403Sobrien ios_base::openmode __mode = ios_base::out|ios_base::trunc) 665132720Skan : __ostream_type(), _M_filebuf() 66697403Sobrien { 66797403Sobrien this->init(&_M_filebuf); 66897403Sobrien this->open(__s, __mode); 66997403Sobrien } 67097403Sobrien 671117397Skan /** 672117397Skan * @brief The destructor does nothing. 673117397Skan * 674117397Skan * The file is closed by the filebuf object, not the formatting 675117397Skan * stream. 676117397Skan */ 67797403Sobrien ~basic_ofstream() 67897403Sobrien { } 67997403Sobrien 68097403Sobrien // Members: 68197403Sobrien /** 682117397Skan * @brief Accessing the underlying buffer. 683117397Skan * @return The current basic_filebuf buffer. 684117397Skan * 685117397Skan * This hides both signatures of std::basic_ios::rdbuf(). 68697403Sobrien */ 68797403Sobrien __filebuf_type* 68897403Sobrien rdbuf() const 68997403Sobrien { return const_cast<__filebuf_type*>(&_M_filebuf); } 69097403Sobrien 69197403Sobrien /** 692117397Skan * @brief Wrapper to test for an open file. 693117397Skan * @return @c rdbuf()->is_open() 69497403Sobrien */ 69597403Sobrien bool 69697403Sobrien is_open() { return _M_filebuf.is_open(); } 69797403Sobrien 69897403Sobrien /** 699117397Skan * @brief Opens an external file. 700117397Skan * @param s The name of the file. 701117397Skan * @param mode The open mode flags. 70297403Sobrien * 703117397Skan * Calls @c std::basic_filebuf::open(s,mode|out|trunc). If that 704117397Skan * function fails, @c failbit is set in the stream's error state. 705117397Skan * 70697403Sobrien * Tip: When using std::string to hold the filename, you must use 70797403Sobrien * .c_str() before passing it to this constructor. 70897403Sobrien */ 70997403Sobrien void 71097403Sobrien open(const char* __s, 71197403Sobrien ios_base::openmode __mode = ios_base::out | ios_base::trunc) 71297403Sobrien { 71397403Sobrien if (!_M_filebuf.open(__s, __mode | ios_base::out)) 71497403Sobrien this->setstate(ios_base::failbit); 71597403Sobrien } 71697403Sobrien 717117397Skan /** 718117397Skan * @brief Close the file. 719117397Skan * 720117397Skan * Calls @c std::basic_filebuf::close(). If that function 721117397Skan * fails, @c failbit is set in the stream's error state. 722117397Skan */ 72397403Sobrien void 72497403Sobrien close() 72597403Sobrien { 72697403Sobrien if (!_M_filebuf.close()) 72797403Sobrien this->setstate(ios_base::failbit); 72897403Sobrien } 72997403Sobrien }; 73097403Sobrien 73197403Sobrien 732117397Skan // [27.8.1.11] Template class basic_fstream 73397403Sobrien /** 734117397Skan * @brief Controlling intput and output for files. 735117397Skan * 736117397Skan * This class supports reading from and writing to named files, using 737117397Skan * the inherited functions from std::basic_iostream. To control the 738117397Skan * associated sequence, an instance of std::basic_filebuf is used, which 739117397Skan * this page refers to as @c sb. 74097403Sobrien */ 74197403Sobrien template<typename _CharT, typename _Traits> 74297403Sobrien class basic_fstream : public basic_iostream<_CharT, _Traits> 74397403Sobrien { 74497403Sobrien public: 74597403Sobrien // Types: 74697403Sobrien typedef _CharT char_type; 74797403Sobrien typedef _Traits traits_type; 74897403Sobrien typedef typename traits_type::int_type int_type; 74997403Sobrien typedef typename traits_type::pos_type pos_type; 75097403Sobrien typedef typename traits_type::off_type off_type; 75197403Sobrien 75297403Sobrien // Non-standard types: 75397403Sobrien typedef basic_filebuf<char_type, traits_type> __filebuf_type; 75497403Sobrien typedef basic_ios<char_type, traits_type> __ios_type; 75597403Sobrien typedef basic_iostream<char_type, traits_type> __iostream_type; 75697403Sobrien 75797403Sobrien private: 758117397Skan /** 759117397Skan * @if maint 760117397Skan * @doctodo 761117397Skan * @endif 762117397Skan */ 76397403Sobrien __filebuf_type _M_filebuf; 76497403Sobrien 76597403Sobrien public: 76697403Sobrien // Constructors/destructor: 767117397Skan /** 768117397Skan * @brief Default constructor. 769117397Skan * 770117397Skan * Initializes @c sb using its default constructor, and passes 771117397Skan * @c &sb to the base class initializer. Does not open any files 772117397Skan * (you haven't given it a filename to open). 773117397Skan */ 77497403Sobrien basic_fstream() 775132720Skan : __iostream_type(), _M_filebuf() 77697403Sobrien { this->init(&_M_filebuf); } 77797403Sobrien 77897403Sobrien /** 779117397Skan * @brief Create an input/output file stream. 780117397Skan * @param s Null terminated string specifying the filename. 78197403Sobrien * @param mode Open file in specified mode (see std::ios_base). 78297403Sobrien * 78397403Sobrien * Tip: When using std::string to hold the filename, you must use 78497403Sobrien * .c_str() before passing it to this constructor. 78597403Sobrien */ 78697403Sobrien explicit 78797403Sobrien basic_fstream(const char* __s, 78897403Sobrien ios_base::openmode __mode = ios_base::in | ios_base::out) 78997403Sobrien : __iostream_type(NULL), _M_filebuf() 79097403Sobrien { 79197403Sobrien this->init(&_M_filebuf); 79297403Sobrien this->open(__s, __mode); 79397403Sobrien } 79497403Sobrien 795117397Skan /** 796117397Skan * @brief The destructor does nothing. 797117397Skan * 798117397Skan * The file is closed by the filebuf object, not the formatting 799117397Skan * stream. 800117397Skan */ 80197403Sobrien ~basic_fstream() 80297403Sobrien { } 80397403Sobrien 80497403Sobrien // Members: 80597403Sobrien /** 806117397Skan * @brief Accessing the underlying buffer. 807117397Skan * @return The current basic_filebuf buffer. 808117397Skan * 809117397Skan * This hides both signatures of std::basic_ios::rdbuf(). 81097403Sobrien */ 81197403Sobrien __filebuf_type* 81297403Sobrien rdbuf() const 81397403Sobrien { return const_cast<__filebuf_type*>(&_M_filebuf); } 81497403Sobrien 81597403Sobrien /** 816117397Skan * @brief Wrapper to test for an open file. 817117397Skan * @return @c rdbuf()->is_open() 81897403Sobrien */ 81997403Sobrien bool 82097403Sobrien is_open() { return _M_filebuf.is_open(); } 82197403Sobrien 82297403Sobrien /** 823117397Skan * @brief Opens an external file. 824117397Skan * @param s The name of the file. 825117397Skan * @param mode The open mode flags. 82697403Sobrien * 827117397Skan * Calls @c std::basic_filebuf::open(s,mode). If that 828117397Skan * function fails, @c failbit is set in the stream's error state. 829117397Skan * 83097403Sobrien * Tip: When using std::string to hold the filename, you must use 83197403Sobrien * .c_str() before passing it to this constructor. 83297403Sobrien */ 83397403Sobrien void 83497403Sobrien open(const char* __s, 83597403Sobrien ios_base::openmode __mode = ios_base::in | ios_base::out) 83697403Sobrien { 83797403Sobrien if (!_M_filebuf.open(__s, __mode)) 838132720Skan this->setstate(ios_base::failbit); 83997403Sobrien } 84097403Sobrien 841117397Skan /** 842117397Skan * @brief Close the file. 843117397Skan * 844117397Skan * Calls @c std::basic_filebuf::close(). If that function 845117397Skan * fails, @c failbit is set in the stream's error state. 846117397Skan */ 84797403Sobrien void 84897403Sobrien close() 84997403Sobrien { 85097403Sobrien if (!_M_filebuf.close()) 851132720Skan this->setstate(ios_base::failbit); 85297403Sobrien } 85397403Sobrien }; 85497403Sobrien} // namespace std 85597403Sobrien 856132720Skan#ifndef _GLIBCXX_EXPORT_TEMPLATE 85797403Sobrien# include <bits/fstream.tcc> 85897403Sobrien#endif 85997403Sobrien 860132720Skan#endif /* _GLIBCXX_FSTREAM */ 861