Source code of Windows XP (NT5)
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.
 
 
 
 
 
 

500 lines
14 KiB

// sstream standard header
#pragma once
#ifndef _SSTREAM_
#define _SSTREAM_
#include <string>
#pragma pack(push,8)
#pragma warning(push,3)
#pragma warning(disable: 4251)
_STD_BEGIN
// TEMPLATE CLASS basic_stringbuf
template<class _Elem,
class _Traits,
class _Alloc>
class basic_stringbuf
: public basic_streambuf<_Elem, _Traits>
{ // stream buffer maintaining an allocated character array
public:
typedef _Alloc allocator_type;
typedef basic_streambuf<_Elem, _Traits> _Mysb;
typedef basic_string<_Elem, _Traits, _Alloc> _Mystr;
explicit basic_stringbuf(ios_base::openmode _Mode =
ios_base::in | ios_base::out)
{ // construct empty character buffer from mode
_Init(0, 0, _Getstate(_Mode));
}
explicit basic_stringbuf(const _Mystr& _Str,
ios_base::openmode _Mode = ios_base::in | ios_base::out)
{ // construct character buffer from string, mode
_Init(_Str.c_str(), _Str.size(), _Getstate(_Mode));
}
virtual ~basic_stringbuf()
{ // destroy the object
_Tidy();
}
enum
{ // constants for bits in stream state
_Allocated = 1, // set if character array storage has been allocated
_Constant = 2, // set if character array nonmutable
_Noread = 4}; // set if character array cannot be read
typedef int _Strstate;
typedef typename _Traits::int_type int_type;
typedef typename _Traits::pos_type pos_type;
typedef typename _Traits::off_type off_type;
_Mystr str() const
{ // return string copy of character array
if (!(_Mystate & _Constant) && _Mysb::pptr() != 0)
{ // writable, make string from write buffer
_Mystr _Str(_Mysb::pbase(), (_Seekhigh < _Mysb::pptr()
? _Mysb::pptr() : _Seekhigh) - _Mysb::pbase());
return (_Str);
}
else if (!(_Mystate & _Noread) && _Mysb::gptr() != 0)
{ // readable, make string from read buffer
_Mystr _Str(_Mysb::eback(), _Mysb::egptr() - _Mysb::eback());
return (_Str);
}
else
{ // inaccessible, return empty string
_Mystr _Nul;
return (_Nul);
}
}
void str(const _Mystr& _Newstr)
{ // replace character array from string
_Tidy();
_Init(_Newstr.c_str(), _Newstr.size(), _Mystate);
}
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 (_Mystate & _Constant)
return (_Traits::eof()); // array nonmutable, fail
else
{ // grow buffer and store element
size_t _Oldsize = _Mysb::pptr() == 0
? 0 : _Mysb::epptr() - _Mysb::eback();
size_t _Newsize = _Oldsize;
size_t _Inc = _Newsize / 2 < _MINSIZE
? _MINSIZE : _Newsize / 2; // grow by 50 per cent
_Elem *_Ptr = 0;
while (0 < _Inc && INT_MAX - _Inc < _Newsize)
_Inc /= 2; // increment causes overflow, halve it
if (0 < _Inc)
{ // finite increment, allocate new character array
_Newsize += _Inc;
_Ptr = _Al.allocate(_Newsize, (void *)0);
}
if (0 < _Oldsize)
_Traits::copy(_Ptr, _Mysb::eback(), _Oldsize);
if (_Mystate & _Allocated)
_Al.deallocate(_Mysb::eback(), _Oldsize);
_Mystate |= _Allocated;
if (_Oldsize == 0)
{ // first growth, set up pointers
_Seekhigh = _Ptr;
_Mysb::setp(_Ptr, _Ptr + _Newsize);
if (_Mystate & _Noread)
_Mysb::setg(_Ptr, 0, _Ptr);
else
_Mysb::setg(_Ptr, _Ptr, _Ptr + 1);
}
else
{ // not first growth, adjust pointers
_Seekhigh = _Seekhigh - _Mysb::eback() + _Ptr;
_Mysb::setp(_Mysb::pbase() - _Mysb::eback() + _Ptr,
_Mysb::pptr() - _Mysb::eback() + _Ptr, _Ptr + _Newsize);
if (_Mystate & _Noread)
_Mysb::setg(_Ptr, 0, _Ptr);
else
_Mysb::setg(_Ptr,
_Mysb::gptr() - _Mysb::eback() + _Ptr,
_Mysb::pptr() + 1);
}
*_Mysb::_Pninc() = _Traits::to_char_type(_Meta);
return (_Meta);
}
}
virtual int_type pbackfail(int_type _Meta = _Traits::eof())
{ // put an element back to stream
if (_Mysb::gptr() == 0
|| _Mysb::gptr() <= _Mysb::eback()
|| !_Traits::eq_int_type(_Traits::eof(), _Meta)
&& !_Traits::eq(_Traits::to_char_type(_Meta), _Mysb::gptr()[-1])
&& _Mystate & _Constant)
return (_Traits::eof()); // can't put back, fail
else
{ // back up one position and store put-back character
_Mysb::gbump(-1);
if (!_Traits::eq_int_type(_Traits::eof(), _Meta))
*_Mysb::gptr() = _Traits::to_char_type(_Meta);
return (_Traits::not_eof(_Meta));
}
}
virtual int_type underflow()
{ // get an element from stream, but don't point past it
if (_Mysb::gptr() == 0)
return (_Traits::eof()); // no character buffer, fail
else if (_Mysb::gptr() < _Mysb::egptr())
return (_Traits::to_int_type(*_Mysb::gptr())); // return buffered
else if (_Mystate & _Noread || _Mysb::pptr() == 0
|| _Mysb::pptr() <= _Mysb::gptr() && _Seekhigh <= _Mysb::gptr())
return (_Traits::eof()); // can't read, fail
else
{ // extend read buffer into written area, then return buffered
if (_Seekhigh < _Mysb::pptr())
_Seekhigh = _Mysb::pptr();
_Mysb::setg(_Mysb::eback(), _Mysb::gptr(), _Seekhigh);
return (_Traits::to_int_type(*_Mysb::gptr()));
}
}
virtual pos_type seekoff(off_type _Off, ios_base::seekdir _Way,
ios_base::openmode _Which = ios_base::in | ios_base::out)
{ // change position by _Off, according to _Way, _Mode
if (_Mysb::pptr() != 0 && _Seekhigh < _Mysb::pptr())
_Seekhigh = _Mysb::pptr(); // update high-water pointer
if (_Which & ios_base::in && _Mysb::gptr() != 0)
{ // position within read buffer
if (_Way == ios_base::end)
_Off += off_type(_Seekhigh - _Mysb::eback());
else if (_Way == ios_base::cur
&& (_Which & ios_base::out) == 0)
_Off += off_type(_Mysb::gptr() - _Mysb::eback());
else if (_Way != ios_base::beg)
_Off = _BADOFF;
if (0 <= _Off && _Off <= _Seekhigh - _Mysb::eback())
{ // change read position
_Mysb::gbump((int)(_Mysb::eback() - _Mysb::gptr() + _Off));
if (_Which & ios_base::out && _Mysb::pptr() != 0)
_Mysb::setp(_Mysb::pbase(), _Mysb::gptr(),
_Mysb::epptr()); // change write position to match
}
else
_Off = _BADOFF;
}
else if (_Which & ios_base::out && _Mysb::pptr() != 0)
{ // position within write buffer
if (_Way == ios_base::end)
_Off += off_type(_Seekhigh - _Mysb::eback());
else if (_Way == ios_base::cur)
_Off += off_type(_Mysb::pptr() - _Mysb::eback());
else if (_Way != ios_base::beg)
_Off = _BADOFF;
if (0 <= _Off && _Off <= _Seekhigh - _Mysb::eback())
_Mysb::pbump((int)(_Mysb::eback()
- _Mysb::pptr() + _Off)); // change write position
else
_Off = _BADOFF;
}
else
_Off = _BADOFF; // neither read nor write buffer selected, fail
return (pos_type(_Off));
}
virtual pos_type seekpos(pos_type _Ptr,
ios_base::openmode _Mode = ios_base::in | ios_base::out)
{ // change position to _Pos, according to _Mode
streamoff _Off = (streamoff)_Ptr;
if (_Mysb::pptr() != 0 && _Seekhigh < _Mysb::pptr())
_Seekhigh = _Mysb::pptr(); // update high-water pointer
if (_Off == _BADOFF)
;
else if (_Mode & ios_base::in && _Mysb::gptr() != 0)
{ // position within read buffer
if (0 <= _Off && _Off <= _Seekhigh - _Mysb::eback())
{ // change read position
_Mysb::gbump((int)(_Mysb::eback() - _Mysb::gptr() + _Off));
if (_Mode & ios_base::out && _Mysb::pptr() != 0)
_Mysb::setp(_Mysb::pbase(), _Mysb::gptr(),
_Mysb::epptr()); // change write position to match
}
else
_Off = _BADOFF;
}
else if (_Mode & ios_base::out && _Mysb::pptr() != 0)
{ // position within write buffer
if (0 <= _Off && _Off <= _Seekhigh - _Mysb::eback())
_Mysb::pbump((int)(_Mysb::eback()
- _Mysb::pptr() + _Off)); // change write position
else
_Off = _BADOFF;
}
else
_Off = _BADOFF;
return (streampos(_Off));
}
void _Init(const _Elem *_Ptr, size_t _Count, _Strstate _State)
{ // initialize buffer to [_Ptr, _Ptr + _Count), set state
_Seekhigh = 0;
_Mystate = _State;
if (_Count != 0
&& (_Mystate & (_Noread | _Constant)) != (_Noread | _Constant))
{ // finite buffer that can be read or written, set it up
_Elem *_Pnew = _Al.allocate(_Count, (void *)0);
_Traits::copy(_Pnew, _Ptr, _Count);
_Seekhigh = _Pnew + _Count;
if (!(_Mystate & _Noread))
_Mysb::setg(_Pnew, _Pnew,
_Pnew + _Count); // setup read buffer
if (!(_Mystate & _Constant))
{ // setup write buffer, and maybe read buffer
_Mysb::setp(_Pnew, _Pnew + _Count);
if (_Mysb::gptr() == 0)
_Mysb::setg(_Pnew, 0, _Pnew);
}
_Mystate |= _Allocated;
}
}
void _Tidy()
{ // discard any allocated buffer and clear pointers
if (_Mystate & _Allocated)
_Al.deallocate(_Mysb::eback(),
(_Mysb::pptr() != 0 ? _Mysb::epptr()
: _Mysb::egptr()) - _Mysb::eback());
_Mysb::setg(0, 0, 0);
_Mysb::setp(0, 0);
_Seekhigh = 0;
_Mystate &= ~_Allocated;
}
private:
enum
{ // constant for minimum buffer size
_MINSIZE = 32};
_Strstate _Getstate(ios_base::openmode _Mode)
{ // convert open mode to stream state bits
_Strstate _State = (_Strstate)0;
if (!(_Mode & ios_base::in))
_State |= _Noread;
if (!(_Mode & ios_base::out))
_State |= _Constant;
return (_State);
}
_Elem *_Seekhigh; // the high-water pointer in character array
_Strstate _Mystate; // the stream state
allocator_type _Al; // the allocator object
};
#ifdef _DLL_CPPLIB
template class _CRTIMP2 basic_stringbuf<char,
char_traits<char>, allocator<char> >;
template class _CRTIMP2 basic_stringbuf<wchar_t,
char_traits<wchar_t>, allocator<wchar_t> >;
#endif // _DLL_CPPLIB
// TEMPLATE CLASS basic_istringstream
template<class _Elem,
class _Traits,
class _Alloc>
class basic_istringstream
: public basic_istream<_Elem, _Traits>
{ // input stream associated with a character array
public:
typedef _Alloc allocator_type;
typedef basic_stringbuf<_Elem, _Traits, _Alloc> _Mysb;
typedef basic_string<_Elem, _Traits, _Alloc> _Mystr;
explicit basic_istringstream(ios_base::openmode _Mode = ios_base::in)
: basic_istream<_Elem, _Traits>(&_Stringbuffer),
_Stringbuffer(_Mode | ios_base::in)
{ // construct empty readable character buffer
}
explicit basic_istringstream(const _Mystr& _Str,
ios_base::openmode _Mode = ios_base::in)
: basic_istream<_Elem, _Traits>(&_Stringbuffer),
_Stringbuffer(_Str, _Mode | ios_base::in)
{ // construct readable character buffer from NTCS
}
virtual ~basic_istringstream()
{ // destroy the object
}
_Mysb *rdbuf() const
{ // return pointer to file buffer
return ((_Mysb *)&_Stringbuffer);
}
_Mystr str() const
{ // return string copy of character array
return (_Stringbuffer.str());
}
void str(const _Mystr& _Newstr)
{ // replace character array from string
_Stringbuffer.str(_Newstr);
}
private:
_Mysb _Stringbuffer; // the string buffer
};
#ifdef _DLL_CPPLIB
template class _CRTIMP2 basic_istringstream<char,
char_traits<char>, allocator<char> >;
template class _CRTIMP2 basic_istringstream<wchar_t,
char_traits<wchar_t>, allocator<wchar_t> >;
#endif // _DLL_CPPLIB
// TEMPLATE CLASS basic_ostringstream
template<class _Elem,
class _Traits,
class _Alloc>
class basic_ostringstream
: public basic_ostream<_Elem, _Traits>
{ // output stream associated with a character array
public:
typedef _Alloc allocator_type;
typedef basic_stringbuf<_Elem, _Traits, _Alloc> _Mysb;
typedef basic_string<_Elem, _Traits, _Alloc> _Mystr;
explicit basic_ostringstream(ios_base::openmode _Mode = ios_base::out)
: basic_ostream<_Elem, _Traits>(&_Stringbuffer),
_Stringbuffer(_Mode | ios_base::out)
{ // construct empty writable character buffer
}
explicit basic_ostringstream(const _Mystr& _Str,
ios_base::openmode _Mode = ios_base::out)
: basic_ostream<_Elem, _Traits>(&_Stringbuffer),
_Stringbuffer(_Str, _Mode | ios_base::out)
{ // construct writable character buffer from NTCS
}
virtual ~basic_ostringstream()
{ // destroy the object
}
_Mysb *rdbuf() const
{ // return pointer to buffer
return ((_Mysb *)&_Stringbuffer);
}
_Mystr str() const
{ // return string copy of character array
return (_Stringbuffer.str());
}
void str(const _Mystr& _Newstr)
{ // replace character array from string
_Stringbuffer.str(_Newstr);
}
private:
_Mysb _Stringbuffer; // the string buffer
};
#ifdef _DLL_CPPLIB
template class _CRTIMP2 basic_ostringstream<char,
char_traits<char>, allocator<char> >;
template class _CRTIMP2 basic_ostringstream<wchar_t,
char_traits<wchar_t>, allocator<wchar_t> >;
#endif // _DLL_CPPLIB
// TEMPLATE CLASS basic_stringstream
template<class _Elem,
class _Traits,
class _Alloc>
class basic_stringstream
: public basic_iostream<_Elem, _Traits>
{ // input/output stream associated with a character array
public:
typedef _Elem char_type;
typedef _Traits traits_type;
typedef _Alloc allocator_type;
typedef typename _Traits::int_type int_type;
typedef typename _Traits::pos_type pos_type;
typedef typename _Traits::off_type off_type;
typedef basic_string<_Elem, _Traits, _Alloc> _Mystr;
explicit basic_stringstream(ios_base::openmode _Mode =
ios_base::in | ios_base::out)
: basic_iostream<_Elem, _Traits>(&_Stringbuffer),
_Stringbuffer(_Mode)
{ // construct empty character buffer
}
explicit basic_stringstream(const _Mystr& _Str,
ios_base::openmode _Mode = ios_base::in | ios_base::out)
: basic_iostream<_Elem, _Traits>(&_Stringbuffer),
_Stringbuffer(_Str, _Mode)
{ // construct character buffer from NTCS
}
virtual ~basic_stringstream()
{ // destroy the object
}
basic_stringbuf<_Elem, _Traits, _Alloc> *rdbuf() const
{ // return pointer to buffer
return ((basic_stringbuf<_Elem, _Traits, _Alloc> *)&_Stringbuffer);
}
_Mystr str() const
{ // return string copy of character array
return (_Stringbuffer.str());
}
void str(const _Mystr& _Newstr)
{ // replace character array from string
_Stringbuffer.str(_Newstr);
}
private:
basic_stringbuf<_Elem, _Traits, _Alloc>
_Stringbuffer; // the string buffer
};
#ifdef _DLL_CPPLIB
template class _CRTIMP2 basic_stringstream<char,
char_traits<char>, allocator<char> >;
template class _CRTIMP2 basic_stringstream<wchar_t,
char_traits<wchar_t>, allocator<wchar_t> >;
#endif // _DLL_CPPLIB
_STD_END
#pragma warning(default: 4251)
#pragma warning(pop)
#pragma pack(pop)
#endif /* _SSTREAM_ */
/*
* Copyright (c) 1992-2001 by P.J. Plauger. ALL RIGHTS RESERVED.
* Consult your license regarding permissions and restrictions.
V3.10:0009 */