1047 lines
26 KiB
Plaintext
1047 lines
26 KiB
Plaintext
|
// istream standard header
|
||
|
#pragma once
|
||
|
#ifndef _ISTREAM_
|
||
|
#define _ISTREAM_
|
||
|
#include <ostream>
|
||
|
|
||
|
#pragma pack(push,8)
|
||
|
#pragma warning(push,3)
|
||
|
_STD_BEGIN
|
||
|
|
||
|
// TEMPLATE CLASS basic_istream
|
||
|
template<class _Elem,
|
||
|
class _Traits>
|
||
|
class basic_istream
|
||
|
: virtual public basic_ios<_Elem, _Traits>
|
||
|
{ // control extractions from a stream buffer
|
||
|
public:
|
||
|
typedef basic_istream<_Elem, _Traits> _Myt;
|
||
|
typedef basic_ios<_Elem, _Traits> _Myios;
|
||
|
typedef basic_streambuf<_Elem, _Traits> _Mysb;
|
||
|
typedef istreambuf_iterator<_Elem, _Traits> _Iter;
|
||
|
typedef ctype<_Elem> _Ctype;
|
||
|
typedef num_get<_Elem, _Iter> _Nget;
|
||
|
|
||
|
explicit basic_istream(_Mysb *_Strbuf, bool _Isstd = false,
|
||
|
bool _Noinit = false)
|
||
|
: _Chcount(0)
|
||
|
{ // construct from stream buffer pointer
|
||
|
if (!_Noinit)
|
||
|
_Myios::init(_Strbuf, _Isstd);
|
||
|
}
|
||
|
|
||
|
basic_istream(_Uninitialized)
|
||
|
{ // construct uninitialized
|
||
|
ios_base::_Addstd();
|
||
|
}
|
||
|
|
||
|
virtual ~basic_istream()
|
||
|
{ // destroy the object
|
||
|
}
|
||
|
|
||
|
typedef typename _Traits::int_type int_type;
|
||
|
typedef typename _Traits::pos_type pos_type;
|
||
|
typedef typename _Traits::off_type off_type;
|
||
|
|
||
|
// TEMPLATE CLASS sentry
|
||
|
class _Sentry_base
|
||
|
{ // stores thread lock and reference to input stream
|
||
|
public:
|
||
|
_Sentry_base(_Myt& _Istr)
|
||
|
: _Myistr(_Istr)
|
||
|
{ // lock the stream buffer, if there
|
||
|
if (_Myistr.rdbuf() != 0)
|
||
|
_Myistr.rdbuf()->_Lock();
|
||
|
}
|
||
|
|
||
|
~_Sentry_base()
|
||
|
{ // destroy after unlocking
|
||
|
if (_Myistr.rdbuf() != 0)
|
||
|
_Myistr.rdbuf()->_Unlock();
|
||
|
}
|
||
|
|
||
|
_Myt& _Myistr; // the input stream, for _Unlock call at destruction
|
||
|
};
|
||
|
|
||
|
class sentry
|
||
|
: public _Sentry_base
|
||
|
{ // stores thread lock and result of _Ipfx call
|
||
|
public:
|
||
|
explicit sentry(_Myt& _Istr, bool _Noskip = false)
|
||
|
: _Sentry_base(_Istr)
|
||
|
{ // construct locking and calling _Ipfx
|
||
|
_Ok = _Myistr._Ipfx(_Noskip);
|
||
|
}
|
||
|
|
||
|
operator bool() const
|
||
|
{ // test if _Ipfx succeeded
|
||
|
return (_Ok);
|
||
|
}
|
||
|
|
||
|
private:
|
||
|
sentry(const sentry&); // not defined
|
||
|
sentry& operator=(const sentry&); // not defined
|
||
|
|
||
|
bool _Ok; // true if _Ipfx succeeded at construction
|
||
|
};
|
||
|
|
||
|
bool _Ipfx(bool _Noskip = false)
|
||
|
{ // test stream state and skip whitespace as needed
|
||
|
if (ios_base::good())
|
||
|
{ // state okay, flush tied stream and skip whitespace
|
||
|
if (_Myios::tie() != 0)
|
||
|
_Myios::tie()->flush();
|
||
|
|
||
|
if (!_Noskip && ios_base::flags() & ios_base::skipws)
|
||
|
{ // skip whitespace
|
||
|
const _Ctype& _Facet = _USE(ios_base::getloc(), _Ctype);
|
||
|
|
||
|
_TRY_IO_BEGIN
|
||
|
int_type _Meta = _Myios::rdbuf()->sgetc();
|
||
|
|
||
|
for (; ; _Meta = _Myios::rdbuf()->snextc())
|
||
|
if (_Traits::eq_int_type(_Traits::eof(), _Meta))
|
||
|
{ // end of file, quit
|
||
|
_Myios::setstate(ios_base::eofbit);
|
||
|
break;
|
||
|
}
|
||
|
else if (!_Facet.is(_Ctype::space,
|
||
|
_Traits::to_char_type(_Meta)))
|
||
|
break; // not whitespace, quit
|
||
|
_CATCH_IO_END
|
||
|
}
|
||
|
|
||
|
if (ios_base::good())
|
||
|
return (true);
|
||
|
}
|
||
|
_Myios::setstate(ios_base::failbit);
|
||
|
return (false);
|
||
|
}
|
||
|
|
||
|
bool ipfx(bool _Noskip = false)
|
||
|
{ // test stream state and skip whitespace as needed (retained)
|
||
|
return _Ipfx(_Noskip);
|
||
|
}
|
||
|
|
||
|
void isfx()
|
||
|
{ // perform any wrapup (retained)
|
||
|
}
|
||
|
|
||
|
_Myt& operator>>(_Myt& (__cdecl *_Pfn)(_Myt&))
|
||
|
{ // call basic_istream manipulator
|
||
|
return ((*_Pfn)(*this));
|
||
|
}
|
||
|
|
||
|
_Myt& operator>>(_Myios& (__cdecl *_Pfn)(_Myios&))
|
||
|
{ // call basic_ios manipulator
|
||
|
(*_Pfn)(*(_Myios *)this);
|
||
|
return (*this);
|
||
|
}
|
||
|
|
||
|
_Myt& operator>>(ios_base& (__cdecl *_Pfn)(ios_base&))
|
||
|
{ // call ios_base manipulator
|
||
|
(*_Pfn)(*(ios_base *)this);
|
||
|
return (*this);
|
||
|
}
|
||
|
|
||
|
_Myt& operator>>(_Bool& _Val)
|
||
|
{ // extract a boolean
|
||
|
ios_base::iostate _State = ios_base::goodbit;
|
||
|
const sentry _Ok(*this);
|
||
|
|
||
|
if (_Ok)
|
||
|
{ // state okay, use facet to extract
|
||
|
const _Nget& _Facet = _USE(ios_base::getloc(), _Nget);
|
||
|
|
||
|
_TRY_IO_BEGIN
|
||
|
_Facet.get(_Iter(_Myios::rdbuf()), _Iter(0),
|
||
|
*this, _State, _Val);
|
||
|
_CATCH_IO_END
|
||
|
}
|
||
|
|
||
|
_Myios::setstate(_State);
|
||
|
return (*this);
|
||
|
}
|
||
|
|
||
|
_Myt& operator>>(short& _Val)
|
||
|
{ // extract a short
|
||
|
ios_base::iostate _State = ios_base::goodbit;
|
||
|
const sentry _Ok(*this);
|
||
|
|
||
|
if (_Ok)
|
||
|
{ // state okay, use facet to extract
|
||
|
long _Tmp = 0;
|
||
|
const _Nget& _Facet = _USE(ios_base::getloc(), _Nget);
|
||
|
|
||
|
_TRY_IO_BEGIN
|
||
|
_Facet.get(_Iter(_Myios::rdbuf()), _Iter(0),
|
||
|
*this, _State, _Tmp);
|
||
|
_CATCH_IO_END
|
||
|
|
||
|
if (_State & ios_base::failbit
|
||
|
|| _Tmp < SHRT_MIN || SHRT_MAX < _Tmp)
|
||
|
_State |= ios_base::failbit;
|
||
|
else
|
||
|
_Val = (short)_Tmp;
|
||
|
}
|
||
|
|
||
|
_Myios::setstate(_State);
|
||
|
return (*this);
|
||
|
}
|
||
|
|
||
|
_Myt& operator>>(unsigned short& _Val)
|
||
|
{ // extract an unsigned short
|
||
|
ios_base::iostate _State = ios_base::goodbit;
|
||
|
const sentry _Ok(*this);
|
||
|
|
||
|
if (_Ok)
|
||
|
{ // state okay, use facet to extract
|
||
|
const _Nget& _Facet = _USE(ios_base::getloc(), _Nget);
|
||
|
|
||
|
_TRY_IO_BEGIN
|
||
|
_Facet.get(_Iter(_Myios::rdbuf()), _Iter(0),
|
||
|
*this, _State, _Val);
|
||
|
_CATCH_IO_END
|
||
|
}
|
||
|
|
||
|
_Myios::setstate(_State);
|
||
|
return (*this);
|
||
|
}
|
||
|
|
||
|
_Myt& operator>>(int& _Val)
|
||
|
{ // extract an int
|
||
|
ios_base::iostate _State = ios_base::goodbit;
|
||
|
const sentry _Ok(*this);
|
||
|
|
||
|
if (_Ok)
|
||
|
{ // state okay, use facet to extract
|
||
|
long _Tmp = 0;
|
||
|
const _Nget& _Facet = _USE(ios_base::getloc(), _Nget);
|
||
|
|
||
|
_TRY_IO_BEGIN
|
||
|
_Facet.get(_Iter(_Myios::rdbuf()), _Iter(0),
|
||
|
*this, _State, _Tmp);
|
||
|
_CATCH_IO_END
|
||
|
|
||
|
if (_State & ios_base::failbit
|
||
|
|| _Tmp < INT_MIN || INT_MAX < _Tmp)
|
||
|
_State |= ios_base::failbit;
|
||
|
else
|
||
|
_Val = _Tmp;
|
||
|
}
|
||
|
|
||
|
_Myios::setstate(_State);
|
||
|
return (*this);
|
||
|
}
|
||
|
|
||
|
_Myt& operator>>(unsigned int& _Val)
|
||
|
{ // extract an unsigned int
|
||
|
ios_base::iostate _State = ios_base::goodbit;
|
||
|
const sentry _Ok(*this);
|
||
|
if (_Ok)
|
||
|
{ // state okay, use facet to extract
|
||
|
const _Nget& _Facet = _USE(ios_base::getloc(), _Nget);
|
||
|
|
||
|
_TRY_IO_BEGIN
|
||
|
_Facet.get(_Iter(_Myios::rdbuf()), _Iter(0),
|
||
|
*this, _State, _Val);
|
||
|
_CATCH_IO_END
|
||
|
}
|
||
|
|
||
|
_Myios::setstate(_State);
|
||
|
return (*this);
|
||
|
}
|
||
|
|
||
|
_Myt& operator>>(long& _Val)
|
||
|
{ // extract a long
|
||
|
ios_base::iostate _State = ios_base::goodbit;
|
||
|
const sentry _Ok(*this);
|
||
|
|
||
|
if (_Ok)
|
||
|
{ // state okay, use facet to extract
|
||
|
const _Nget& _Facet = _USE(ios_base::getloc(), _Nget);
|
||
|
_TRY_IO_BEGIN
|
||
|
_Facet.get(_Iter(_Myios::rdbuf()), _Iter(0),
|
||
|
*this, _State, _Val);
|
||
|
_CATCH_IO_END
|
||
|
}
|
||
|
|
||
|
_Myios::setstate(_State);
|
||
|
return (*this);
|
||
|
}
|
||
|
|
||
|
_Myt& operator>>(unsigned long& _Val)
|
||
|
{ // extract an unsigned long
|
||
|
ios_base::iostate _State = ios_base::goodbit;
|
||
|
const sentry _Ok(*this);
|
||
|
|
||
|
if (_Ok)
|
||
|
{ // state okay, use facet to extract
|
||
|
const _Nget& _Facet = _USE(ios_base::getloc(), _Nget);
|
||
|
|
||
|
_TRY_IO_BEGIN
|
||
|
_Facet.get(_Iter(_Myios::rdbuf()), _Iter(0),
|
||
|
*this, _State, _Val);
|
||
|
_CATCH_IO_END
|
||
|
}
|
||
|
|
||
|
_Myios::setstate(_State);
|
||
|
return (*this);
|
||
|
}
|
||
|
#ifdef _LONGLONG
|
||
|
|
||
|
_Myt& operator>>(_LONGLONG& _Val)
|
||
|
{ // extract a long long
|
||
|
ios_base::iostate _State = ios_base::goodbit;
|
||
|
const sentry _Ok(*this);
|
||
|
|
||
|
if (_Ok)
|
||
|
{ // state okay, use facet to extract
|
||
|
const _Nget& _Facet = _USE(ios_base::getloc(), _Nget);
|
||
|
|
||
|
_TRY_IO_BEGIN
|
||
|
_Facet.get(_Iter(_Myios::rdbuf()), _Iter(0),
|
||
|
*this, _State, _Val);
|
||
|
_CATCH_IO_END
|
||
|
}
|
||
|
|
||
|
_Myios::setstate(_State);
|
||
|
return (*this);
|
||
|
}
|
||
|
|
||
|
_Myt& operator>>(_ULONGLONG& _Val)
|
||
|
{ // extract an unsigned long long
|
||
|
ios_base::iostate _State = ios_base::goodbit;
|
||
|
const sentry _Ok(*this);
|
||
|
if (_Ok)
|
||
|
{ // state okay, use facet to extract
|
||
|
const _Nget& _Facet = _USE(ios_base::getloc(), _Nget);
|
||
|
|
||
|
_TRY_IO_BEGIN
|
||
|
_Facet.get(_Iter(_Myios::rdbuf()), _Iter(0),
|
||
|
*this, _State, _Val);
|
||
|
_CATCH_IO_END
|
||
|
}
|
||
|
|
||
|
_Myios::setstate(_State);
|
||
|
return (*this);
|
||
|
}
|
||
|
#endif /* _LONGLONG */
|
||
|
|
||
|
_Myt& operator>>(float& _Val)
|
||
|
{ // extract a float
|
||
|
ios_base::iostate _State = ios_base::goodbit;
|
||
|
const sentry _Ok(*this);
|
||
|
|
||
|
if (_Ok)
|
||
|
{ // state okay, use facet to extract
|
||
|
const _Nget& _Facet = _USE(ios_base::getloc(), _Nget);
|
||
|
|
||
|
_TRY_IO_BEGIN
|
||
|
_Facet.get(_Iter(_Myios::rdbuf()), _Iter(0),
|
||
|
*this, _State, _Val);
|
||
|
_CATCH_IO_END
|
||
|
}
|
||
|
|
||
|
_Myios::setstate(_State);
|
||
|
return (*this);
|
||
|
}
|
||
|
|
||
|
_Myt& operator>>(double& _Val)
|
||
|
{ // extract a double
|
||
|
ios_base::iostate _State = ios_base::goodbit;
|
||
|
const sentry _Ok(*this);
|
||
|
if (_Ok)
|
||
|
{ // state okay, use facet to extract
|
||
|
const _Nget& _Facet = _USE(ios_base::getloc(), _Nget);
|
||
|
|
||
|
_TRY_IO_BEGIN
|
||
|
_Facet.get(_Iter(_Myios::rdbuf()), _Iter(0),
|
||
|
*this, _State, _Val);
|
||
|
_CATCH_IO_END
|
||
|
}
|
||
|
|
||
|
_Myios::setstate(_State);
|
||
|
return (*this);
|
||
|
}
|
||
|
|
||
|
_Myt& operator>>(long double& _Val)
|
||
|
{ // extract a long double
|
||
|
ios_base::iostate _State = ios_base::goodbit;
|
||
|
const sentry _Ok(*this);
|
||
|
|
||
|
if (_Ok)
|
||
|
{ // state okay, use facet to extract
|
||
|
const _Nget& _Facet = _USE(ios_base::getloc(), _Nget);
|
||
|
_TRY_IO_BEGIN
|
||
|
_Facet.get(_Iter(_Myios::rdbuf()), _Iter(0),
|
||
|
*this, _State, _Val);
|
||
|
_CATCH_IO_END
|
||
|
}
|
||
|
|
||
|
_Myios::setstate(_State);
|
||
|
return (*this);
|
||
|
}
|
||
|
|
||
|
_Myt& operator>>(void *& _Val)
|
||
|
{ // extract a void pointer
|
||
|
ios_base::iostate _State = ios_base::goodbit;
|
||
|
const sentry _Ok(*this);
|
||
|
|
||
|
if (_Ok)
|
||
|
{ // state okay, use facet to extract
|
||
|
const _Nget& _Facet = _USE(ios_base::getloc(), _Nget);
|
||
|
|
||
|
_TRY_IO_BEGIN
|
||
|
_Facet.get(_Iter(_Myios::rdbuf()), _Iter(0),
|
||
|
*this, _State, _Val);
|
||
|
_CATCH_IO_END
|
||
|
}
|
||
|
|
||
|
_Myios::setstate(_State);
|
||
|
return (*this);
|
||
|
}
|
||
|
|
||
|
_Myt& operator>>(_Mysb *_Strbuf)
|
||
|
{ // extract until end-of-file into a stream buffer
|
||
|
ios_base::iostate _State = ios_base::goodbit;
|
||
|
bool _Copied = false;
|
||
|
const sentry _Ok(*this);
|
||
|
|
||
|
if (_Ok && _Strbuf != 0)
|
||
|
{ // state okay, extract characters
|
||
|
_TRY_IO_BEGIN
|
||
|
int_type _Meta = _Myios::rdbuf()->sgetc();
|
||
|
|
||
|
for (; ; _Meta = _Myios::rdbuf()->snextc())
|
||
|
if (_Traits::eq_int_type(_Traits::eof(), _Meta))
|
||
|
{ // end of file, quit
|
||
|
_State |= ios_base::eofbit;
|
||
|
break;
|
||
|
}
|
||
|
else
|
||
|
{ // got a character, insert it into buffer
|
||
|
_TRY_BEGIN
|
||
|
if (_Traits::eq_int_type(_Traits::eof(),
|
||
|
_Strbuf->sputc(_Traits::to_char_type(_Meta))))
|
||
|
break;
|
||
|
_CATCH_ALL
|
||
|
break;
|
||
|
_CATCH_END
|
||
|
_Copied = true;
|
||
|
}
|
||
|
_CATCH_IO_END
|
||
|
}
|
||
|
|
||
|
_Myios::setstate(!_Copied ? _State | ios_base::failbit : _State);
|
||
|
return (*this);
|
||
|
}
|
||
|
|
||
|
int_type get()
|
||
|
{ // extract a metacharacter
|
||
|
int_type _Meta = 0;
|
||
|
ios_base::iostate _State = ios_base::goodbit;
|
||
|
_Chcount = 0;
|
||
|
const sentry _Ok(*this, true);
|
||
|
|
||
|
if (!_Ok)
|
||
|
_Meta = _Traits::eof(); // state not okay, return EOF
|
||
|
else
|
||
|
{ // state okay, extract a character
|
||
|
_TRY_IO_BEGIN
|
||
|
_Meta = _Myios::rdbuf()->sbumpc();
|
||
|
|
||
|
if (_Traits::eq_int_type(_Traits::eof(), _Meta))
|
||
|
_State |= ios_base::eofbit | ios_base::failbit; // end of file
|
||
|
else
|
||
|
++_Chcount; // got a character, count it
|
||
|
_CATCH_IO_END
|
||
|
}
|
||
|
|
||
|
_Myios::setstate(_State);
|
||
|
return (_Meta);
|
||
|
}
|
||
|
|
||
|
_Myt& get(_Elem *_Str, streamsize _Count)
|
||
|
{ // get up to _Count characters into NTCS
|
||
|
return (get(_Str, _Count, _Myios::widen('\n')));
|
||
|
}
|
||
|
|
||
|
_Myt& get(_Elem *_Str, streamsize _Count, _Elem _Delim)
|
||
|
{ // get up to _Count characters into NTCS, stop before _Delim
|
||
|
ios_base::iostate _State = ios_base::goodbit;
|
||
|
_Chcount = 0;
|
||
|
const sentry _Ok(*this, true);
|
||
|
|
||
|
if (_Ok && 0 < _Count)
|
||
|
{ // state okay, extract characters
|
||
|
_TRY_IO_BEGIN
|
||
|
int_type _Meta = _Myios::rdbuf()->sgetc();
|
||
|
|
||
|
for (; 0 < --_Count; _Meta = _Myios::rdbuf()->snextc())
|
||
|
if (_Traits::eq_int_type(_Traits::eof(), _Meta))
|
||
|
{ // end of file, quit
|
||
|
_State |= ios_base::eofbit;
|
||
|
break;
|
||
|
}
|
||
|
else if (_Traits::to_char_type(_Meta) == _Delim)
|
||
|
break; // got a delimiter, quit
|
||
|
else
|
||
|
{ // got a character, add it to string
|
||
|
*_Str++ = _Traits::to_char_type(_Meta);
|
||
|
++_Chcount;
|
||
|
}
|
||
|
_CATCH_IO_END
|
||
|
}
|
||
|
|
||
|
_Myios::setstate(_Chcount == 0
|
||
|
? _State | ios_base::failbit : _State);
|
||
|
*_Str = _Elem(); // add terminating null character
|
||
|
return (*this);
|
||
|
}
|
||
|
|
||
|
_Myt& get(_Elem& _Ch)
|
||
|
{ // get a character
|
||
|
int_type _Meta = get();
|
||
|
if (!_Traits::eq_int_type(_Traits::eof(), _Meta))
|
||
|
_Ch = _Traits::to_char_type(_Meta);
|
||
|
return (*this);
|
||
|
}
|
||
|
|
||
|
_Myt& get(_Mysb& _Strbuf)
|
||
|
{ // extract up to newline and insert into stream buffer
|
||
|
return (get(_Strbuf, _Myios::widen('\n')));
|
||
|
}
|
||
|
|
||
|
_Myt& get(_Mysb& _Strbuf, _Elem _Delim)
|
||
|
{ // extract up to delimiter and insert into stream buffer
|
||
|
ios_base::iostate _State = ios_base::goodbit;
|
||
|
_Chcount = 0;
|
||
|
const sentry _Ok(*this, true);
|
||
|
|
||
|
if (_Ok)
|
||
|
{ // state okay, use facet to extract
|
||
|
_TRY_IO_BEGIN
|
||
|
int_type _Meta = _Myios::rdbuf()->sgetc();
|
||
|
|
||
|
for (; ; _Meta = _Myios::rdbuf()->snextc())
|
||
|
if (_Traits::eq_int_type(_Traits::eof(), _Meta))
|
||
|
{ // end of file, quit
|
||
|
_State |= ios_base::eofbit;
|
||
|
break;
|
||
|
}
|
||
|
else
|
||
|
{ // got a character, insert it into stream buffer
|
||
|
_TRY_BEGIN
|
||
|
_Elem _Ch = _Traits::to_char_type(_Meta);
|
||
|
if (_Ch == _Delim
|
||
|
|| _Traits::eq_int_type(_Traits::eof(),
|
||
|
_Strbuf.sputc(_Ch)))
|
||
|
break;
|
||
|
_CATCH_ALL
|
||
|
break;
|
||
|
_CATCH_END
|
||
|
++_Chcount;
|
||
|
}
|
||
|
_CATCH_IO_END
|
||
|
}
|
||
|
|
||
|
if (_Chcount == 0)
|
||
|
_State |= ios_base::failbit;
|
||
|
_Myios::setstate(_State);
|
||
|
return (*this);
|
||
|
}
|
||
|
|
||
|
_Myt& getline(_Elem *_Str, streamsize _Count)
|
||
|
{ // get up to _Count characters into NTCS, discard newline
|
||
|
return (getline(_Str, _Count, _Myios::widen('\n')));
|
||
|
}
|
||
|
|
||
|
_Myt& getline(_Elem *_Str, streamsize _Count, _Elem _Delim)
|
||
|
{ // get up to _Count characters into NTCS, discard _Delim
|
||
|
ios_base::iostate _State = ios_base::goodbit;
|
||
|
_Chcount = 0;
|
||
|
const sentry _Ok(*this, true);
|
||
|
|
||
|
if (_Ok && 0 < _Count)
|
||
|
{ // state okay, use facet to extract
|
||
|
int_type _Metadelim = _Traits::to_int_type(_Delim);
|
||
|
|
||
|
_TRY_IO_BEGIN
|
||
|
int_type _Meta = _Myios::rdbuf()->sgetc();
|
||
|
|
||
|
for (; ; _Meta = _Myios::rdbuf()->snextc())
|
||
|
if (_Traits::eq_int_type(_Traits::eof(), _Meta))
|
||
|
{ // end of file, quit
|
||
|
_State |= ios_base::eofbit;
|
||
|
break;
|
||
|
}
|
||
|
else if (_Meta == _Metadelim)
|
||
|
{ // got a delimiter, discard it and quit
|
||
|
++_Chcount;
|
||
|
_Myios::rdbuf()->sbumpc();
|
||
|
break;
|
||
|
}
|
||
|
else if (--_Count <= 0)
|
||
|
{ // buffer full, quit
|
||
|
_State |= ios_base::failbit;
|
||
|
break;
|
||
|
}
|
||
|
else
|
||
|
{ // got a character, add it to string
|
||
|
++_Chcount;
|
||
|
*_Str++ = _Traits::to_char_type(_Meta);
|
||
|
}
|
||
|
_CATCH_IO_END
|
||
|
}
|
||
|
|
||
|
*_Str = _Elem(); // add terminating null character
|
||
|
_Myios::setstate(_Chcount == 0 ? _State | ios_base::failbit : _State);
|
||
|
return (*this);
|
||
|
}
|
||
|
|
||
|
_Myt& ignore(streamsize _Count = 1, int_type _Metadelim = _Traits::eof())
|
||
|
{ // ignore up to _Count characters, discarding delimiter
|
||
|
ios_base::iostate _State = ios_base::goodbit;
|
||
|
_Chcount = 0;
|
||
|
const sentry _Ok(*this, true);
|
||
|
|
||
|
if (_Ok && 0 < _Count)
|
||
|
{ // state okay, use facet to extract
|
||
|
_TRY_IO_BEGIN
|
||
|
for (; ; )
|
||
|
{ // get a metacharacter if more room in buffer
|
||
|
int_type _Meta;
|
||
|
if (_Count != INT_MAX && --_Count < 0)
|
||
|
break; // buffer full, quit
|
||
|
else if (_Traits::eq_int_type(_Traits::eof(),
|
||
|
_Meta = _Myios::rdbuf()->sbumpc()))
|
||
|
{ // end of file, quit
|
||
|
_State |= ios_base::eofbit;
|
||
|
break;
|
||
|
}
|
||
|
else
|
||
|
{ // got a character, count it
|
||
|
++_Chcount;
|
||
|
if (_Meta == _Metadelim)
|
||
|
break; // got a delimiter, quit
|
||
|
}
|
||
|
}
|
||
|
_CATCH_IO_END
|
||
|
}
|
||
|
|
||
|
_Myios::setstate(_State);
|
||
|
return (*this);
|
||
|
}
|
||
|
|
||
|
_Myt& read(_Elem *_Str, streamsize _Count)
|
||
|
{ // read up to _Count characters into buffer
|
||
|
ios_base::iostate _State = ios_base::goodbit;
|
||
|
_Chcount = 0;
|
||
|
const sentry _Ok(*this, true);
|
||
|
|
||
|
if (_Ok)
|
||
|
{ // state okay, use facet to extract
|
||
|
_TRY_IO_BEGIN
|
||
|
const streamsize _Num = _Myios::rdbuf()->sgetn(_Str, _Count);
|
||
|
_Chcount += _Num;
|
||
|
if (_Num != _Count)
|
||
|
_State |= ios_base::eofbit | ios_base::failbit; // short read
|
||
|
_CATCH_IO_END
|
||
|
}
|
||
|
|
||
|
_Myios::setstate(_State);
|
||
|
return (*this);
|
||
|
}
|
||
|
|
||
|
streamsize readsome(_Elem *_Str, streamsize _Count)
|
||
|
{ // read up to _Count characters into buffer, without blocking
|
||
|
ios_base::iostate _State = ios_base::goodbit;
|
||
|
_Chcount = 0;
|
||
|
const sentry _Ok(*this, true);
|
||
|
streamsize _Num;
|
||
|
|
||
|
if (!_Ok)
|
||
|
_State |= ios_base::failbit; // no buffer, fail
|
||
|
else if ((_Num = _Myios::rdbuf()->in_avail()) < 0)
|
||
|
_State |= ios_base::eofbit; // no characters available
|
||
|
else if (0 < _Num)
|
||
|
read(_Str, _Num < _Count ? _Num : _Count); // read available
|
||
|
|
||
|
_Myios::setstate(_State);
|
||
|
return (gcount());
|
||
|
}
|
||
|
|
||
|
int_type peek()
|
||
|
{ // return next character, unconsumed
|
||
|
ios_base::iostate _State = ios_base::goodbit;
|
||
|
_Chcount = 0;
|
||
|
int_type _Meta = 0;
|
||
|
const sentry _Ok(*this, true);
|
||
|
|
||
|
if (!_Ok)
|
||
|
_Meta = _Traits::eof(); // state not okay, return EOF
|
||
|
else
|
||
|
{ // state okay, read a character
|
||
|
_TRY_IO_BEGIN
|
||
|
if (_Traits::eq_int_type(_Traits::eof(),
|
||
|
_Meta = _Myios::rdbuf()->sgetc()))
|
||
|
_State |= ios_base::eofbit;
|
||
|
_CATCH_IO_END
|
||
|
}
|
||
|
|
||
|
_Myios::setstate(_State);
|
||
|
return (_Meta);
|
||
|
}
|
||
|
|
||
|
_Myt& putback(_Elem _Ch)
|
||
|
{ // put back a character
|
||
|
ios_base::iostate _State = ios_base::goodbit;
|
||
|
_Chcount = 0;
|
||
|
const sentry _Ok(*this, true);
|
||
|
|
||
|
if (_Ok)
|
||
|
{ // state okay, put character back
|
||
|
_TRY_IO_BEGIN
|
||
|
if (_Traits::eq_int_type(_Traits::eof(),
|
||
|
_Myios::rdbuf()->sputbackc(_Ch)))
|
||
|
_State |= ios_base::badbit;
|
||
|
_CATCH_IO_END
|
||
|
}
|
||
|
|
||
|
_Myios::setstate(_State);
|
||
|
return (*this);
|
||
|
}
|
||
|
|
||
|
_Myt& unget()
|
||
|
{ // put back last read character
|
||
|
ios_base::iostate _State = ios_base::goodbit;
|
||
|
_Chcount = 0;
|
||
|
const sentry _Ok(*this, true);
|
||
|
|
||
|
if (_Ok)
|
||
|
{ // state okay, use facet to extract
|
||
|
_TRY_IO_BEGIN
|
||
|
if (_Traits::eq_int_type(_Traits::eof(),
|
||
|
_Myios::rdbuf()->sungetc()))
|
||
|
_State |= ios_base::badbit;
|
||
|
_CATCH_IO_END
|
||
|
}
|
||
|
|
||
|
_Myios::setstate(_State);
|
||
|
return (*this);
|
||
|
}
|
||
|
|
||
|
streamsize gcount() const
|
||
|
{ // get count from last extraction
|
||
|
return (_Chcount);
|
||
|
}
|
||
|
|
||
|
int sync()
|
||
|
{ // synchronize with input source
|
||
|
ios_base::iostate _State = ios_base::goodbit;
|
||
|
int _Ans;
|
||
|
|
||
|
if (_Myios::rdbuf() == 0)
|
||
|
_Ans = -1; // no buffer, fail
|
||
|
else if (_Myios::rdbuf()->pubsync() == -1)
|
||
|
{ // stream buffer sync failed, fail
|
||
|
_State |= ios_base::badbit;
|
||
|
_Ans = -1;
|
||
|
}
|
||
|
else
|
||
|
_Ans = 0; // success
|
||
|
|
||
|
_Myios::setstate(_State);
|
||
|
return (_Ans);
|
||
|
}
|
||
|
|
||
|
_Myt& seekg(pos_type _Pos)
|
||
|
{ // set input stream position to _Pos
|
||
|
if (!ios_base::fail()
|
||
|
&& (off_type)_Myios::rdbuf()->pubseekpos(_Pos,
|
||
|
ios_base::in) == _BADOFF)
|
||
|
_Myios::setstate(ios_base::failbit);
|
||
|
return (*this);
|
||
|
}
|
||
|
|
||
|
_Myt& seekg(off_type _Off, ios_base::seekdir _Way)
|
||
|
{ // change input stream position by _Off, according to _Way
|
||
|
if (!ios_base::fail()
|
||
|
&& (off_type)_Myios::rdbuf()->pubseekoff(_Off, _Way,
|
||
|
ios_base::in) == _BADOFF)
|
||
|
_Myios::setstate(ios_base::failbit);
|
||
|
return (*this);
|
||
|
}
|
||
|
|
||
|
pos_type tellg()
|
||
|
{ // return input stream position
|
||
|
if (!ios_base::fail())
|
||
|
return (_Myios::rdbuf()->pubseekoff(0,
|
||
|
ios_base::cur, ios_base::in));
|
||
|
else
|
||
|
return (pos_type(_BADOFF));
|
||
|
}
|
||
|
|
||
|
private:
|
||
|
streamsize _Chcount; // the character count
|
||
|
};
|
||
|
|
||
|
#ifdef _DLL_CPPLIB
|
||
|
template class _CRTIMP2 basic_istream<char, char_traits<char> >;
|
||
|
template class _CRTIMP2 basic_istream<wchar_t, char_traits<wchar_t> >;
|
||
|
#endif // _DLL_CPPLIB
|
||
|
|
||
|
// TEMPLATE CLASS basic_iostream
|
||
|
template<class _Elem,
|
||
|
class _Traits>
|
||
|
class basic_iostream
|
||
|
: public basic_istream<_Elem, _Traits>,
|
||
|
public basic_ostream<_Elem, _Traits>
|
||
|
{ // control insertions and extractions from a stream buffer
|
||
|
public:
|
||
|
explicit basic_iostream(basic_streambuf<_Elem, _Traits> *_Strbuf)
|
||
|
: basic_istream<_Elem, _Traits>(_Strbuf, false, true),
|
||
|
basic_ostream<_Elem, _Traits>(_Strbuf)
|
||
|
{ // construct from stream buffer pointer
|
||
|
}
|
||
|
|
||
|
virtual ~basic_iostream()
|
||
|
{ // destroy the object
|
||
|
}
|
||
|
};
|
||
|
|
||
|
#ifdef _DLL_CPPLIB
|
||
|
template class _CRTIMP2 basic_iostream<char, char_traits<char> >;
|
||
|
template class _CRTIMP2 basic_iostream<wchar_t, char_traits<wchar_t> >;
|
||
|
#endif // _DLL_CPPLIB
|
||
|
|
||
|
// EXTRACTORS
|
||
|
template<class _Elem,
|
||
|
class _Traits> inline
|
||
|
basic_istream<_Elem, _Traits>& __cdecl operator>>(
|
||
|
basic_istream<_Elem, _Traits>& _Istr, _Elem *_Str)
|
||
|
{ // extract NTBS
|
||
|
typedef basic_istream<_Elem, _Traits> _Myis;
|
||
|
typedef ctype<_Elem> _Ctype;
|
||
|
ios_base::iostate _State = ios_base::goodbit;
|
||
|
_Elem *_Str0 = _Str;
|
||
|
const typename _Myis::sentry _Ok(_Istr);
|
||
|
|
||
|
if (_Ok)
|
||
|
{ // state okay, extract characters
|
||
|
const _Ctype& _Facet = _USE(_Istr.getloc(), _Ctype);
|
||
|
|
||
|
_TRY_IO_BEGIN
|
||
|
streamsize _Count = 0 < _Istr.width() ? _Istr.width() : INT_MAX;
|
||
|
typename _Myis::int_type _Meta = _Istr.rdbuf()->sgetc();
|
||
|
_Elem _Ch;
|
||
|
for (; 0 < --_Count; _Meta = _Istr.rdbuf()->snextc())
|
||
|
if (_Traits::eq_int_type(_Traits::eof(), _Meta))
|
||
|
{ // end of file, quit
|
||
|
_State |= ios_base::eofbit;
|
||
|
break;
|
||
|
}
|
||
|
else if (_Facet.is(_Ctype::space,
|
||
|
_Ch = _Traits::to_char_type(_Meta))
|
||
|
|| _Ch == _Elem())
|
||
|
break; // whitespace or nul, quit
|
||
|
else
|
||
|
*_Str++ = _Traits::to_char_type(_Meta); // add it to string
|
||
|
_CATCH_IO_(_Istr)
|
||
|
}
|
||
|
|
||
|
*_Str = _Elem(); // add terminating null character
|
||
|
_Istr.width(0);
|
||
|
_Istr.setstate(_Str == _Str0 ? _State | ios_base::failbit : _State);
|
||
|
return (_Istr);
|
||
|
}
|
||
|
|
||
|
template<class _Elem,
|
||
|
class _Traits> inline
|
||
|
basic_istream<_Elem, _Traits>& __cdecl operator>>(
|
||
|
basic_istream<_Elem, _Traits>& _Istr, _Elem& _Ch)
|
||
|
{ // extract a character
|
||
|
typedef basic_istream<_Elem, _Traits> _Myis;
|
||
|
typename _Myis::int_type _Meta;
|
||
|
ios_base::iostate _State = ios_base::goodbit;
|
||
|
const typename _Myis::sentry _Ok(_Istr);
|
||
|
|
||
|
if (_Ok)
|
||
|
{ // state okay, extract characters
|
||
|
_TRY_IO_BEGIN
|
||
|
_Meta = _Istr.rdbuf()->sbumpc();
|
||
|
if (_Traits::eq_int_type(_Traits::eof(), _Meta))
|
||
|
_State |= ios_base::eofbit | ios_base::failbit; // end of file
|
||
|
else
|
||
|
_Ch = _Traits::to_char_type(_Meta); // got a character
|
||
|
_CATCH_IO_(_Istr)
|
||
|
}
|
||
|
|
||
|
_Istr.setstate(_State);
|
||
|
return (_Istr);
|
||
|
}
|
||
|
|
||
|
|
||
|
template<class _Elem,
|
||
|
class _Traits> inline
|
||
|
basic_istream<_Elem, _Traits>& __cdecl operator>>(
|
||
|
basic_istream<_Elem, _Traits>& _Istr, signed char *_Str)
|
||
|
{ // extract a signed char NTBS
|
||
|
return (_Istr >> (char *)_Str);
|
||
|
}
|
||
|
|
||
|
template<class _Elem,
|
||
|
class _Traits> inline
|
||
|
basic_istream<_Elem, _Traits>& __cdecl operator>>(
|
||
|
basic_istream<_Elem, _Traits>& _Istr, signed char& _Ch)
|
||
|
{ // extract a signed char
|
||
|
return (_Istr >> (char&)_Ch);
|
||
|
}
|
||
|
|
||
|
template<class _Elem,
|
||
|
class _Traits> inline
|
||
|
basic_istream<_Elem, _Traits>& __cdecl operator>>(
|
||
|
basic_istream<_Elem, _Traits>& _Istr, unsigned char *_Str)
|
||
|
{ // extract an unsigned char NTBS
|
||
|
return (_Istr >> (char *)_Str);
|
||
|
}
|
||
|
|
||
|
template<class _Elem,
|
||
|
class _Traits> inline
|
||
|
basic_istream<_Elem, _Traits>& __cdecl operator>>(
|
||
|
basic_istream<_Elem, _Traits>& _Istr, unsigned char& _Ch)
|
||
|
{ // extract an unsigned char
|
||
|
return (_Istr >> (char&)_Ch);
|
||
|
}
|
||
|
|
||
|
template<class _Elem,
|
||
|
class _Traits> inline
|
||
|
basic_istream<_Elem, _Traits>& __cdecl operator>>(
|
||
|
basic_istream<_Elem, _Traits>& _Istr, signed short * _Str)
|
||
|
{ // extract a wide character NTBS
|
||
|
return (_Istr >> (wchar_t *)_Str);
|
||
|
}
|
||
|
|
||
|
#ifdef _DLL_CPPLIB
|
||
|
template _CRTIMP2 basic_istream<char, char_traits<char> >& __cdecl
|
||
|
operator>>(basic_istream<char, char_traits<char> >&, char *);
|
||
|
template _CRTIMP2 basic_istream<char, char_traits<char> >& __cdecl
|
||
|
operator>>(basic_istream<char, char_traits<char> >&, char&);
|
||
|
template _CRTIMP2 basic_istream<char, char_traits<char> >& __cdecl
|
||
|
operator>>(basic_istream<char, char_traits<char> >&, signed char *);
|
||
|
template _CRTIMP2 basic_istream<char, char_traits<char> >& __cdecl
|
||
|
operator>>(basic_istream<char, char_traits<char> >&, signed char&);
|
||
|
template _CRTIMP2 basic_istream<char, char_traits<char> >& __cdecl
|
||
|
operator>>(basic_istream<char, char_traits<char> >&, unsigned char *);
|
||
|
template _CRTIMP2 basic_istream<char, char_traits<char> >& __cdecl
|
||
|
operator>>(basic_istream<char, char_traits<char> >&, unsigned char&);
|
||
|
template _CRTIMP2 basic_istream<wchar_t, char_traits<wchar_t> >& __cdecl
|
||
|
operator>>(basic_istream<wchar_t, char_traits<wchar_t> >&, wchar_t *);
|
||
|
template _CRTIMP2 basic_istream<wchar_t, char_traits<wchar_t> >& __cdecl
|
||
|
operator>>(basic_istream<wchar_t, char_traits<wchar_t> >&, wchar_t&);
|
||
|
#endif // _DLL_CPPLIB
|
||
|
|
||
|
// MANIPULATORS
|
||
|
template<class _Elem,
|
||
|
class _Traits> inline
|
||
|
basic_istream<_Elem, _Traits>&
|
||
|
__cdecl ws(basic_istream<_Elem, _Traits>& _Istr)
|
||
|
{ // consume whitespace
|
||
|
typedef basic_istream<_Elem, _Traits> _Myis;
|
||
|
typedef ctype<_Elem> _Ctype;
|
||
|
ios_base::iostate _State = ios_base::goodbit;
|
||
|
const typename _Myis::sentry _Ok(_Istr, true);
|
||
|
|
||
|
if (_Ok)
|
||
|
{ // state okay, extract characters
|
||
|
const _Ctype& _Facet = _USE(_Istr.getloc(), _Ctype);
|
||
|
|
||
|
_TRY_IO_BEGIN
|
||
|
for (typename _Traits::int_type _Meta = _Istr.rdbuf()->sgetc(); ;
|
||
|
_Meta = _Istr.rdbuf()->snextc())
|
||
|
if (_Traits::eq_int_type(_Traits::eof(), _Meta))
|
||
|
{ // end of file, quit
|
||
|
_State |= ios_base::eofbit;
|
||
|
break;
|
||
|
}
|
||
|
else if (!_Facet.is(_Ctype::space,
|
||
|
_Traits::to_char_type(_Meta)))
|
||
|
break; // not whitespace, quit
|
||
|
_CATCH_IO_(_Istr)
|
||
|
}
|
||
|
|
||
|
_Istr.setstate(_State);
|
||
|
return (_Istr);
|
||
|
}
|
||
|
|
||
|
_CRTIMP2 inline basic_istream<char, char_traits<char> >&
|
||
|
__cdecl ws(basic_istream<char, char_traits<char> >& _Istr)
|
||
|
{ // consume whitespace
|
||
|
typedef char _Elem;
|
||
|
typedef char_traits<_Elem> _Traits;
|
||
|
ios_base::iostate _State = ios_base::goodbit;
|
||
|
const basic_istream<_Elem, _Traits>::sentry _Ok(_Istr, true);
|
||
|
|
||
|
if (_Ok)
|
||
|
{ // state okay, use facet to extract
|
||
|
const ctype<_Elem>& _Facet = _USE(_Istr.getloc(), ctype<_Elem>);
|
||
|
|
||
|
_TRY_IO_BEGIN
|
||
|
for (_Traits::int_type _Meta = _Istr.rdbuf()->sgetc(); ;
|
||
|
_Meta = _Istr.rdbuf()->snextc())
|
||
|
if (_Traits::eq_int_type(_Traits::eof(), _Meta))
|
||
|
{ // end of file, quit
|
||
|
_State |= ios_base::eofbit;
|
||
|
break;
|
||
|
}
|
||
|
else if (!_Facet.is(ctype<_Elem>::space,
|
||
|
_Traits::to_char_type(_Meta)))
|
||
|
break; // not whitespace, quit
|
||
|
_CATCH_IO_(_Istr)
|
||
|
}
|
||
|
|
||
|
_Istr.setstate(_State);
|
||
|
return (_Istr);
|
||
|
}
|
||
|
|
||
|
_CRTIMP2 inline basic_istream<wchar_t, char_traits<wchar_t> >&
|
||
|
__cdecl ws(basic_istream<wchar_t, char_traits<wchar_t> >& _Istr)
|
||
|
{ // consume whitespace
|
||
|
typedef wchar_t _Elem;
|
||
|
typedef char_traits<_Elem> _Traits;
|
||
|
ios_base::iostate _State = ios_base::goodbit;
|
||
|
const basic_istream<_Elem, _Traits>::sentry _Ok(_Istr, true);
|
||
|
|
||
|
if (_Ok)
|
||
|
{ // state okay, use facet to extract
|
||
|
const ctype<_Elem>& _Facet = _USE(_Istr.getloc(), ctype<_Elem>);
|
||
|
|
||
|
_TRY_IO_BEGIN
|
||
|
for (_Traits::int_type _Meta = _Istr.rdbuf()->sgetc(); ;
|
||
|
_Meta = _Istr.rdbuf()->snextc())
|
||
|
if (_Traits::eq_int_type(_Traits::eof(), _Meta))
|
||
|
{ // end of file, quit
|
||
|
_State |= ios_base::eofbit;
|
||
|
break;
|
||
|
}
|
||
|
else if (!_Facet.is(ctype<_Elem>::space,
|
||
|
_Traits::to_char_type(_Meta)))
|
||
|
break; // not whitespace, quit
|
||
|
|
||
|
_CATCH_IO_(_Istr)
|
||
|
}
|
||
|
_Istr.setstate(_State);
|
||
|
return (_Istr);
|
||
|
}
|
||
|
_STD_END
|
||
|
#pragma warning(pop)
|
||
|
#pragma pack(pop)
|
||
|
|
||
|
#endif /* _ISTREAM_ */
|
||
|
|
||
|
/*
|
||
|
* Copyright (c) 1992-2001 by P.J. Plauger. ALL RIGHTS RESERVED.
|
||
|
* Consult your license regarding permissions and restrictions.
|
||
|
V3.10:0009 */
|