/* * Copyright (c) 1996 Gunther Schadow. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef _BUFFER_H #define _BUFFER_H #pragma interface #include /* class Buffer -- a multi purpose dynamic stretch-and-shrink buffer |<--------------------------- size ------------------------------>| |Chunk0 |Chunk1 | base|................................|................................| ^ ^ ^ ^ base get-pointer get-end put-pointer When the get pointer passes a chunk boundary, the buffer memory is shrunk, so that the lower chunk is thrown away, and the buffers new base is the start of the next chunk. When the put-pointer gets beyond the upper boundary, the memory is stretched by the amount of a new chunk. The two differend pointers for end of readable space and put pointer exist to allow data to be stored in the buffer, that might still be changed before consumption is appropriate. This is particularly useful for an intermediate transport protocol. */ class Buffer { private: char *_base; char *_poi; char *_end; char *_ppoi; size_t _size; const size_t chunksize = 1024; public: Buffer(); // don't allocate memory yet Buffer(size_t size); // allocate a minimum of size Buffer(const char *buf, size_t len); // initialize buffer with contents virtual ~Buffer(); char *base() const { return _base; } // current base of buffer size_t size() const { return _size; } // get current max size of buffer // for get public: char *poi() const { return _poi; } // current pointer for get char *end() const { return _end; } // current end for get size_t len() const { return _end - _poi; } // current length for get size_t get(char *buf, size_t max); // get at most max bytes int get(); // get one byte void unget(); // put back one byte size_t discard(size_t max); // discard at most max bytes private: void lshrink(); // for put public: size_t pcnt() const { return _ppoi-_end; } // amount of new data char *ppoi() const { return _ppoi; } // current pointer for put void put(const char *buf, size_t len); // put len bytes void put(char); // put one byte void trunc(char *pos); // discard new data after pos void setend(char *pos); // set end pointer to pos private: char *ppoi(size_t s); // return current end with min s of following space void hshrink(); }; inline void Buffer::put(char c) // put one byte { *(ppoi(1)) = c; } inline int Buffer::get() // get next byte return -1 if none was left. // don't shrink buffer for ungetch(). { return _poi < _end ? *(_poi++) : -1; } inline void Buffer::unget() // put back one byte { if(_poi > _base) _poi--; } #endif