// -*- C++ -*- /*************************************************************************** * * fstream -- declarations of the C++ Standard Library file stream classes * * $Id$ * *************************************************************************** * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * implied. See the License for the specific language governing * permissions and limitations under the License. * * Copyright 1994-2008 Rogue Wave Software, Inc. * **************************************************************************/ #ifndef _RWSTD_FSTREAM_INCLUDED #define _RWSTD_FSTREAM_INCLUDED #if __GNUG__ >= 3 # pragma GCC system_header #endif // gcc >= 3 #include #include #include #include #include #include #ifndef _RWSTD_NO_REDUNDANT_DEFINITIONS # include # include #endif // _RWSTD_NO_REDUNDANT_DEFINITIONS #ifndef _RWSTD_PBACK_SIZE # define _RWSTD_PBACK_SIZE ((_RWSTD_STREAMSIZE)4) #endif // _RWSTD_PBACK_SIZE _RWSTD_NAMESPACE (std) { #ifndef _RWSTD_IOSFWD_INCLUDED _EXPORT template > class basic_filebuf; _EXPORT template > class basic_ifstream; _EXPORT template > class basic_ofstream; _EXPORT template > class basic_fstream; typedef basic_filebuf filebuf; typedef basic_ifstream ifstream; typedef basic_ofstream ofstream; typedef basic_fstream fstream; # ifndef _RWSTD_NO_WCHAR_T typedef basic_filebuf wfilebuf; typedef basic_ifstream wifstream; typedef basic_ofstream wofstream; typedef basic_fstream wfstream; # endif // _RWSTD_NO_WCHAR_T #endif // _RWSTD_IOSFWD_INCLUDED _EXPORT template class basic_filebuf: public basic_streambuf<_CharT, _Traits> { typedef basic_streambuf<_CharT, _Traits> _Streambuf; public: typedef _CharT char_type; typedef _Traits traits_type; typedef _TYPENAME traits_type::int_type int_type; typedef _TYPENAME traits_type::pos_type pos_type; typedef _TYPENAME traits_type::off_type off_type; // 27.8.1.2, p1 basic_filebuf () : _Streambuf(), _C_file (0), _C_cur_pos (pos_type (off_type (-1))), _C_beg_pos (pos_type (off_type (-1))), _C_pbacksize (0) { // call the virtual setbuf defined in this class (but // not an override defined in a class derived from it) basic_filebuf::setbuf (0, _RWSTD_DEFAULT_BUFSIZE); } #if defined (_RWSTD_NO_EXT_FILEBUF) \ && !defined (_RWSTD_NO_STATIC_IOSTREAM_INIT) \ && (!defined (__GNUG__) || 2 < __GNUG__ || 96 < __GNUC_MINOR__) private: // g++ 2.95 error: `std::ios_base::Init' does not declare a template type friend struct ios_base::Init; #endif // _RWSTD_NO_EXT_FILEBUF && !_RWSTD_NO_STATIC_IOSTREAM_INIT // ctor extensions - associate this with an open file and // optionally set buffer size and caller-allocated buffer // NOTE: passed in buffer will NOT be deallocated #ifndef _RWSTD_NO_NATIVE_IO _EXPLICIT basic_filebuf (int __fd, char_type* __buf = 0, _RWSTD_STREAMSIZE __bufsz = _RWSTD_DEFAULT_BUFSIZE) : _Streambuf (ios_base::openmode (_RW::__rw_fdmode (__fd))), _C_file (0), _C_cur_pos (), _C_beg_pos (), _C_pbacksize (0) { _C_open (__fd, 0, __buf, __bufsz); } #endif // _RWSTD_NO_NATIVE_IO public: #if !defined(_RWSTD_NO_EXT_FILEBUF) || defined(_RWSTD_NO_NATIVE_IO) // extension enabled only if the macro stdin is also #defined // i.e., if the header or has been #included # ifdef stdin _EXPLICIT basic_filebuf (FILE *__fptr, char_type* __buf = 0, _RWSTD_STREAMSIZE __bufsz = _RWSTD_DEFAULT_BUFSIZE) : _Streambuf (), _C_file (0), _C_cur_pos (), _C_beg_pos (), _C_pbacksize (0) { open (__fptr, __buf, __bufsz); } # endif // stdin #endif // !_RWSTD_NO_EXT_FILEBUF || _RWSTD_NO_NATIVE_IO // 27.8.1.2, p3 virtual ~basic_filebuf (); // 27.8.1.3, p2 (last optional argument is an extension) basic_filebuf* open (const char*, ios_base::openmode, long = 0666); #ifndef _RWSTD_NO_EXT_FILEBUF // extensions - associate *this with an open file descriptor // and optionally set buffer size and caller-allocated buffer // NOTE: passed in buffer will NOT be deallocated # ifndef _RWSTD_NO_NATIVE_IO basic_filebuf* open (int __fd, char_type *__buf = 0, _RWSTD_STREAMSIZE __bufsz = _RWSTD_DEFAULT_BUFSIZE) { return _C_open (__fd, 0, __buf, __bufsz); } # endif // _RWSTD_NO_NATIVE_IO # ifdef stdin // extension enabled only if the macro stdin is also #defined // i.e., if the header or has been #included basic_filebuf* open (FILE *__file, char_type *__buf = 0, _RWSTD_STREAMSIZE __bufsz = _RWSTD_DEFAULT_BUFSIZE) { return _C_open (-1, __file, __buf, __bufsz); } # endif // stdin # ifndef _RWSTD_NO_NATIVE_IO // extension - return the associated file descriptor int fd () const { return _RW::__rw_fileno (_C_file, this->_C_state); } // extension - associate *this with an open file descriptor basic_filebuf* attach (int __fd) { return _C_open (__fd, 0, this->_C_buffer, this->_C_bufsize); } // extension - flush and detach from file descriptor without closing it int detach () { const int __fd = fd (); return close (false) ? __fd : -1; } # endif // _RWSTD_NO_NATIVE_IO #endif // _RWSTD_NO_EXT_FILEBUF // 27.8.1.3, p6, argument is an extension basic_filebuf* close (bool = true); // 27.8.1.3, p1 bool is_open () const { return 0 != _C_file; } protected: // 27.8.1.4, p1 virtual _RWSTD_STREAMSIZE showmanyc (); // 27.8.1.4, p3 virtual int_type underflow (); // 27.8.1.4, p4 - same as base implementation // virtual int_type uflow (); // 27.8.1.4, p8 virtual int_type overflow (int_type = traits_type::eof ()); // 27.8.1.4, p5 virtual int_type pbackfail (int_type = traits_type::eof ()); // 27.8.1.4, p10 // setbuf (0, 0) sets unbuffered mode (safe to use at any time) // setbuf (0, N) sets buffered mode with internal buffer of size N // setbuf (b, N) sets buffered mode with user-allocated buffer `b' // of size `N' (user responsible for deallocation) virtual basic_streambuf* setbuf (char_type*, _RWSTD_STREAMSIZE); // 27.8.1.4, p11 virtual pos_type seekoff (off_type, ios_base::seekdir, ios_base::openmode = _RW::__rw_in_out); // 27.8.1.4, p14 virtual pos_type seekpos (pos_type, ios_base::openmode = _RW::__rw_in_out); // 27.8.1.4, p16 - in input mode, repopulates buffer from file virtual int sync (); // overridden for efficiency virtual _RWSTD_STREAMSIZE xsputn (const char_type*, _RWSTD_STREAMSIZE); private: basic_filebuf* _C_open (int, void*, char_type*, _RWSTD_STREAMSIZE); // count newlines in char sequence to handle CR/LF translation on win32 // calculates seek offsets in external representation off_type _C_crlf_extern_count (const char*, const char*) const; // calculates seek offsets in internal representation off_type _C_crlf_intern_count (const char_type*, const char_type*) const; // write unshift sequence to file (multibyte, state-dependent encondings) bool _C_unshift (); void *_C_file; // underlying FILE ptr or file descriptor pos_type _C_cur_pos; // offset/state in file corresponding to // end of buffer, and actual pos in file pos_type _C_beg_pos; // offset/state in file corresponding // to the beginning of buffer _RWSTD_SIZE_T _C_pbacksize; // size of putback area }; template inline basic_filebuf<_CharT, _Traits>::~basic_filebuf () { _TRY { close (); } _CATCH (...) { // LWG issue 622: swallow all exceptions } if (this->_C_own_buf ()) delete [] this->_C_buffer; } template inline _TYPENAME basic_filebuf<_CharT, _Traits>::off_type basic_filebuf<_CharT, _Traits>:: _C_crlf_extern_count (const char* __start, const char* __finish) const { _RWSTD_ASSERT (__start <= __finish); off_type __n = 0; #if defined (_RWSTD_NEWLINE_CR_LF) || defined (_RWSTD_NEWLINE_LF_CR) // compute the number of newline characters in the external representation if (!(this->_C_state & ios_base::binary)) { typedef char_traits _CTraits; while ((__start = _CTraits::find (__start, __finish - __start, '\n'))) { ++__start; ++__n; } } #else // if !defined (_RWSTD_NEWLINE_CR_LF) || ... _RWSTD_UNUSED (__start); _RWSTD_UNUSED (__finish); #endif // _RWSTD_NEWLINE_CR_LF return __n; } template inline _TYPENAME basic_filebuf<_CharT, _Traits>::off_type basic_filebuf<_CharT, _Traits>:: _C_crlf_intern_count (const char_type* __start, const char_type* __finish) const { _RWSTD_ASSERT (__start <= __finish); off_type __n = 0; #if defined (_RWSTD_NEWLINE_CR_LF) || defined (_RWSTD_NEWLINE_LF_CR) // compute the number of newline characters in the internal representation if (!(this->_C_state & ios_base::binary)) { const char_type __nl = _USE_FACET (ctype, this->getloc ()).widen ('\n'); while ((__start = _Traits::find (__start, __finish - __start, __nl))) { ++__start; ++__n; } } #else // if !defined (_RWSTD_NEWLINE_CR_LF) || ... _RWSTD_UNUSED (__start); _RWSTD_UNUSED (__finish); #endif // _RWSTD_NEWLINE_CR_LF return __n; } template class basic_ifstream: public basic_istream<_CharT, _Traits> { public: typedef _CharT char_type; typedef _Traits traits_type; typedef _TYPENAME traits_type::int_type int_type; typedef _TYPENAME traits_type::pos_type pos_type; typedef _TYPENAME traits_type::off_type off_type; // NOTE: the ctors below pass the address of an unitialized // member variable, _C_filebuf, to a base class ctor // the variable will be initialized only *after* the base // class ctor returns basic_ifstream () : basic_istream (rdbuf ()) { } _EXPLICIT basic_ifstream (const char *__name, ios_base::openmode __mode = ios_base::in, long __prot = 0666) : basic_istream (rdbuf ()) { open (__name, __mode, __prot); } #ifndef _RWSTD_NO_EXT_FILEBUF // extensions - associate this with an open file and set buffer # ifndef _RWSTD_NO_NATIVE_IO _EXPLICIT basic_ifstream (int __fd, char_type *__buf = 0, _RWSTD_STREAMSIZE __n = _RWSTD_DEFAULT_BUFSIZE) : basic_istream (rdbuf ()) { open (__fd, __buf, __n); } # endif // _RWSTD_NO_NATIVE_IO # ifdef stdin _EXPLICIT basic_ifstream (FILE *__fptr, char_type *__buf = 0, _RWSTD_STREAMSIZE __n = _RWSTD_DEFAULT_BUFSIZE) : basic_istream (rdbuf ()) { open (__fptr, __buf, __n); } # endif // stdin #endif // _RWSTD_NO_EXT_FILEBUF // NOTE: the pointer returned from rdbuf() may be different from // the one passed to basic_ios<>::rdbuf (basic_filebuf<>*) basic_filebuf* rdbuf() const { // necessary to help SunPro 5.0/T9 typedef basic_ifstream __self_type; return &_RWSTD_CONST_CAST (__self_type*, this)->_C_filebuf; } bool is_open () const { return rdbuf ()->is_open (); } void open (const char *__name, ios_base::openmode __mode = ios_base::in, long __prot = 0666) { this->clear (rdbuf ()->open (__name, __mode |= ios_base::in, __prot) ? ios_base::goodbit : ios_base::failbit); } #ifndef _RWSTD_NO_EXT_FILEBUF // extensions - associate this with an open file and set buffer # ifndef _RWSTD_NO_NATIVE_IO void open (int __fd, char_type *__buf=0, _RWSTD_STREAMSIZE __n = _RWSTD_DEFAULT_BUFSIZE) { this->clear (rdbuf ()->open (__fd, __buf, __n) ? ios_base::goodbit : ios_base::failbit); } # endif // _RWSTD_NO_NATIVE_IO # ifdef stdin void open (FILE *__fptr, char_type *__buf=0, _RWSTD_STREAMSIZE __n = _RWSTD_DEFAULT_BUFSIZE) { this->clear (rdbuf ()->open (__fptr, __buf, __n) ? ios_base::goodbit : ios_base::failbit); } # endif // stdin #endif // _RWSTD_NO_EXT_FILEBUF void close () { if (!rdbuf ()->close ()) this->setstate (ios_base::failbit); } private: basic_filebuf _C_filebuf; }; template class basic_ofstream: public basic_ostream<_CharT, _Traits> { public: typedef _CharT char_type; typedef _Traits traits_type; typedef _TYPENAME traits_type::int_type int_type; typedef _TYPENAME traits_type::pos_type pos_type; typedef _TYPENAME traits_type::off_type off_type; // NOTE: the ctors below pass the address of an unitialized // member variable, _C_filebuf, to a base class ctor // the variable will be initialized only *after* the base // class ctor returns basic_ofstream () : basic_ostream (rdbuf ()) { } _EXPLICIT basic_ofstream (const char *__name, ios_base::openmode __mode = ios_base::out, long __prot = 0666) : basic_ostream (rdbuf ()) { open (__name, __mode, __prot); } #ifndef _RWSTD_NO_EXT_FILEBUF // extensions - associate this with an open file and set buffer # ifndef _RWSTD_NO_NATIVE_IO _EXPLICIT basic_ofstream (int __fd, char_type *__buf = 0, _RWSTD_STREAMSIZE __n = _RWSTD_DEFAULT_BUFSIZE) : basic_ostream (rdbuf ()) { open (__fd, __buf, __n); } # endif // _RWSTD_NO_NATIVE_IO # ifdef stdin _EXPLICIT basic_ofstream (FILE *__fptr, char_type *__buf = 0, _RWSTD_STREAMSIZE __n = _RWSTD_DEFAULT_BUFSIZE) : basic_ostream (rdbuf ()) { open (__fptr, __buf, __n); } # endif // stdin #endif // _RWSTD_NO_EXT_FILEBUF // NOTE: the pointer returned from rdbuf() may be different from // the one passed to basic_ios<>::rdbuf (basic_filebuf<>*) basic_filebuf* rdbuf () const { // necessary to help SunPro 5.0/T9 typedef basic_ofstream _SelfT; return &_RWSTD_CONST_CAST (_SelfT*, this)->_C_filebuf; } bool is_open () const { return rdbuf ()->is_open (); } void open (const char *__name, ios_base::openmode __mode = ios_base::out, long __prot = 0666) { this->clear (rdbuf ()->open (__name, __mode |= ios_base::out, __prot) ? ios_base::goodbit : ios_base::failbit); } #ifndef _RWSTD_NO_EXT_FILEBUF // extensions - associate this with an open file and set buffer # ifndef _RWSTD_NO_NATIVE_IO void open (int __fd, char_type *__buf=0, _RWSTD_STREAMSIZE __n = _RWSTD_DEFAULT_BUFSIZE) { this->clear (rdbuf ()->open (__fd, __buf, __n) ? ios_base::goodbit : ios_base::failbit); } # endif // _RWSTD_NO_NATIVE_IO # ifdef stdin void open (FILE *__fp, char_type *__buf=0, _RWSTD_STREAMSIZE __n = _RWSTD_DEFAULT_BUFSIZE) { this->clear (rdbuf ()->open (__fp, __buf, __n) ? ios_base::goodbit : ios_base::failbit); } # endif // stdin #endif // _RWSTD_NO_EXT_FILEBUF void close() { if (!rdbuf ()->close ()) this->setstate (ios_base::failbit); } private: basic_filebuf _C_filebuf; }; template class basic_fstream: public basic_iostream<_CharT, _Traits> { public: typedef _CharT char_type; typedef _Traits traits_type; typedef _TYPENAME traits_type::int_type int_type; typedef _TYPENAME traits_type::pos_type pos_type; typedef _TYPENAME traits_type::off_type off_type; // NOTE: the ctors below pass the address of an unitialized // member variable, _C_filebuf, to a base class ctor // the variable will be initialized only *after* the base // class ctor returns basic_fstream () : basic_iostream(rdbuf ()) { } _EXPLICIT basic_fstream (const char *__name, ios_base::openmode __mode = _RW::__rw_in_out, long __prot = 0666) : basic_iostream(rdbuf ()) { open (__name, __mode, __prot); } #ifndef _RWSTD_NO_EXT_FILEBUF // extensions - associate this with an open file and set buffer # ifndef _RWSTD_NO_NATIVE_IO _EXPLICIT basic_fstream (int __fd, char_type *__buf = 0, _RWSTD_STREAMSIZE __n = _RWSTD_DEFAULT_BUFSIZE) : basic_iostream(rdbuf ()) { open (__fd, __buf, __n); } # endif // _RWSTD_NO_NATIVE_IO # ifdef stdin _EXPLICIT basic_fstream (FILE *__fptr, char_type *__buf = 0, _RWSTD_STREAMSIZE __n = _RWSTD_DEFAULT_BUFSIZE) : basic_iostream(rdbuf ()) { open (__fptr, __buf, __n); } # endif // stdin #endif // _RWSTD_NO_EXT_FILEBUF // NOTE: the pointer returned from rdbuf() may be different from // the one passed to basic_ios<>::rdbuf (basic_filebuf<>*) basic_filebuf* rdbuf() const { // necessary to help SunPro 5.0/T9 typedef basic_fstream _SelfT; return &_RWSTD_CONST_CAST (_SelfT*, this)->_C_filebuf; } bool is_open () const { return rdbuf ()->is_open (); } void open (const char *__name, ios_base::openmode __mode = _RW::__rw_in_out, long __prot = 0666) { this->clear (rdbuf ()->open (__name, __mode, __prot) ? ios_base::goodbit : ios_base::failbit); } #ifndef _RWSTD_NO_EXT_FILEBUF // extensions - associate this with an open file and set buffer" # ifndef _RWSTD_NO_NATIVE_IO void open (int __fd, char_type *__buf=0, _RWSTD_STREAMSIZE __n = _RWSTD_DEFAULT_BUFSIZE) { this->clear (rdbuf ()->open (__fd, __buf, __n) ? ios_base::goodbit : ios_base::failbit); } # endif // _RWSTD_NO_NATIVE_IO # ifdef stdin void open (FILE *__fptr, char_type *__buf=0, _RWSTD_STREAMSIZE __n = _RWSTD_DEFAULT_BUFSIZE) { this->clear (rdbuf ()->open (__fptr, __buf, __n) ? ios_base::goodbit : ios_base::failbit); } # endif // stdin #endif // _RWSTD_NO_EXT_FILEBUF void close () { if (!rdbuf ()->close ()) this->setstate (ios_base::failbit); } private: basic_filebuf _C_filebuf; }; } // namespace std #if _RWSTD_DEFINE_TEMPLATE_FIRST (_BASIC_FILEBUF) # include #endif // _RWSTD_DEFINE_TEMPLATE_FIRST (_BASIC_FILEBUF) #ifdef _RWSTD_MSVC # pragma warning (push) # pragma warning (disable: 4231) #endif // _RWSTD_MSVC _RWSTD_NAMESPACE (std) { #if _RWSTD_INSTANTIATE (_BASIC_FILEBUF, _CHAR) _RWSTD_INSTANTIATE_2 (class _RWSTD_TI_EXPORT basic_filebuf >); #endif // _RWSTD_INSTANTIATE (_BASIC_FILEBUF, _CHAR) #if _RWSTD_INSTANTIATE (_BASIC_FILEBUF, _WCHAR_T) _RWSTD_INSTANTIATE_2 (class _RWSTD_TI_EXPORT basic_filebuf >); #endif // _RWSTD_INSTANTIATE (_BASIC_FILEBUF, _WCHAR_T) } // namespace std #ifdef _RWSTD_MSVC # pragma warning (pop) #endif // _RWSTD_MSVC #if _RWSTD_DEFINE_TEMPLATE_LAST (_BASIC_FILEBUF) # include #endif // _RWSTD_DEFINE_TEMPLATE_LAST (_BASIC_FILEBUF) #endif // _RWSTD_FSTREAM_INCLUDED