📄 fstream
字号:
// fstream standard header
#pragma once
#ifndef _FSTREAM_
#define _FSTREAM_
#ifndef RC_INVOKED
#include <istream>
#pragma pack(push,_CRT_PACKING)
#pragma warning(push,3)
_STD_BEGIN
#pragma warning(disable: 4127)
extern _MRTIMP2_NCEEPURE _Filet *__CLRCALL_PURE_OR_CDECL _Fiopen(
const char *,
ios_base::openmode, int);
extern _MRTIMP2_NCEEPURE _Filet *__CLRCALL_PURE_OR_CDECL _Fiopen(
const wchar_t *,
ios_base::openmode, int);
#ifdef _NATIVE_WCHAR_T_DEFINED
extern _MRTIMP2_NCEEPURE _Filet *__CLRCALL_PURE_OR_CDECL _Fiopen(
const unsigned short *,
ios_base::openmode, int);
#endif /* _NATIVE_WCHAR_T_DEFINED */
// 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 = _CSTD fgetwc(_File)) == WEOF)
return (false);
else
{ // got one, convert to wchar_t
_Wchar = (wchar_t)_Meta;
return (true);
}
}
#ifdef _NATIVE_WCHAR_T_DEFINED
template<> inline bool _Fgetc(unsigned short& _Wchar, _Filet *_File)
{ // get an unsigned short element from a C stream
wint_t _Meta;
if ((_Meta = _CSTD fgetwc(_File)) == WEOF)
return (false);
else
{ // got one, convert to unsigned short
_Wchar = (unsigned short)_Meta;
return (true);
}
}
#endif /* _NATIVE_WCHAR_T_DEFINED */
// TEMPLATE FUNCTION _Fputc
template<class _Elem> inline
bool _Fputc(_Elem _Ch, _Filet *_File)
{ // put an element to a C stream
return (fwrite(&_Ch, 1, sizeof (_Elem), _File) == sizeof (_Elem));
}
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 (_CSTD fputwc(_Wchar, _File) != WEOF);
}
#ifdef _NATIVE_WCHAR_T_DEFINED
template<> inline bool _Fputc(unsigned short _Wchar, _Filet *_File)
{ // put an unsigned short element to a C stream
return (_CSTD fputwc(_Wchar, _File) != WEOF);
}
#endif /* _NATIVE_WCHAR_T_DEFINED */
// 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 (_CSTD ungetwc(_Wchar, _File) != WEOF);
}
#ifdef _NATIVE_WCHAR_T_DEFINED
template<> inline bool _Ungetc(const unsigned short& _Wchar, _Filet *_File)
{ // put back an unsigned short element to a C stream
return (_CSTD ungetwc(_Wchar, _File) != WEOF);
}
#endif /* _NATIVE_WCHAR_T_DEFINED */
// 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 typename _Traits::state_type _Myst;
typedef codecvt<_Elem, char, typename _Traits::state_type> _Cvt;
virtual __CLR_OR_THIS_CALL ~basic_filebuf()
{ // destroy the object
if (_Myfile != 0)
_Reset_back(); // revert from _Mychar buffer
if (_Closef)
close();
}
basic_filebuf(_Filet *_File = 0)
: _Mysb()
{ // 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)
{ // construct uninitialized
}
basic_filebuf(_Myt&& _Right)
{ // construct by copying _Right
_Init(_Right._Myfile, _Newfl); // match buffering styles
_Init((_Filet *)0, _Closefl); // then make *this look closed
_Assign_rv(_STD forward<_Myt>(_Right));
}
_Myt& operator=(_Myt&& _Right)
{ // assign from _Right
_Assign_rv(_STD forward<_Myt>(_Right));
return (*this);
}
void _Assign_rv(_Myt&& _Right)
{ // assign by moving _Right
if (this != &_Right)
{ // different, worth moving
close();
this->swap(_Right);
}
}
void swap(_Myt& _Right)
{ // swap with _Right
if (this != &_Right)
{ // different, worth swapping
_Mysb::swap(_Right);
_STD swap(_Pcvt, _Right._Pcvt);
_STD swap(_Mychar, _Right._Mychar);
_STD swap(_Wrotesome, _Right._Wrotesome);
_STD swap(_State, _Right._State);
_STD swap(_Closef, _Right._Closef);
_STD swap(_Myfile, _Right._Myfile);
}
}
void swap(_Myt&& _Right)
{ // swap with _Right
_Assign_rv(_STD forward<_Myt>(_Right));
}
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,
int _Prot = (int)ios_base::_Openprot)
{ // open a C stream with specified mode
_Filet *_File;
if (_Myfile != 0 || (_File = _Fiopen(_Filename, _Mode, _Prot)) == 0)
return (0); // open failed
_Init(_File, _Openfl);
_Initcvt(&_USE(_Mysb::getloc(), _Cvt));
return (this); // open succeeded
}
#if _HAS_CPP0X
_Myt *open(const string& _Str,
ios_base::openmode _Mode,
int _Prot = (int)ios_base::_Openprot)
{ // open a C stream with specified mode
return (open(_Str.c_str(), _Mode, _Prot));
}
#endif /* _HAS_CPP0X */
_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 *open(const wchar_t *_Filename,
ios_base::openmode _Mode,
int _Prot = (int)ios_base::_Openprot)
{ // open a wide-named C stream -- EXTENSION
_Filet *_File;
if (_Myfile != 0 || (_File = _Fiopen(_Filename, _Mode, _Prot)) == 0)
return (0); // open failed
_Init(_File, _Openfl);
_Initcvt(&_USE(_Mysb::getloc(), _Cvt));
return (this); // open succeeded
}
#if _HAS_CPP0X
_Myt *open(const wstring& _Str,
ios_base::openmode _Mode,
int _Prot = (int)ios_base::_Openprot)
{ // open a wide-named C stream -- EXTENSION
return (open(_Str.c_str(), _Mode, _Prot));
}
#endif /* _HAS_CPP0X */
_Myt *open(const wchar_t *_Filename,
ios_base::open_mode _Mode)
{ // open a wide-named C stream (old style) -- EXTENSION
return (open(_Filename, (ios_base::openmode)_Mode));
}
#ifdef _NATIVE_WCHAR_T_DEFINED
_Myt *open(const unsigned short *_Filename,
ios_base::openmode _Mode,
int _Prot = (int)ios_base::_Openprot)
{ // open a wide-named C stream -- EXTENSION
_Filet *_File;
if (_Myfile != 0 || (_File = _Fiopen(_Filename, _Mode, _Prot)) == 0)
return (0); // open failed
_Init(_File, _Openfl);
_Initcvt(&_USE(_Mysb::getloc(), _Cvt));
return (this); // open succeeded
}
_Myt *open(const unsigned short *_Filename,
ios_base::open_mode _Mode)
{ // open a wide-named C stream (old style) -- EXTENSION
return (open(_Filename, (ios_base::openmode)_Mode));
}
#endif /* _NATIVE_WCHAR_T_DEFINED */
_Myt *close()
{ // close the C stream
_Myt *_Ans = this;
if (_Myfile == 0)
_Ans = 0;
else
{ // put any homing sequence and close file
if (!_Endwrite())
_Ans = 0;
if (fclose(_Myfile) != 0)
_Ans = 0;
}
_Init(0, _Closefl);
return (_Ans);
}
virtual void __CLR_OR_THIS_CALL _Lock()
{ // lock file instead of stream buffer
if (_Myfile)
_CSTD _lock_file(_Myfile);
}
virtual void __CLR_OR_THIS_CALL _Unlock()
{ // unlock file instead of stream buffer
if (_Myfile)
_CSTD _unlock_file(_Myfile);
}
protected:
virtual int_type __CLR_OR_THIS_CALL 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
_Reset_back(); // revert from _Mychar buffer
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 *_Src;
char *_Dest;
string _Str(_STRING_INC, '\0');
for (; ; )
switch (_Pcvt->out(_State,
&_Ch, &_Ch + 1, _Src,
&*_Str.begin(), &*_Str.begin() + _Str.size(), _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 (_Src != &_Ch)
return (_Meta); // converted whole element
if (0 < _Count)
;
else if (_Str.size() < 4 * _STRING_INC)
_Str.append(_STRING_INC, '\0'); // try with more space
else
return (_Traits::eof()); // conversion failed
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 __CLR_OR_THIS_CALL 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 if (_Mysb::gptr() != &_Mychar)
{ // putback to _Mychar
_Mychar = _Traits::to_char_type(_Meta);
_Set_back(); // switch to _Mychar buffer
return (_Meta);
}
else
return (_Traits::eof()); // nowhere to put back
}
virtual int_type __CLR_OR_THIS_CALL 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 __CLR_OR_THIS_CALL 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
_Reset_back(); // revert from _Mychar buffer
if (_Pcvt == 0)
{ // no codecvt facet, just get it
_Elem _Ch = 0;
return (_Fgetc(_Ch, _Myfile) ? _Traits::to_int_type(_Ch)
: _Traits::eof());
}
else
{ // build string until codecvt succeeds
string _Str;
for (; ; )
{ // get using codecvt facet
_Elem _Ch, *_Dest;
const char *_Src;
int _Nleft;
int _Meta = fgetc(_Myfile);
if (_Meta == EOF)
return (_Traits::eof()); // partial char?
_Str.append(1, (char)_Meta); // append byte and convert
switch (_Pcvt->in(_State,
&*_Str.begin(), &*_Str.begin() + _Str.size(), _Src,
&_Ch, &_Ch + 1, _Dest))
{ // test result of converting one element
case codecvt_base::partial:
case codecvt_base::ok:
if (_Dest != &_Ch)
{ // got an element, put back excess and deliver it
_Nleft = (int)(&*_Str.begin() + _Str.size() - _Src);
for (; 0 < _Nleft; )
ungetc(_Src[--_Nleft], _Myfile);
return (_Traits::to_int_type(_Ch));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -