windows-nt/Source/XPSP1/NT/base/crts/libw32/include/streambuf
2020-09-26 16:20:57 +08:00

401 lines
9.8 KiB
Plaintext

// streambuf standard header
#pragma once
#ifndef _STREAMBUF_
#define _STREAMBUF_
#include <xiosbase>
#pragma pack(push,8)
#pragma warning(push,3)
_STD_BEGIN
// TEMPLATE CLASS basic_streambuf
template<class _Elem, class _Traits>
class basic_streambuf
{ // control read/write buffers
basic_streambuf(const basic_streambuf<_Elem, _Traits>&); // not defined
basic_streambuf<_Elem, _Traits>&
operator=(const basic_streambuf<_Elem, _Traits>&); // not defined
protected:
basic_streambuf()
: _Plocale(_NEW_CRT locale)
{ // construct with no buffers
_Init();
}
basic_streambuf(_Uninitialized)
{ // construct uninitialized
}
public:
typedef basic_streambuf<_Elem, _Traits> _Myt;
typedef _Elem char_type;
typedef _Traits traits_type;
virtual ~basic_streambuf()
{ // destroy the object
_DELETE_CRT(_Plocale);
}
typedef typename _Traits::int_type int_type;
typedef typename _Traits::pos_type pos_type;
typedef typename _Traits::off_type off_type;
pos_type pubseekoff(off_type _Off, ios_base::seekdir _Way,
ios_base::openmode _Mode = ios_base::in | ios_base::out)
{ // change position by _Off, according to _Way, _Mode
return (seekoff(_Off, _Way, _Mode));
}
pos_type pubseekoff(off_type _Off, ios_base::seek_dir _Way,
ios_base::open_mode _Mode)
{ // change position by _Off, according to _Way, _Mode (old style)
return (pubseekoff(_Off, (ios_base::seekdir)_Way,
(ios_base::openmode)_Mode));
}
pos_type pubseekpos(pos_type _Pos,
ios_base::openmode _Mode = ios_base::in | ios_base::out)
{ // change position to _Pos, according to _Mode
return (seekpos(_Pos, _Mode));
}
pos_type pubseekpos(pos_type _Pos, ios_base::open_mode _Mode)
{ // change position to _Pos, according to _Mode (old style)
return (seekpos(_Pos, (ios_base::openmode)_Mode));
}
_Myt *pubsetbuf(_Elem *_Buffer, streamsize _Count)
{ // offer _Buffer to external agent
return (setbuf(_Buffer, _Count));
}
locale pubimbue(const locale &_Newlocale)
{ // set locale to argument
locale _Oldlocale = *_Plocale;
imbue(_Newlocale);
*_Plocale = _Newlocale;
return (_Oldlocale);
}
locale getloc() const
{ // get locale
return (*_Plocale);
}
streamsize in_avail()
{ // return count of buffered input characters
return (gptr() != 0 && gptr() < egptr()
? (streamsize)(egptr() - gptr()) : showmanyc());
}
int pubsync()
{ // synchronize with external agent
return (sync());
}
int_type sbumpc()
{ // get a character and point past it
return (gptr() != 0 && gptr() < egptr()
? _Traits::to_int_type(*_Gninc()) : uflow());
}
int_type sgetc()
{ // get a character and don't point past it
return (gptr() != 0 && gptr() < egptr()
? _Traits::to_int_type(*gptr()) : underflow());
}
streamsize sgetn(_Elem *_Ptr, streamsize _Count)
{ // get up to _Count characters into array beginning at _Ptr
return (xsgetn(_Ptr, _Count));
}
int_type snextc()
{ // point to next character and return it
return (_Traits::eq_int_type(_Traits::eof(), sbumpc())
? _Traits::eof() : sgetc());
}
int_type sputbackc(_Elem _Ch)
{ // put back _Ch
return (gptr() != 0 && eback() < gptr()
&& _Traits::eq(_Ch, gptr()[-1])
? _Traits::to_int_type(*_Gndec())
: pbackfail(_Traits::to_int_type(_Ch)));
}
void stossc()
{ // point past a character
if (gptr() != 0 && gptr() < egptr())
_Gninc();
else
uflow();
}
int_type sungetc()
{ // back up one position
return (gptr() != 0 && eback() < gptr()
? _Traits::to_int_type(*_Gndec()) : pbackfail());
}
int_type sputc(_Elem _Ch)
{ // put a character
return (pptr() != 0 && pptr() < epptr()
? _Traits::to_int_type(*_Pninc() = _Ch)
: overflow(_Traits::to_int_type(_Ch)));
}
streamsize sputn(const _Elem *_Ptr, streamsize _Count)
{ // put _Count characters from array beginning at _Ptr
return (xsputn(_Ptr, _Count));
}
void _Lock()
{ // set the thread lock
_Mylock._Lock();
}
void _Unlock()
{ // clear the thread lock
_Mylock._Unlock();
}
protected:
_Elem *eback() const
{ // return beginning of read buffer
return (*_IGfirst);
}
_Elem *gptr() const
{ // return current position in read buffer
return (*_IGnext);
}
_Elem *pbase() const
{ // return beginning of write buffer
return (*_IPfirst);
}
_Elem *pptr() const
{ // return current position in write buffer
return (*_IPnext);
}
_Elem *egptr() const
{ // return end of read buffer
return (*_IGnext + *_IGcount);
}
void gbump(int _Off)
{ // alter current position in read buffer by _Off
*_IGcount -= _Off;
*_IGnext += _Off;
}
void setg(_Elem *_First, _Elem *_Next, _Elem *_Last)
{ // set pointers for read buffer
*_IGfirst = _First;
*_IGnext = _Next;
*_IGcount = (int)(_Last - _Next);
}
_Elem *epptr() const
{ // return end of write buffer
return (*_IPnext + *_IPcount);
}
_Elem *_Gndec()
{ // decrement current position in read buffer
++*_IGcount;
return (--*_IGnext);
}
_Elem *_Gninc()
{ // increment current position in read buffer
--*_IGcount;
return ((*_IGnext)++);
}
void pbump(int _Off)
{ // alter current position in write buffer by _Off
*_IPcount -= _Off;
*_IPnext += _Off;
}
void setp(_Elem *_First, _Elem *_Last)
{ // set pointers for write buffer
*_IPfirst = _First;
*_IPnext = _First;
*_IPcount = (int)(_Last - _First);
}
void setp(_Elem *_First, _Elem *_Next, _Elem *_Last)
{ // set pointers for write buffer, extended version
*_IPfirst = _First;
*_IPnext = _Next;
*_IPcount = (int)(_Last - _Next);
}
_Elem *_Pninc()
{ // decrement current position in write buffer
--*_IPcount;
return ((*_IPnext)++);
}
void _Init()
{ // initialize buffer parameters for no buffers
_IGfirst = &_Gfirst, _IPfirst = &_Pfirst;
_IGnext = &_Gnext, _IPnext = &_Pnext;
_IGcount = &_Gcount, _IPcount = &_Pcount;
setp(0, 0), setg(0, 0, 0);
}
void _Init(_Elem **_Gf, _Elem **_Gn, int *_Gc,
_Elem **_Pf, _Elem **_Pn, int *_Pc)
{ // initialize buffer parameters as specified
_IGfirst = _Gf, _IPfirst = _Pf;
_IGnext = _Gn, _IPnext = _Pn;
_IGcount = _Gc, _IPcount = _Pc;
}
virtual int_type overflow(int_type = _Traits::eof())
{ // put a character to stream (always fail)
return (_Traits::eof());
}
virtual int_type pbackfail(int_type = _Traits::eof())
{ // put a character back to stream (always fail)
return (_Traits::eof());
}
virtual streamsize showmanyc()
{ // return count of input characters
return (0);
}
virtual int_type underflow()
{ // get a character from stream, but don't point past it
return (_Traits::eof());
}
virtual int_type uflow()
{ // get a character from stream, point past it
return (_Traits::eq_int_type(_Traits::eof(), underflow())
? _Traits::eof() : _Traits::to_int_type(*_Gninc()));
}
virtual streamsize xsgetn(_Elem * _Ptr, streamsize _Count)
{ // get _Count characters from stream
int_type _Meta;
streamsize _Size, _Copied;
for (_Copied = 0; 0 < _Count; )
if (gptr() != 0 && 0 < (_Size = (streamsize)(egptr() - gptr())))
{ // copy from read buffer
if (_Count < _Size)
_Size = _Count;
_Traits::copy(_Ptr, gptr(), _Size);
_Ptr += _Size;
_Copied += _Size;
_Count -= _Size;
gbump((int)_Size);
}
else if (_Traits::eq_int_type(_Traits::eof(), _Meta = uflow()))
break; // end of file, quit
else
{ // get a single character
*_Ptr++ = _Traits::to_char_type(_Meta);
++_Copied;
--_Count;
}
return (_Copied);
}
virtual streamsize xsputn(const _Elem *_Ptr, streamsize _Count)
{ // put _Count characters to stream
streamsize _Size, _Copied;
for (_Copied = 0; 0 < _Count; )
if (pptr() != 0 && 0 < (_Size = (streamsize)(epptr() - pptr())))
{ // copy to write buffer
if (_Count < _Size)
_Size = _Count;
_Traits::copy(pptr(), _Ptr, _Size);
_Ptr += _Size;
_Copied += _Size;
_Count -= _Size;
pbump((int)_Size);
}
else if (_Traits::eq_int_type(_Traits::eof(),
overflow(_Traits::to_int_type(*_Ptr))))
break; // single character put failed, quit
else
{ // count character successfully put
++_Ptr;
++_Copied;
--_Count;
}
return (_Copied);
}
virtual pos_type seekoff(off_type, ios_base::seekdir,
ios_base::openmode = ios_base::in | ios_base::out)
{ // change position by offset, according to way and mode
return (streampos(_BADOFF));
}
virtual pos_type seekpos(pos_type,
ios_base::openmode = ios_base::in | ios_base::out)
{ // change to specified position, according to mode
return (streampos(_BADOFF));
}
virtual _Myt *setbuf(_Elem *, streamsize)
{ // offer buffer to external agent (do nothing)
return (this);
}
virtual int sync()
{ // synchronize with external agent (do nothing)
return (0);
}
virtual void imbue(const locale&)
{ // set locale to argument (do nothing)
}
private:
_Mutex _Mylock; // thread lock
_Elem *_Gfirst; // beginning of read buffer
_Elem *_Pfirst; // beginning of write buffer
_Elem **_IGfirst; // pointer to beginning of read buffer
_Elem **_IPfirst; // pointer to beginning of write buffer
_Elem *_Gnext; // current position in read buffer
_Elem *_Pnext; // current position in write buffer
_Elem **_IGnext; // pointer to current position in read buffer
_Elem **_IPnext; // pointer to current position in write buffer
int _Gcount; // length of read buffer
int _Pcount; // length of write buffer
int *_IGcount; // pointer to length of read buffer
int *_IPcount; // pointer to length of write buffer
locale *_Plocale; // pointer to imbued locale object
};
#ifdef _DLL_CPPLIB
template class _CRTIMP2 basic_streambuf<char, char_traits<char> >;
template class _CRTIMP2 basic_streambuf<wchar_t, char_traits<wchar_t> >;
#endif // _DLL_CPPLIB
_STD_END
#pragma warning(pop)
#pragma pack(pop)
#endif /* _STREAMBUF_ */
/*
* Copyright (c) 1992-2001 by P.J. Plauger. ALL RIGHTS RESERVED.
* Consult your license regarding permissions and restrictions.
V3.10:0009 */