|
|
researchv10 Norman
/*ident "@(#)ctrans:lib/stream/streambuf.c 1.1.6.2" */
/**************************************************************************
Copyright (c) 1984 AT&T
All Rights Reserved
THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T
The copyright notice above does not evidence any
actual or intended publication of such source code.
streambuf.c:
*****************************************************************************/
#include <iostream.h>
#include "streamdefs.h"
#include <string.h>
#include <memory.h>
/*
Allocate some space for the buffer.
Returns: EOF on error
0 on success
*/
int streambuf::doallocate()
{
char *buf = new char[STREAMBUFSIZE] ;
if ( !buf ) return EOF ;
setb(buf,buf+STREAMBUFSIZE,1) ;
return 0;
}
/*
Come here on a put to a full buffer. Allocate the buffer if
it is uninitialized.
Returns: EOF on error
the argument on success
*/
int streambuf::overflow(int c)
{
if ( c==EOF ) return zapeof(c) ;
if ( allocate() == EOF) return EOF;
if ( x_pptr <= x_epptr ) return sputc(c) ;
else return EOF ;
}
/*
Fill a buffer.
Returns: EOF on error or end of input
next character on success
*/
int streambuf::underflow()
{
if ( x_pptr > x_egptr ) setg(x_eback,x_gptr,x_pptr) ;
if ( x_egptr > x_gptr ) return 0 ;
else return EOF ;
}
int streambuf::pbackfail(int)
{
return EOF;
}
int streambuf::sync()
{
// It's unclear exactly what this should do. Should it reset
// the buffer or what. One theory (that used to be in the code.
// was that it should insert a 0. Which seems to be the
// right thing for "strings".
if ( x_pptr && x_epptr > x_pptr ) sputc(0) ;
return EOF ;
}
streampos streambuf::seekpos(streampos p, open_mode m)
{
return seekoff(p, ios::beg, m) ;
}
streampos streambuf::seekoff(streampos,seek_dir,open_mode)
{
return EOF ;
}
int streambuf::xsputn(register const char* s, int n)
{
register int req = n ;
if ( unbuffered() ) {
while( req-- > 0 ) {
if ( sputc(*s++) == EOF ) return n-req-1 ;
}
return n ;
}
register int avail = x_epptr-x_pptr ;
while ( avail < req ) {
memcpy(x_pptr,s,avail) ;
s += avail ;
pbump(avail) ;
req -= avail ;
if ( overflow(zapeof(*s++)) == EOF ) return n-req ;
--req ;
avail = x_epptr-x_pptr ;
}
memcpy(x_pptr,s,req ) ;
pbump(req) ;
return n ;
}
int streambuf::xsgetn(register char* s, int n)
{
register char* p = s ;
register int req = n ;
if ( unbuffered() ) {
while (req-- > 0 ) {
register int c ;
if ( (c=sbumpc() ) != EOF ) *p++ = c ;
else return p-s ;
}
}
if ( req <= 0 ) return 0 ;
register int avail = x_egptr-x_gptr ;
while ( avail < req ) {
memcpy(p,x_gptr,avail) ;
p += avail ;
req -= avail ;
gbump(avail) ;
if ( underflow()==EOF ) return p-s ;
avail = x_egptr-x_gptr ;
}
memcpy(p,x_gptr,req) ;
gbump(req) ;
return n ;
}
streambuf* streambuf::setbuf(char* p , int len)
{
if ( x_base ) return 0 ;
if ( len <= 0 || p == 0 ) {
// make it unbuffered
setb(0,0,0) ;
setg(0,0,0) ;
setp(0,0);
unbuffered(1) ;
}
else {
setb(p,p+len,0) ;
setg(p,p,p) ;
setp(p,p+len) ;
unbuffered(0) ;
}
return this;
}
streambuf* streambuf::setbuf(unsigned char* p, int len)
{
return setbuf((char*)p,len) ;
}
streambuf::streambuf() :
x_unbuf(0), alloc(0)
{
setb(0,0,0);
setg(0,0,0);
setp(0,0);
}
streambuf::streambuf(char* p, int l) :
x_unbuf(0), alloc(0)
{
setb(0,0,0);
setbuf(p,l) ;
}
streambuf::~streambuf()
{
sync() ;
if (x_base && alloc) delete x_base;
}
int streambuf::x_snextc()
{
// called by snextc to handle overflow
if ( x_egptr==0 || x_gptr != x_egptr ) {
// we stepped beyond x_gptr meaning snextc was called when
// x_gtr == x_egptr rather than when x_gptr+1=x_egptr.
underflow() ;
pbump(1) ;
}
return sgetc() ;
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.