Category : C++ Source Code
Archive   : VCCRT1.ZIP
Filename : STDIOSTR.CXX
*stdiostr.cxx -
*
* Copyright (c) 1991-1992, Microsoft Corporation. All rights reserved.
*
*Purpose:
*
*******************************************************************************/
#include
#include
#include
#pragma hdrstop
extern "C" {
#include
#include
}
#include
stdiobuf::stdiobuf(FILE * f)
: streambuf()
{
unbuffered(1); // initially unbuffered
_str = f;
}
stdiobuf::~stdiobuf()
// : ~streambuf()
{
stdiobuf::sync(); // make sure buffer flushed
// _str = 0;
}
int stdiobuf::setrwbuf(int readsize, int writesize)
{
char * tbuf;
unbuffered(!(readsize+writesize));
if (unbuffered())
return(0);
tbuf = new char[(readsize+writesize)];
if (!tbuf)
return(EOF);
setb( tbuf, tbuf + (readsize+writesize), 1);
if (readsize)
{
setg(base(),base()+readsize,base()+readsize);
}
else
{
setg(0,0,0);
}
if (writesize)
{
setp(base()+readsize,ebuf());
}
else
{
setp(0,0);
}
return(1);
}
int stdiobuf::overflow(int c) {
long count, nout;
if (allocate()==EOF) // make sure there is a reserve area
return EOF;
if (!unbuffered() && epptr())
{
if ((count = pptr() - pbase()) > 0)
{
nout=fwrite((void *) pbase(), 1, (int)count, _str);
pbump(-(int)nout);
if (nout != count)
{
memmove(pbase(),pbase()+nout,(int)(count-nout));
return(EOF);
}
}
}
if ((!unbuffered()) && (!epptr()))
setp(base()+(blen()>>1),ebuf()); // hack: default to 2nd half
if (c!=EOF)
{
if ((!unbuffered()) && (pptr() < epptr())) // guard against recursion
sputc(c);
else
return fputc(c, _str);
}
return(1); // return something other than EOF if successful
}
int stdiobuf::underflow()
{
int count;
if (allocate()==EOF) // make sure there is a reserve area
return EOF;
if ((!unbuffered()) && (!egptr()))
setg(base(),(base()+(blen()>>1)),(base()+(blen()>>1))); // hack: default
if (unbuffered() || (!egptr()))
return fgetc(_str);
if (gptr() >= egptr())
// buffer empty, try for more
{
if (!(count = fread((void *)eback(), 1, (size_t)(egptr()-eback()), _str)))
return(EOF); // reach EOF, nothing read
setg(eback(),(egptr()-count),egptr()); // _gptr = _egptr - count
if (gptr()!=eback())
{
// CONSIDER: expensive, is there a better sol'n?
memmove(gptr(), eback(), count); // overlapping memory!
}
}
return sbumpc(); // CONSIDER: possible recursion
}
streampos stdiobuf::seekoff(streamoff off, ios::seek_dir dir, int)
{
int fdir;
long retpos;
switch (dir) {
case ios::beg :
fdir = SEEK_SET;
break;
case ios::cur :
fdir = SEEK_CUR;
break;
case ios::end :
fdir = SEEK_END;
break;
default:
// error
return(EOF);
}
// CONSIDER: is this needed?
stdiobuf::overflow(EOF);
if (fseek(_str, off, fdir))
return (EOF);
if ((retpos=ftell(_str))==-1L)
return(EOF);
return((streampos)retpos);
}
int stdiobuf::pbackfail(int c)
{
if (eback()
if (stdiobuf::seekoff( -1, ios::cur, ios::in)==EOF)
return EOF;
if (!unbuffered() && egptr())
{
memmove((gptr()+1),gptr(),(egptr()-(gptr()+1)));
*gptr()=(char)c;
}
return(c);
}
int stdiobuf::sync()
{
long count;
char * p;
FILE __near * stream;
char flags;
if (!unbuffered())
{
if (stdiobuf::overflow(EOF)==EOF)
return(EOF);
if ((count=in_avail())>0)
{
stream = (FILE __near *) _FP_OFF(_str);
flags = _osfile[_fileno(stream)];
if (flags & FTEXT)
{
// If text mode, need to account for CR/LF etc.
for (p = gptr(); p < egptr(); p++)
if (*p == '\n')
count++;
// account for EOF if read, not counted by _read
// UNDONE: is this necessary?
if ((_iob2_(stream))._flag2 & _IOCTRLZ)
count++;
#if 0
// UNDONE: is this correct?
if ((gptr()==eback()) && (flags & FCRLF))
count--;
#endif
}
if (stdiobuf::seekoff( -count, ios::cur, ios::in)==EOF)
return(EOF);
setg(eback(),egptr(),egptr()); // empty get area (_gptr = _egptr;)
}
}
return(0);
}
stdiostream::stdiostream(FILE * file)
: iostream(new stdiobuf(file))
{
istream::delbuf(1);
ostream::delbuf(1);
// CONSIDER: do anything else?
}
stdiostream::~stdiostream()
{
// CONSIDER: do anything else?
}
// include here for better granularity
int ios::sunk_with_stdio = 0;
void ios::sync_with_stdio()
{
#if ((!defined(_WINDOWS)) || defined(_QWIN))
if (!sunk_with_stdio) // first time only
{
// printf("In sync_with_stdio\n");
cin = new stdiobuf(stdin);
cin.delbuf(1);
cin.setf(ios::stdio);
cout = new stdiobuf(stdout);
cout.delbuf(1);
cout.setf(ios::stdio|ios::unitbuf);
((stdiobuf*)(cout.rdbuf()))->setrwbuf(0,80); // UNDONE: size??
cerr = new stdiobuf(stderr);
cerr.delbuf(1);
cerr.setf(ios::stdio|ios::unitbuf);
((stdiobuf*)(cerr.rdbuf()))->setrwbuf(0,80); // UNDONE: size??
clog = new stdiobuf(stderr);
clog.delbuf(1);
clog.setf(ios::stdio);
((stdiobuf*)(clog.rdbuf()))->setrwbuf(0,BUFSIZ);
sunk_with_stdio++;
}
#endif
}
Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!
This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.
But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/