Category : C++ Source Code
Archive   : VCCRT1.ZIP
Filename : STDIOSTR.CXX

 
Output of file : STDIOSTR.CXX contained in archive : VCCRT1.ZIP
/***
*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
}


  3 Responses to “Category : C++ Source Code
Archive   : VCCRT1.ZIP
Filename : STDIOSTR.CXX

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. 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/