home *** CD-ROM | disk | FTP | other *** search
- /***
- *streamb.cpp - fuctions for streambuf class.
- *
- * Copyright (c) 1990-1997, Microsoft Corporation. All rights reserved.
- *
- *Purpose:
- * Functions for streambuf class.
- *
- *******************************************************************************/
-
- #include <cruntime.h>
- #include <internal.h>
- #include <string.h>
- #include <stdlib.h>
- #include <iostream.h>
- #include <dbgint.h>
- #pragma hdrstop
-
-
- #ifndef BUFSIZ
- #define BUFSIZ 512
- #endif /* BUFSIZ */
-
- /***
- *streambuf::streambuf() -
- *
- *Purpose:
- * Default constructor.
- *
- *Entry:
- *
- *Exit:
- *
- *Exceptions:
- *
- *******************************************************************************/
-
- streambuf::streambuf()
- {
- _fAlloc = 0;
- _fUnbuf = 0;
- x_lastc = EOF;
- _base = NULL;
- _ebuf = NULL;
- _pbase = NULL;
- _pptr = NULL;
- _epptr = NULL;
- _eback = NULL;
- _gptr = NULL;
- _egptr = NULL;
-
- #ifdef _MT
- LockFlg = -1; // default is now : locking
- _mtlockinit(lockptr());
- #endif /* _MT */
-
- }
-
- /***
- *streambuf::streambuf(char* pBuf, int cbBuf) -
- *
- *Purpose:
- * Constructor which specifies a buffer area.
- *
- *Entry:
- *
- *Exit:
- *
- *Exceptions:
- *
- *******************************************************************************/
-
- streambuf::streambuf( char* pBuf, int cbBuf )
- {
- _fAlloc = 0;
- _fUnbuf = 0;
- x_lastc = EOF;
- _base = pBuf;
- _ebuf = pBuf + (unsigned)cbBuf;
- _pbase = NULL;
- _pptr = NULL;
- _epptr = NULL;
- _eback = NULL;
- _gptr = NULL;
- _egptr = NULL;
-
- if( pBuf == NULL || cbBuf == 0 ){
- _fUnbuf = 1;
- _base = NULL;
- _ebuf = NULL;
- }
-
- #ifdef _MT
- LockFlg = -1; // default is now : locking
- _mtlockinit(lockptr());
- #endif /* _MT */
-
- }
-
-
- /***
- *virtual streambuf::~streambuf() -
- *
- *Purpose:
- * Destructor.
- *
- *Entry:
- *
- *Exit:
- *
- *Exceptions:
- *
- *******************************************************************************/
-
- streambuf::~streambuf()
- {
- #ifdef _MT
- _mtlockterm(lockptr());
- #endif /* _MT */
-
- sync(); // make sure buffer empty before possibly destroying it
- if( (_fAlloc) && (_base) )
- delete _base;
- }
-
-
- /***
- * virtual streambuf * streambuf::setbuf(char * p, int len) -
- *
- *Purpose:
- * Offers the array at p with len bytes to be used as a reserve area.
- *
- *Entry:
- *
- *Exit:
- *
- *Exceptions:
- *
- *******************************************************************************/
-
- streambuf * streambuf::setbuf(char * p, int len)
- {
- if (!_base)
- {
- if ((!p) || (!len))
- _fUnbuf = 1; // mark as unbuffered
- else
- {
- _base = p;
- _ebuf = p + (unsigned)len;
- _fUnbuf = 0;
- }
- return (this);
- }
- return((streambuf *)NULL);
- }
-
-
- /***
- *virtual int streambuf::xsputn( char* pBuf, int cbBuf ) -
- *
- *Purpose:
- * Tries to output cbBuf characters. Returns number of characters
- * that were outputted.
- *
- *Entry:
- *
- *Exit:
- *
- *Exceptions:
- *
- *******************************************************************************/
-
- int streambuf::xsputn( const char* pBuf, int cbBuf )
- {
- int cbOut;
-
- for (cbOut = 0; cbBuf--; cbOut++)
- {
- if ((_fUnbuf) || (_pptr >= _epptr))
- {
- if (overflow((unsigned char)*pBuf)==EOF) // 0-extend 0xFF !=EOF
- break;
- }
- else
- {
- *(_pptr++) = *pBuf;
- }
- pBuf++;
- }
- return cbOut;
- }
-
- /***
- *virtual int streambuf::xsgetn( char* pBuf, int cbBuf ) -
- *
- *Purpose:
- * Tries to input cbBuf characters. Returns number of characters
- * that were read from streambuf.
- *
- *Entry:
- *
- *Exit:
- *
- *Exceptions:
- *
- *******************************************************************************/
-
- // #pragma intrinsic(memcpy,__min)
-
- int streambuf::xsgetn( char * pBuf, int cbBuf)
- {
- int count;
- int cbIn = 0;
- if (_fUnbuf)
- {
- if (x_lastc==EOF)
- x_lastc=underflow();
-
- while (cbBuf--)
- {
- if (x_lastc==EOF)
- break;
- *(pBuf++) = (char)x_lastc;
- cbIn++;
- x_lastc=underflow();
- }
- }
- else
- {
- while (cbBuf)
- {
- if (underflow()==EOF) // make sure something to read
- break;
- count = __min(egptr() - gptr(),cbBuf);
- if (count>0)
- {
- memcpy(pBuf,gptr(),count);
- pBuf += count;
- _gptr += count;
- cbIn += count;
- cbBuf -= count;
- }
- }
- }
- return cbIn;
- }
-
- /***
- *virtual int streambuf::sync() -
- *
- *Purpose:
- * Tries to flush all data in put area and give back any data in the
- * get area (if possible), leaving both areas empty on exit.
- * Default behavior is to fail unless buffers empty.
- *
- *Entry:
- *
- *Exit:
- *
- *Exceptions:
- *
- *******************************************************************************/
-
- int streambuf::sync()
- {
- if ((gptr() <_egptr) || (_pptr > _pbase))
- {
- return EOF;
- }
- return 0;
- }
-
- /***
- *int streambuf::allocate() -
- *
- *Purpose:
- * Tries to set up a Reserve Area. If one already exists, or if
- * unbuffered, just returns 0.
- *
- *Entry:
- *
- *Exit:
- *
- *Exceptions:
- *
- *******************************************************************************/
-
- int streambuf::allocate()
- {
- if ((_fUnbuf) || (_base))
- return 0;
- if (doallocate()==EOF) return EOF;
-
- return(1);
- }
-
- /***
- *virtual int streambuf::doallocate() -
- *
- *Purpose:
- * Tries to set up a Reserve Area. Returns EOF if unsuccessful.
- *
- *Entry:
- *
- *Exit:
- *
- *Exceptions:
- *
- *******************************************************************************/
-
- int streambuf::doallocate()
- {
- char * tptr;
- if (!( tptr = _new_crt char[BUFSIZ]))
- return(EOF);
- setb(tptr, tptr + BUFSIZ, 1);
- return(1);
- }
-
- /***
- *void streambuf::setb(char * b, char * eb, int a = 0) -
- *
- *Purpose:
- * Sets up reserve area.
- *
- *Entry:
- *
- *Exit:
- *
- *Exceptions:
- *
- *******************************************************************************/
-
- void streambuf::setb(char * b, char * eb, int a )
- {
- if ((_fAlloc) && (_base))
- delete _base;
- _base = b;
- _fAlloc = a;
- _ebuf = eb;
- }
-
- /***
- *virtual streampos streambuf::seekoff(streamoff off, ios::seekdir dir, int mode)
- *
- *Purpose:
- * seekoff member function. seek forward or backward in the stream.
- * Default behavior: returns EOF.
- *
- *Entry:
- * off = offset (+ or -) to seek by
- * dir = one of ios::beg, ios::end, or ios::cur.
- * mode = ios::in or ios::out.
- *
- *Exit:
- * Returns new file position or EOF if error or seeking not supported.
- *
- *Exceptions:
- * Returns EOF if error.
- *
- *******************************************************************************/
- streampos streambuf::seekoff(streamoff,ios::seek_dir,int)
- {
- return EOF;
- }
-
- /***
- *virtual streampos streambuf::seekpos(streampos pos, int mode) -
- *
- *Purpose:
- * seekoff member function. seek to absolute file position.
- * Default behavior: returns seekoff(streamoff(pos), ios::beg, mode).
- *
- *Entry:
- * pos = absolute offset to seek to
- * mode = ios::in or ios::out.
- *
- *Exit:
- * Returns new file position or EOF if error or seeking not supported.
- *
- *Exceptions:
- * Returns EOF if error.
- *
- *******************************************************************************/
- streampos streambuf::seekpos(streampos pos,int mode)
- {
- return seekoff(streamoff(pos), ios::beg, mode);
- }
-
- /***
- *virtual int streambuf::pbackfail(int c) - handle failure of putback
- *
- *Purpose:
- * pbackfail member function. Handle exception of pback function.
- * Default behavior: returns EOF. See spec. for details.
- *
- * Note: the following implementation gives default behavior, thanks
- * to the default seekoff, but also supports derived classes properly:
- *
- *Entry:
- * c = character to put back
- *
- *Exit:
- * Returns c if successful or EOF on error.
- *
- *Exceptions:
- * Returns EOF if error. Behavior is undefined if c was not the
- * previous character in the stream.
- *
- *******************************************************************************/
- int streambuf::pbackfail(int c)
- {
- if (eback()<gptr()) return sputbackc((char)c);
-
- if (seekoff( -1, ios::cur, ios::in)==EOF) // always EOF for streambufs
- return EOF;
- if (!unbuffered() && egptr())
- {
- memmove((gptr()+1),gptr(),(egptr()-(gptr()+1)));
- *gptr()=(char)c;
- }
- return(c);
- }
-