mirror of https://github.com/tongzx/nt5src
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
730 lines
20 KiB
730 lines
20 KiB
// fstream standard header
|
|
#pragma once
|
|
#ifndef _FSTREAM_
|
|
#define _FSTREAM_
|
|
#include <istream>
|
|
|
|
#pragma pack(push,8)
|
|
#pragma warning(push,3)
|
|
|
|
#pragma warning(disable: 4127)
|
|
_STD_BEGIN
|
|
|
|
extern _CRTIMP2 _Filet *__cdecl _Fiopen(const char *, ios_base::openmode);
|
|
|
|
// TEMPLATE FUNCTION _Fgetc
|
|
template<class _Elem> inline
|
|
bool _Fgetc(_Elem& _Ch, _Filet *_File)
|
|
{ // get an element from a C stream
|
|
return (fread(&_Ch, sizeof (_Elem), 1, _File) == 1);
|
|
}
|
|
|
|
template<> inline bool _Fgetc(char& _Byte, _Filet *_File)
|
|
{ // get a char element from a C stream
|
|
int _Meta;
|
|
if ((_Meta = fgetc(_File)) == EOF)
|
|
return (false);
|
|
else
|
|
{ // got one, convert to char
|
|
_Byte = (char)_Meta;
|
|
return (true);
|
|
}
|
|
}
|
|
|
|
template<> inline bool _Fgetc(wchar_t& _Wchar, _Filet *_File)
|
|
{ // get a wchar_t element from a C stream
|
|
wint_t _Meta;
|
|
if ((_Meta = fgetwc(_File)) == WEOF)
|
|
return (false);
|
|
else
|
|
{ // got one, convert to wchar_t
|
|
_Wchar = (wchar_t)_Meta;
|
|
return (true);
|
|
}
|
|
}
|
|
#ifdef _CRTBLD_NATIVE_WCHAR_T
|
|
template<> inline bool _Fgetc(unsigned short& _Wchar, _Filet *_File)
|
|
{ // get a unsigned short element from a C stream
|
|
wint_t _Meta;
|
|
if ((_Meta = fgetwc(_File)) == WEOF)
|
|
return (false);
|
|
else
|
|
{ // got one, convert to unsigned short
|
|
_Wchar = (unsigned short)_Meta;
|
|
return (true);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
// TEMPLATE FUNCTION _Fputc
|
|
template<class _Elem> inline
|
|
bool _Fputc(_Elem _Ch, _Filet *_File)
|
|
{ // put an element to a C stream
|
|
return (fwrite(&_Ch, sizeof (_Elem), 1, _File) == 1);
|
|
}
|
|
|
|
template<> inline bool _Fputc(char _Byte, _Filet *_File)
|
|
{ // put a char element to a C stream
|
|
return (fputc(_Byte, _File) != EOF);
|
|
}
|
|
|
|
template<> inline bool _Fputc(wchar_t _Wchar, _Filet *_File)
|
|
{ // put a wchar_t element to a C stream
|
|
return (fputwc(_Wchar, _File) != WEOF);
|
|
}
|
|
#ifdef _CRTBLD_NATIVE_WCHAR_T
|
|
template<> inline bool _Fputc(unsigned short _Wchar, _Filet *_File)
|
|
{ // put a unsigned short element to a C stream
|
|
return (fputwc(_Wchar, _File) != WEOF);
|
|
}
|
|
#endif
|
|
|
|
// TEMPLATE FUNCTION _Ungetc
|
|
template<class _Elem> inline
|
|
bool _Ungetc(const _Elem& _Ch, _Filet *_File)
|
|
{ // put back an arbitrary element to a C stream (always fail)
|
|
return (false);
|
|
}
|
|
|
|
template<> inline bool _Ungetc(const char& _Byte, _Filet *_File)
|
|
{ // put back a char element to a C stream
|
|
return (ungetc((unsigned char)_Byte, _File) != EOF);
|
|
}
|
|
|
|
template<> inline bool _Ungetc(const signed char& _Byte, _Filet *_File)
|
|
{ // put back a signed char element to a C stream
|
|
return (ungetc((unsigned char)_Byte, _File) != EOF);
|
|
}
|
|
|
|
template<> inline bool _Ungetc(const unsigned char& _Byte, _Filet *_File)
|
|
{ // put back an unsigned char element to a C stream
|
|
return (ungetc(_Byte, _File) != EOF);
|
|
}
|
|
|
|
template<> inline bool _Ungetc(const wchar_t& _Wchar, _Filet *_File)
|
|
{ // put back a wchar_t element to a C stream
|
|
return (ungetwc(_Wchar, _File) != WEOF);
|
|
}
|
|
#ifdef _CRTBLD_NATIVE_WCHAR_T
|
|
template<> inline bool _Ungetc(const unsigned short& _Wchar, _Filet *_File)
|
|
{ // put back a unsigned short element to a C stream
|
|
return (ungetwc(_Wchar, _File) != WEOF);
|
|
}
|
|
#endif
|
|
|
|
// TEMPLATE CLASS basic_filebuf
|
|
template<class _Elem,
|
|
class _Traits>
|
|
class basic_filebuf
|
|
: public basic_streambuf<_Elem, _Traits>
|
|
{ // stream buffer associated with a C stream
|
|
public:
|
|
typedef basic_filebuf<_Elem, _Traits> _Myt;
|
|
typedef basic_streambuf<_Elem, _Traits> _Mysb;
|
|
typedef codecvt<_Elem, char, typename _Traits::state_type> _Cvt;
|
|
|
|
virtual ~basic_filebuf()
|
|
{ // destroy the object
|
|
if (_Closef)
|
|
close();
|
|
_DELETE_CRT(_Mystr);
|
|
}
|
|
|
|
basic_filebuf(_Filet *_File = 0)
|
|
: _Mysb(), _Mystr(0), _Loc()
|
|
{ // construct from pointer to C stream
|
|
_Init(_File, _Newfl);
|
|
}
|
|
|
|
typedef typename _Traits::int_type int_type;
|
|
typedef typename _Traits::pos_type pos_type;
|
|
typedef typename _Traits::off_type off_type;
|
|
|
|
basic_filebuf(_Uninitialized)
|
|
: _Mysb(_Noinit), _Loc(_Noinit)
|
|
{ // construct uninitialized
|
|
}
|
|
|
|
enum _Initfl
|
|
{ // reasons for a call to _Init
|
|
_Newfl, _Openfl, _Closefl};
|
|
|
|
bool is_open() const
|
|
{ // test if C stream has been opened
|
|
return (_Myfile != 0);
|
|
}
|
|
|
|
_Myt *open(const char *_Filename, ios_base::openmode _Mode)
|
|
{ // open a C stream with specified mode
|
|
_Filet *_File;
|
|
if (_Myfile != 0 || (_File = _Fiopen(_Filename, _Mode)) == 0)
|
|
return (0); // open failed
|
|
|
|
_Init(_File, _Openfl);
|
|
_Initcvt((_Cvt *)&_USE(_Mysb::getloc(), _Cvt));
|
|
return (this); // open succeeded
|
|
}
|
|
|
|
_Myt *open(const char *_Filename, ios_base::open_mode _Mode)
|
|
{ // open a C stream with specified mode (old style)
|
|
return (open(_Filename, (ios_base::openmode)_Mode));
|
|
}
|
|
|
|
_Myt *close()
|
|
{ // close the C stream
|
|
if (_Myfile != 0 && _Endwrite() && fclose(_Myfile) == 0)
|
|
{ // close succeeded, tidy up
|
|
_Init(0, _Closefl);
|
|
return (this);
|
|
}
|
|
else
|
|
return (0);
|
|
}
|
|
|
|
protected:
|
|
virtual int_type overflow(int_type _Meta = _Traits::eof())
|
|
{ // put an element to stream
|
|
if (_Traits::eq_int_type(_Traits::eof(), _Meta))
|
|
return (_Traits::not_eof(_Meta)); // EOF, return success code
|
|
else if (_Mysb::pptr() != 0
|
|
&& _Mysb::pptr() < _Mysb::epptr())
|
|
{ // room in buffer, store it
|
|
*_Mysb::_Pninc() = _Traits::to_char_type(_Meta);
|
|
return (_Meta);
|
|
}
|
|
else if (_Myfile == 0)
|
|
return (_Traits::eof()); // no open C stream, fail
|
|
else if (_Pcvt == 0)
|
|
return (_Fputc(_Traits::to_char_type(_Meta), _Myfile)
|
|
? _Meta : _Traits::eof()); // no codecvt facet, put as is
|
|
else
|
|
{ // put using codecvt facet
|
|
const int _STRING_INC = 8;
|
|
const _Elem _Ch = _Traits::to_char_type(_Meta);
|
|
const _Elem *_Source;
|
|
char *_Dest;
|
|
|
|
_Mystr->erase();
|
|
string _Str(_STRING_INC, '\0');
|
|
for (; ; )
|
|
switch (_Pcvt->out(_State,
|
|
&_Ch, &_Ch + 1, _Source,
|
|
&*_Str.begin(), &*_Str.end(), _Dest))
|
|
{ // test result of converting one element
|
|
case codecvt_base::partial:
|
|
case codecvt_base::ok:
|
|
{ // converted something, try to put it out
|
|
size_t _Count = _Dest - &*_Str.begin();
|
|
if (0 < _Count && _Count !=
|
|
fwrite(&*_Str.begin(), 1, _Count, _Myfile))
|
|
return (_Traits::eof()); // write failed
|
|
|
|
_Wrotesome = true; // write succeeded
|
|
if (_Source != &_Ch)
|
|
return (_Meta); // converted whole element
|
|
if (_Count == 0)
|
|
_Str.append(_STRING_INC, '\0'); // try some more
|
|
break;
|
|
}
|
|
|
|
case codecvt_base::noconv:
|
|
return (_Fputc(_Ch, _Myfile) ? _Meta
|
|
: _Traits::eof()); // no conversion, put as is
|
|
|
|
default:
|
|
return (_Traits::eof()); // conversion failed
|
|
}
|
|
}
|
|
}
|
|
|
|
virtual int_type pbackfail(int_type _Meta = _Traits::eof())
|
|
{ // put an element back to stream
|
|
if (_Mysb::gptr() != 0
|
|
&& _Mysb::eback() < _Mysb::gptr()
|
|
&& (_Traits::eq_int_type(_Traits::eof(), _Meta)
|
|
|| _Traits::eq_int_type(_Traits::to_int_type(_Mysb::gptr()[-1]),
|
|
_Meta)))
|
|
{ // just back up position
|
|
_Mysb::_Gndec();
|
|
return (_Traits::not_eof(_Meta));
|
|
}
|
|
else if (_Myfile == 0 || _Traits::eq_int_type(_Traits::eof(), _Meta))
|
|
return (_Traits::eof()); // no open C stream or EOF, fail
|
|
else if (_Pcvt == 0 && _Ungetc(_Traits::to_char_type(_Meta), _Myfile))
|
|
return (_Meta); // no facet and unget succeeded, return
|
|
else
|
|
{ // putback to _Mychar
|
|
_Mychar = _Traits::to_char_type(_Meta);
|
|
_Mysb::setg(&_Mychar, &_Mychar, &_Mychar + 1);
|
|
return (_Meta);
|
|
}
|
|
}
|
|
|
|
virtual int_type underflow()
|
|
{ // get an element from stream, but don't point past it
|
|
int_type _Meta;
|
|
if (_Mysb::gptr() != 0
|
|
&& _Mysb::gptr() < _Mysb::egptr())
|
|
return (_Traits::to_int_type(*_Mysb::gptr())); // return buffered
|
|
else if (_Traits::eq_int_type(_Traits::eof(), _Meta = uflow()))
|
|
return (_Meta); // uflow failed, return EOF
|
|
else
|
|
{ // get a char, don't point past it
|
|
pbackfail(_Meta);
|
|
return (_Meta);
|
|
}
|
|
}
|
|
|
|
virtual int_type uflow()
|
|
{ // get an element from stream, point past it
|
|
if (_Mysb::gptr() != 0
|
|
&& _Mysb::gptr() < _Mysb::egptr())
|
|
return (_Traits::to_int_type(
|
|
*_Mysb::_Gninc())); // return buffered
|
|
else if (_Myfile == 0)
|
|
return (_Traits::eof()); // no open C stream, fail
|
|
else if (_Pcvt == 0)
|
|
{ // no codecvt facet, just get it
|
|
_Elem _Ch = 0;
|
|
return (_Fgetc(_Ch, _Myfile) ? _Traits::to_int_type(_Ch)
|
|
: _Traits::eof());
|
|
}
|
|
else
|
|
for (_State0 = _State, _Mystr->erase(); ; )
|
|
{ // get using codecvt facet
|
|
_Elem _Ch, *_Dest;
|
|
const char *_Source;
|
|
int _Meta = fgetc(_Myfile);
|
|
|
|
if (_Meta == EOF)
|
|
return (_Traits::eof()); // partial char?
|
|
|
|
_Mystr->append(1, (char)_Meta); // append byte and convert
|
|
_State = _State0;
|
|
switch (_Pcvt->in(_State,
|
|
&*_Mystr->begin(), &*_Mystr->end(), _Source,
|
|
&_Ch, &_Ch + 1, _Dest))
|
|
{ // test result of converting one element
|
|
case codecvt_base::partial:
|
|
break; // partial, not done yet
|
|
|
|
case codecvt_base::noconv:
|
|
if (_Mystr->size() < sizeof (_Elem))
|
|
break; // no conversion, but need more chars
|
|
|
|
memcpy(&_Ch, &*_Mystr->begin(),
|
|
sizeof (_Elem)); // copy raw bytes to element
|
|
|
|
case codecvt_base::ok: // can fall through
|
|
return (_Traits::to_int_type(_Ch)); // return result
|
|
|
|
default:
|
|
return (_Traits::eof()); // conversion failed
|
|
}
|
|
}
|
|
}
|
|
|
|
virtual pos_type seekoff(off_type _Off, ios_base::seekdir _Way,
|
|
ios_base::openmode =
|
|
(ios_base::openmode)(ios_base::in | ios_base::out))
|
|
{ // change position by _Off
|
|
fpos_t _Fileposition;
|
|
|
|
if (_Mysb::gptr() != &_Mychar
|
|
|| _Mysb::egptr() <= _Mysb::gptr()
|
|
|| _Way != ios_base::cur)
|
|
; // don't have to worry about putback character
|
|
else if (_Pcvt == 0)
|
|
_Off -= (off_type)sizeof (_Elem); // back up over _Elem bytes
|
|
else
|
|
{ // back up over converted bytes
|
|
_Off -= (off_type)_Mystr->size();
|
|
_Mystr->erase();
|
|
_State = _State0;
|
|
}
|
|
if (_Myfile == 0 || !_Endwrite()
|
|
|| (_Off != 0 || _Way != ios_base::cur)
|
|
&& fseek(_Myfile, (long)_Off, _Way) != 0
|
|
|| fgetpos(_Myfile, &_Fileposition) != 0)
|
|
return (pos_type(_BADOFF)); // report failure
|
|
if (_Mysb::gptr() == &_Mychar)
|
|
_Mysb::setg(&_Mychar, &_Mychar, &_Mychar); // discard putback
|
|
return (pos_type(_State, _Fileposition)); // return new position
|
|
}
|
|
|
|
virtual pos_type seekpos(pos_type _Pos,
|
|
ios_base::openmode =
|
|
(ios_base::openmode)(ios_base::in | ios_base::out))
|
|
{ // change position to _Pos
|
|
fpos_t _Fileposition = _Pos.seekpos();
|
|
off_type _Off = (off_type)_Pos - _FPOSOFF(_Fileposition);
|
|
|
|
if (_Myfile == 0 || !_Endwrite()
|
|
|| fsetpos(_Myfile, &_Fileposition) != 0
|
|
|| _Off != 0 && fseek(_Myfile, (long)_Off, SEEK_CUR) != 0
|
|
|| fgetpos(_Myfile, &_Fileposition) != 0)
|
|
return (pos_type(_BADOFF)); // report failure
|
|
if (_Mystr != 0)
|
|
_State = _Pos.state(), _Mystr->erase(); // restore state
|
|
if (_Mysb::gptr() == &_Mychar)
|
|
_Mysb::setg(&_Mychar, &_Mychar, &_Mychar); // discard putback
|
|
return (pos_type(_State, _Fileposition)); // return new position
|
|
}
|
|
|
|
virtual _Mysb *setbuf(_Elem *_Buffer, streamsize _Count)
|
|
{ // offer _Buffer to C stream
|
|
return (_Myfile == 0 || setvbuf(_Myfile, (char *)_Buffer,
|
|
_Buffer == 0 && _Count == 0 ? _IONBF : _IOFBF,
|
|
_Count * sizeof (_Elem)) != 0 ? 0 : this);
|
|
}
|
|
|
|
virtual int sync()
|
|
{ // synchronize C stream with external file
|
|
return (_Myfile == 0
|
|
|| _Traits::eq_int_type(_Traits::eof(), overflow())
|
|
|| 0 <= fflush(_Myfile) ? 0 : -1);
|
|
}
|
|
|
|
virtual void imbue(const locale& _Loc)
|
|
{ // set locale to argument (capture nontrivial codecvt facet)
|
|
_Initcvt((_Cvt *)&_USE(_Loc, _Cvt));
|
|
}
|
|
|
|
void _Init(_Filet *_File, _Initfl _Which)
|
|
{ // initialize to C stream _File after {new, open, close}
|
|
static typename _Traits::state_type _Stinit; // initial state
|
|
_Closef = _Which == _Openfl;
|
|
_Wrotesome = false;
|
|
|
|
_Mysb::_Init(); // initialize stream buffer base object
|
|
|
|
#ifndef _IORCNT
|
|
#define _IORCNT _IOCNT /* read and write counts are the same */
|
|
#define _IOWCNT _IOCNT
|
|
#endif
|
|
if (_File != 0 && sizeof (_Elem) == 1)
|
|
{ // point inside C stream with [first, first + count) buffer
|
|
_Elem **_Pb = (_Elem **)&_File->_IOBASE;
|
|
_Elem **_Pn = (_Elem **)&_File->_IOPTR;
|
|
int *_Nr = (int *)&_File->_IORCNT;
|
|
int *_Nw = (int *)&_File->_IOWCNT;
|
|
_Mysb::_Init(_Pb, _Pn, _Nr, _Pb, _Pn, _Nw);
|
|
}
|
|
_Myfile = _File;
|
|
_State = _Stinit;
|
|
_State0 = _Stinit;
|
|
_Pcvt = 0; // pointer to codecvt facet
|
|
}
|
|
|
|
bool _Endwrite()
|
|
{ // put shift to initial conversion state, as needed
|
|
if (_Pcvt == 0 || !_Wrotesome)
|
|
return (true);
|
|
else
|
|
{ // may have to put
|
|
const int _STRING_INC = 8;
|
|
char *_Dest;
|
|
overflow();
|
|
|
|
string _Str(_STRING_INC, '\0');
|
|
for (; ; )
|
|
switch (_Pcvt->unshift(_State,
|
|
&*_Str.begin(), &*_Str.end(), _Dest))
|
|
{ // test result of homing conversion
|
|
case codecvt_base::ok:
|
|
_Wrotesome = false; // homed successfully
|
|
|
|
case codecvt_base::partial: // can fall through
|
|
{ // put any generated bytes
|
|
size_t _Count = _Dest - &*_Str.begin();
|
|
if (0 < _Count && _Count !=
|
|
fwrite(&*_Str.begin(), _Count, 1, _Myfile))
|
|
return (false); // write failed
|
|
if (!_Wrotesome)
|
|
return (true);
|
|
_Str.append(_STRING_INC, '\0'); // try some more
|
|
break;
|
|
}
|
|
|
|
case codecvt_base::noconv:
|
|
return (true); // nothing to do
|
|
|
|
default:
|
|
return (false); // conversion failed
|
|
}
|
|
}
|
|
}
|
|
|
|
void _Initcvt(_Cvt *_Newpcvt)
|
|
{ // initialize codecvt pointer
|
|
if (_Newpcvt->always_noconv())
|
|
_Pcvt = 0; // nothing to do
|
|
else
|
|
{ // set up for nontrivial codecvt facet
|
|
_Pcvt = _Newpcvt;
|
|
_Loc = _ADDFAC(_Loc, _Pcvt); // to keep facet alive
|
|
_Mysb::_Init(); // reset any buffering
|
|
if (_Mystr == 0)
|
|
_Mystr = _NEW_CRT _STRING_CRT; // buy conversion buffer
|
|
}
|
|
}
|
|
|
|
private:
|
|
_Cvt *_Pcvt; // pointer to codecvt facet (may be null)
|
|
typename _Traits::state_type _State0; // rollback for bad conversion
|
|
_Elem _Mychar; // putback character, when _Ungetc fails
|
|
_STRING_CRT *_Mystr; // string to hold partial conversion byte sequences
|
|
bool _Wrotesome; // true if homing sequence may be needed
|
|
typename _Traits::state_type _State; // current conversion state
|
|
bool _Closef; // true if C stream must be closed
|
|
locale _Loc; // locale object to hold codecvt facet
|
|
_Filet *_Myfile; // pointer to C stream
|
|
};
|
|
|
|
|
|
#ifdef _DLL_CPPLIB
|
|
#ifdef __FORCE_INSTANCE
|
|
template class _CRTIMP2 basic_filebuf<char,
|
|
char_traits<char> >;
|
|
template class _CRTIMP2 basic_filebuf<wchar_t,
|
|
char_traits<wchar_t> >;
|
|
#ifdef _CRTBLD_NATIVE_WCHAR_T
|
|
template class _CRTIMP2 basic_filebuf<unsigned short,
|
|
char_traits<unsigned short> >;
|
|
#endif
|
|
#endif // __FORCE_INSTANCE
|
|
#endif // _DLL_CPPLIB
|
|
|
|
// TEMPLATE CLASS basic_ifstream
|
|
template<class _Elem,
|
|
class _Traits>
|
|
class basic_ifstream
|
|
: public basic_istream<_Elem, _Traits>
|
|
{ // input stream associated with a C stream
|
|
public:
|
|
typedef basic_ifstream<_Elem, _Traits> _Myt;
|
|
typedef basic_filebuf<_Elem, _Traits> _Myfb;
|
|
typedef basic_ios<_Elem, _Traits> _Myios;
|
|
|
|
basic_ifstream()
|
|
: basic_istream<_Elem, _Traits>(&_Filebuffer)
|
|
{ // construct unopened
|
|
}
|
|
|
|
explicit basic_ifstream(const char *_Filename,
|
|
ios_base::openmode _Mode = ios_base::in)
|
|
: basic_istream<_Elem, _Traits>(&_Filebuffer)
|
|
{ // construct with named file and specified mode
|
|
if (_Filebuffer.open(_Filename, _Mode | ios_base::in) == 0)
|
|
_Myios::setstate(ios_base::failbit);
|
|
}
|
|
|
|
virtual ~basic_ifstream()
|
|
{ // destroy the object
|
|
}
|
|
|
|
_Myfb *rdbuf() const
|
|
{ // return pointer to file buffer
|
|
return ((_Myfb *)&_Filebuffer);
|
|
}
|
|
|
|
bool is_open() const
|
|
{ // test if C stream has been opened
|
|
return (_Filebuffer.is_open());
|
|
}
|
|
|
|
void open(const char *_Filename,
|
|
ios_base::openmode _Mode = ios_base::in)
|
|
{ // open a C stream with specified mode
|
|
if (_Filebuffer.open(_Filename, _Mode | ios_base::in) == 0)
|
|
_Myios::setstate(ios_base::failbit);
|
|
}
|
|
|
|
void open(const char *_Filename, ios_base::open_mode _Mode)
|
|
{ // open named file with specified mode (old style)
|
|
open(_Filename, (ios_base::openmode)_Mode);
|
|
}
|
|
|
|
void close()
|
|
{ // close the C stream
|
|
if (_Filebuffer.close() == 0)
|
|
_Myios::setstate(ios_base::failbit);
|
|
}
|
|
|
|
private:
|
|
_Myfb _Filebuffer; // the file buffer
|
|
};
|
|
|
|
#ifdef _DLL_CPPLIB
|
|
#ifdef __FORCE_INSTANCE
|
|
template class _CRTIMP2 basic_ifstream<char,
|
|
char_traits<char> >;
|
|
template class _CRTIMP2 basic_ifstream<wchar_t,
|
|
char_traits<wchar_t> >;
|
|
#ifdef _CRTBLD_NATIVE_WCHAR_T
|
|
template class _CRTIMP2 basic_ifstream<unsigned short,
|
|
char_traits<unsigned short> >;
|
|
#endif
|
|
#endif // __FORCE_INSTANCE
|
|
#endif // _DLL_CPPLIB
|
|
|
|
// TEMPLATE CLASS basic_ofstream
|
|
template<class _Elem,
|
|
class _Traits>
|
|
class basic_ofstream
|
|
: public basic_ostream<_Elem, _Traits>
|
|
{ // output stream associated with a C stream
|
|
public:
|
|
typedef basic_ofstream<_Elem, _Traits> _Myt;
|
|
typedef basic_filebuf<_Elem, _Traits> _Myfb;
|
|
typedef basic_ios<_Elem, _Traits> _Myios;
|
|
|
|
basic_ofstream()
|
|
: basic_ostream<_Elem, _Traits>(&_Filebuffer)
|
|
{ // construct unopened
|
|
}
|
|
|
|
explicit basic_ofstream(const char *_Filename,
|
|
ios_base::openmode _Mode = ios_base::out)
|
|
: basic_ostream<_Elem, _Traits>(&_Filebuffer)
|
|
{ // construct with named file and specified mode
|
|
if (_Filebuffer.open(_Filename, _Mode | ios_base::out) == 0)
|
|
_Myios::setstate(ios_base::failbit);
|
|
}
|
|
|
|
virtual ~basic_ofstream()
|
|
{ // destroy the object
|
|
}
|
|
|
|
_Myfb *rdbuf() const
|
|
{ // return pointer to file buffer
|
|
return ((_Myfb *)&_Filebuffer);
|
|
}
|
|
|
|
bool is_open() const
|
|
{ // test if C stream has been opened
|
|
return (_Filebuffer.is_open());
|
|
}
|
|
|
|
void open(const char *_Filename,
|
|
ios_base::openmode _Mode = ios_base::out)
|
|
{ // open a C stream with specified mode
|
|
if (_Filebuffer.open(_Filename, _Mode | ios_base::out) == 0)
|
|
_Myios::setstate(ios_base::failbit);
|
|
}
|
|
|
|
void open(const char *_Filename, ios_base::open_mode _Mode)
|
|
{ // open a C stream with specified mode (old style)
|
|
open(_Filename, (ios_base::openmode)_Mode);
|
|
}
|
|
|
|
void close()
|
|
{ // close the C stream
|
|
if (_Filebuffer.close() == 0)
|
|
_Myios::setstate(ios_base::failbit);
|
|
}
|
|
|
|
private:
|
|
_Myfb _Filebuffer; // the file buffer
|
|
};
|
|
|
|
#ifdef _DLL_CPPLIB
|
|
#ifdef __FORCE_INSTANCE
|
|
template class _CRTIMP2 basic_ofstream<char,
|
|
char_traits<char> >;
|
|
template class _CRTIMP2 basic_ofstream<wchar_t,
|
|
char_traits<wchar_t> >;
|
|
#ifdef _CRTBLD_NATIVE_WCHAR_T
|
|
template class _CRTIMP2 basic_ofstream<unsigned short,
|
|
char_traits<unsigned short> >;
|
|
#endif
|
|
#endif // __FORCE_INSTANCE
|
|
#endif // _DLL_CPPLIB
|
|
|
|
// TEMPLATE CLASS basic_fstream
|
|
template<class _Elem,
|
|
class _Traits>
|
|
class basic_fstream
|
|
: public basic_iostream<_Elem, _Traits>
|
|
{ // input/output stream associated with a C stream
|
|
public:
|
|
typedef basic_ios<_Elem, _Traits> _Myios;
|
|
typedef _Elem char_type;
|
|
typedef _Traits traits_type;
|
|
typedef typename _Traits::int_type int_type;
|
|
typedef typename _Traits::pos_type pos_type;
|
|
typedef typename _Traits::off_type off_type;
|
|
|
|
basic_fstream()
|
|
: basic_iostream<_Elem, _Traits>(&_Filebuffer)
|
|
{ // construct unopened
|
|
}
|
|
|
|
explicit basic_fstream(const char *_Filename,
|
|
ios_base::openmode _Mode = ios_base::in | ios_base::out)
|
|
: basic_iostream<_Elem, _Traits>(&_Filebuffer)
|
|
{ // construct with named file and specified mode
|
|
if (_Filebuffer.open(_Filename, _Mode) == 0)
|
|
_Myios::setstate(ios_base::failbit);
|
|
}
|
|
|
|
virtual ~basic_fstream()
|
|
{ // destroy the object
|
|
}
|
|
|
|
basic_filebuf<_Elem, _Traits> *rdbuf() const
|
|
{ // return pointer to file buffer
|
|
return ((basic_filebuf<_Elem, _Traits> *)&_Filebuffer);
|
|
}
|
|
|
|
bool is_open() const
|
|
{ // test if C stream has been opened
|
|
return (_Filebuffer.is_open());
|
|
}
|
|
|
|
void open(const char *_Filename,
|
|
ios_base::openmode _Mode = ios_base::in | ios_base::out)
|
|
{ // open a C stream with specified mode
|
|
if (_Filebuffer.open(_Filename, _Mode) == 0)
|
|
_Myios::setstate(ios_base::failbit);
|
|
}
|
|
|
|
void open(const char *_Filename, ios_base::open_mode _Mode)
|
|
{ // open a C stream with specified mode (old style)
|
|
open(_Filename, (ios_base::openmode)_Mode);
|
|
}
|
|
|
|
void close()
|
|
{ // close the C stream
|
|
if (_Filebuffer.close() == 0)
|
|
_Myios::setstate(ios_base::failbit);
|
|
}
|
|
|
|
private:
|
|
basic_filebuf<_Elem, _Traits> _Filebuffer; // the file buffer
|
|
};
|
|
|
|
#ifdef _DLL_CPPLIB
|
|
#ifdef __FORCE_INSTANCE
|
|
template class _CRTIMP2 basic_fstream<char,
|
|
char_traits<char> >;
|
|
template class _CRTIMP2 basic_fstream<wchar_t,
|
|
char_traits<wchar_t> >;
|
|
#ifdef _CRTBLD_NATIVE_WCHAR_T
|
|
template class _CRTIMP2 basic_fstream<unsigned short,
|
|
char_traits<unsigned short> >;
|
|
#endif
|
|
#endif // __FORCE_INSTANCE
|
|
#endif // _DLL_CPPLIB
|
|
_STD_END
|
|
|
|
#pragma warning(default: 4127)
|
|
#pragma warning(pop)
|
|
#pragma pack(pop)
|
|
|
|
#endif /* _FSTREAM_ */
|
|
|
|
/*
|
|
* Copyright (c) 1992-2001 by P.J. Plauger. ALL RIGHTS RESERVED.
|
|
* Consult your license regarding permissions and restrictions.
|
|
V3.10:0009 */
|