|
|
// strstreambuf -- strstreambuf basic members
#include <climits>
#include <cstdlib>
#include <cstring>
#include <strstream>
#include <xdebug>
#pragma warning(disable:4244 4097)
_STD_BEGIN
_CRTIMP2 istrstream::~istrstream() { // destroy an istrstream
}
_CRTIMP2 ostrstream::ostrstream(char *ptr, streamsize count, ios_base::openmode mode) : ostream(&_Mysb), _Mysb(ptr, count, ptr == 0 || (mode & app) == 0 ? ptr : ptr + strlen(ptr)) { // construct with [ptr, ptr + count)
}
_CRTIMP2 ostrstream::~ostrstream() { // destroy an ostrstream
}
_CRTIMP2 strstream::strstream(char *ptr, streamsize count, ios_base::openmode mode) : iostream(&_Mysb), _Mysb(ptr, count, ptr == 0 || (mode & app) == 0 ? ptr : ptr + strlen(ptr)) { // construct with [ptr, ptr + count)
}
_CRTIMP2 strstream::~strstream() { // destroy a strstream
}
_CRTIMP2 strstreambuf::~strstreambuf() { // destroy a strstreambuf
_Tidy(); }
_CRTIMP2 void strstreambuf::freeze(bool freezeit) { // freeze or unfreeze writing
if (freezeit && !(_Strmode & _Frozen)) { // disable writing
_Strmode |= _Frozen; _Pendsave = epptr(); setp(pbase(), pptr(), eback()); } else if (!freezeit && _Strmode & _Frozen) { // re-enable writing
_Strmode &= ~_Frozen; setp(pbase(), pptr(), _Pendsave); } }
_CRTIMP2 int strstreambuf::overflow(int meta) { // try to extend write area
if (meta == EOF) return (0); // nothing to write
else if (pptr() != 0 && pptr() < epptr()) return ((unsigned char)(*_Pninc() = meta)); // room in buffer
else if (!(_Strmode & _Dynamic) || _Strmode & (_Constant | _Frozen)) return (EOF); // can't extend
else { // okay to extend
int oldsize = gptr() == 0 ? 0 : epptr() - eback(); int newsize = oldsize; int inc = newsize / 2 < _Minsize ? _Minsize : newsize / 2; // grow by 50 per cent if possible
_Minsize = _MINSIZE; // back to default for future growth
char *ptr = 0;
while (0 < inc && INT_MAX - inc < newsize) inc /= 2; // reduce growth increment if too big
if (0 < inc) { // room to grow, increase size
newsize += inc; ptr = _Palloc != 0 ? (char *)(*_Palloc)(newsize) : _NEW_CRT char[newsize]; } if (ptr == 0) return (EOF); // couldn't grow, return failure
if (0 < oldsize) memcpy(ptr, eback(), oldsize); // copy existing buffer
if (!(_Strmode & _Allocated)) ; // no buffer to free
else if (_Pfree != 0) (*_Pfree)(eback()); // free with function call
else _DELETE_CRT_VEC(eback()); // free by deleting array
_Strmode |= _Allocated; if (oldsize == 0) { // set up new buffer
_Seekhigh = ptr; setp(ptr, ptr + newsize); setg(ptr, ptr, ptr); } else { // revise old pointers
_Seekhigh = _Seekhigh - eback() + ptr; setp(pbase() - eback() + ptr, pptr() - eback() + ptr, ptr + newsize); setg(ptr, gptr() - eback() + ptr, pptr() + 1); }
return ((unsigned char)(*_Pninc() = meta)); } }
_CRTIMP2 int strstreambuf::pbackfail(int meta) { // try to putback a character
if (gptr() == 0 || gptr() <= eback() || meta != EOF && (unsigned char)meta != (unsigned char)gptr()[-1] && _Strmode & _Constant) return (EOF); // can't put it back
else { // safe to back up
gbump(-1); return (meta == EOF ? 0 : (unsigned char)(*gptr() = meta)); } }
_CRTIMP2 int strstreambuf::underflow() { // read if read position available
if (gptr() == 0) return (EOF); // no read buffer
else if (gptr() < egptr()) return ((unsigned char)*gptr()); // char in buffer, read it
else if (pptr() == 0 || pptr() <= gptr() && _Seekhigh <= gptr()) return (EOF); // no write buffer to read
else { // update _Seekhigh and expand read region
if (_Seekhigh < pptr()) _Seekhigh = pptr(); setg(eback(), gptr(), _Seekhigh); return ((unsigned char)*gptr()); } }
_CRTIMP2 streampos strstreambuf::seekoff(streamoff off, ios_base::seekdir way, ios_base::openmode which) { // seek by specified offset
if (pptr() != 0 && _Seekhigh < pptr()) _Seekhigh = pptr(); // update high water mark
if (which & ios_base::in && gptr() != 0) { // set input (and maybe output) pointer
if (way == ios_base::end) off += _Seekhigh - eback(); // seek from end
else if (way == ios_base::cur && !(which & ios_base::out)) off += gptr() - eback(); // seek from current position
else if (way != ios_base::beg || off == _BADOFF) off = _BADOFF; // invalid seek
if (0 <= off && off <= _Seekhigh - eback()) { // seek from beginning, set one or two pointers
gbump(eback() - gptr() + off); if (which & ios_base::out && pptr() != 0) setp(pbase(), gptr(), epptr()); } else off = _BADOFF; // invalid seek from beginning
} else if (which & ios_base::out && pptr() != 0) { // set only output pointer
if (way == ios_base::end) off += _Seekhigh - eback(); // seek from end
else if (way == ios_base::cur) off += pptr() - eback(); // seek from current position
else if (way != ios_base::beg || off == _BADOFF) off = _BADOFF; // invalid seek
if (0 <= off && off <= _Seekhigh - eback()) pbump(eback() - pptr() + off); // seek from beginning
else off = _BADOFF; // invalid seek from beginning
} else // nothing to set
off = _BADOFF; return (streampos(off)); }
_CRTIMP2 streampos strstreambuf::seekpos(streampos sp, ios_base::openmode which) { // seek to memorized position
streamoff off = (streamoff)sp; if (pptr() != 0 && _Seekhigh < pptr()) _Seekhigh = pptr(); // update high water mark
if (off == _BADOFF) ; // invalid seek
else if (which & ios_base::in && gptr() != 0) { // set input (and maybe output) pointer
if (0 <= off && off <= _Seekhigh - eback()) { // set valid offset
gbump(eback() - gptr() + off); if (which & ios_base::out && pptr() != 0) setp(pbase(), gptr(), epptr()); } else off = _BADOFF; // offset invalid, don't seek
} else if (which & ios_base::out && pptr() != 0) { // set output pointer
if (0 <= off && off <= _Seekhigh - eback()) pbump(eback() - pptr() + off); else off = _BADOFF; // offset invalid, don't seek
} else // nothing to set
off = _BADOFF; return (streampos(off)); }
_CRTIMP2 void strstreambuf::_Init(streamsize count, char *gp, char *pp, _Strstate mode) { // initialize with possibly static buffer
streambuf::_Init(); _Minsize = _MINSIZE; _Pendsave = 0; _Seekhigh = 0; _Palloc = 0; _Pfree = 0; _Strmode = mode;
if (gp == 0) { // make dynamic
_Strmode |= _Dynamic; if (_Minsize < count) _Minsize = count; } else { // make static
int size = count < 0 ? INT_MAX : count == 0 ? (int)strlen(gp) : count; _Seekhigh = gp + size;
if (pp == 0) setg(gp, gp, gp + size); // set read pointers only
else { // make writable too
if (pp < gp) pp = gp; else if (gp + size < pp) pp = gp + size; setp(pp, gp + size); setg(gp, gp, pp); } } }
_CRTIMP2 void strstreambuf::_Tidy() { // free any allocated storage
if ((_Strmode & (_Allocated | _Frozen)) != _Allocated) ; // no buffer to free
else if (_Pfree != 0) (*_Pfree)(eback()); // free with function call
else _DELETE_CRT_VEC(eback()); // free by deleting array
_Seekhigh = 0; _Strmode &= ~(_Allocated | _Frozen); } _STD_END
/*
* Copyright (c) 1992-2001 by P.J. Plauger. ALL RIGHTS RESERVED. * Consult your license regarding permissions and restrictions. V3.10:0009 */
|