/*ident "@(#)cls4:lib/stream/streambuf.c 1.5" */ /******************************************************************************* C++ source for the C++ Language System, Release 3.0. This product is a new release of the original cfront developed in the computer science research center of AT&T Bell Laboratories. Copyright (c) 1993 UNIX System Laboratories, Inc. Copyright (c) 1991, 1992 AT&T and UNIX System Laboratories, Inc. Copyright (c) 1984, 1989, 1990 AT&T. All Rights Reserved. THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE of AT&T and UNIX System Laboratories, Inc. The copyright notice above does not evidence any actual or intended publication of such source code. *******************************************************************************/ #include #include "streamdefs.h" #include #include /* 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, int m) { return seekoff(p, ios::beg, m) ; } streampos streambuf::seekoff(streampos,ios::seek_dir,int) { 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 ( req <= 0 ) return 0 ; if ( unbuffered() ) { while (req-- > 0 ) { register int c ; if ( (c=sbumpc() ) != EOF ) *p++ = c ; else return p-s ; } return n ; } 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 underflow if ( x_egptr==0 || x_gptr != x_egptr ) { // we stepped beyond x_gptr meaning snextc was called when // x_gptr == x_egptr rather than when x_gptr+1=x_egptr. underflow() ; gbump(1) ; } return sgetc() ; }