// strstreambuf -- strstreambuf basic members #include #include #include #include #include _STD_BEGIN _CRTIMP2 istrstream::~istrstream() { // destruct an istrstream } _CRTIMP2 ostrstream::ostrstream(char *s, streamsize n, openmode mode) : ostream(&_Sb), _Sb(s, n, s == 0 || (mode & app) == 0 ? s : s + strlen(s)) { // write at terminating null (if there) } _CRTIMP2 ostrstream::~ostrstream() { // destruct an ostrstream } _CRTIMP2 strstream::strstream(char *s, streamsize n, openmode mode) : iostream(&_Sb), _Sb(s, n, s == 0 || (mode & app) == 0 ? s : s + strlen(s)) { // write at terminating null (if there) } _CRTIMP2 strstream::~strstream() { // destruct a strstream } _CRTIMP2 strstreambuf::~strstreambuf() { // destruct a strstreambuf _Tidy(); } _CRTIMP2 void strstreambuf::freeze(bool freezeit) { // freeze a dynamic string 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 ch) { // try to extend write area if (ch == EOF) return (0); else if (pptr() != 0 && pptr() < epptr()) return ((unsigned char)(*_Pninc() = (char)ch)); else if (!(_Strmode & _Dynamic) || _Strmode & (_Constant | _Frozen)) return (EOF); else { // okay to extend int osize = gptr() == 0 ? 0 : epptr() - eback(); int nsize = osize + _Alsize; char *p = _Palloc != 0 ? (char *)(*_Palloc)(nsize) : new char[nsize]; if (p == 0) return (EOF); if (0 < osize) memcpy(p, eback(), osize); else if (_ALSIZE < _Alsize) _Alsize = _ALSIZE; if (!(_Strmode & _Allocated)) ; else if (_Pfree != 0) (*_Pfree)(eback()); else delete[] eback(); _Strmode |= _Allocated; if (osize == 0) { // setup new buffer _Seekhigh = p; setp(p, p + nsize); setg(p, p, p); } else { // revise old pointers _Seekhigh = _Seekhigh - eback() + p; setp(pbase() - eback() + p, pptr() - eback() + p, p + nsize); setg(p, gptr() - eback() + p, pptr() + 1); } return ((unsigned char)(*_Pninc() = (char)ch)); } } _CRTIMP2 int strstreambuf::pbackfail(int ch) { // try to putback a character if (gptr() == 0 || gptr() <= eback() || ch != EOF && (unsigned char)ch != (unsigned char)gptr()[-1] && _Strmode & _Constant) return (EOF); else { // safe to back up gbump(-1); return (ch == EOF ? 0 : (unsigned char)(*gptr() = (char)ch)); } } _CRTIMP2 int strstreambuf::underflow() { // read only if read position available if (gptr() == 0) return (EOF); else if (gptr() < egptr()) return ((unsigned char)*gptr()); else if (pptr() == 0 || pptr() <= gptr() && _Seekhigh <= gptr()) return (EOF); 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::seekdir way, ios::openmode which) { // seek by specified offset if (pptr() != 0 && _Seekhigh < pptr()) _Seekhigh = pptr(); if (which & ios::in && gptr() != 0) { // set input (and maybe output) pointer if (way == ios::end) off += _Seekhigh - eback(); else if (way == ios::cur && !(which & ios::out)) off += gptr() - eback(); else if (way != ios::beg || off == _BADOFF) off = _BADOFF; if (0 <= off && off <= _Seekhigh - eback()) { // set one or two pointers gbump(eback() - gptr() + off); if (which & ios::out && pptr() != 0) setp(pbase(), gptr(), epptr()); } else off = _BADOFF; } else if (which & ios::out && pptr() != 0) { // set only output pointer if (way == ios::end) off += _Seekhigh - eback(); else if (way == ios::cur) off += pptr() - eback(); else if (way != ios::beg || off == _BADOFF) off = _BADOFF; if (0 <= off && off <= _Seekhigh - eback()) pbump(eback() - pptr() + off); else off = _BADOFF; } else // nothing to set off = _BADOFF; return (streampos(off)); } _CRTIMP2 streampos strstreambuf::seekpos(streampos sp, ios::openmode which) { // seek to memorized position streamoff off = (streamoff)sp; if (pptr() != 0 && _Seekhigh < pptr()) _Seekhigh = pptr(); if (off == _BADOFF) ; else if (which & ios::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::out && pptr() != 0) setp(pbase(), gptr(), epptr()); } else off = _BADOFF; } else if (which & ios::out && pptr() != 0) { // set output pointer if (0 <= off && off <= _Seekhigh - eback()) pbump(eback() - pptr() + off); else off = _BADOFF; } else // nothing to set off = _BADOFF; return (streampos(off)); } _CRTIMP2 void strstreambuf::_Init(int n, char *gp, char *pp, _Strstate mode) { // initialize with possibly static buffer streambuf::_Init(); _Pendsave = 0; _Seekhigh = 0; _Palloc = 0; _Pfree = 0; _Strmode = mode; if (gp == 0) { // make dynamic _Alsize = _MINSIZE <= n ? n : _ALSIZE; _Strmode |= _Dynamic; } else { // make static int size = n < 0 ? INT_MAX : n == 0 ? strlen(gp) : n; _Alsize = 0; _Seekhigh = gp + size; if (pp == 0) setg(gp, gp, gp + size); 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() { // discard any allocated storage if ((_Strmode & (_Allocated | _Frozen)) != _Allocated) ; else if (_Pfree != 0) (*_Pfree)(eback()); else delete[] eback(); _Seekhigh = 0; _Strmode &= ~(_Allocated | _Frozen); } _STD_END /* * Copyright (c) 1994 by P.J. Plauger. ALL RIGHTS RESERVED. * Consult your license regarding permissions and restrictions. */