00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef INDRI_BUFFER_HPP
00020 #define INDRI_BUFFER_HPP
00021
00022 #include <assert.h>
00023 #include "lemur-compat.hpp"
00024
00025 class Buffer {
00026 private:
00027 char* _buffer;
00028 size_t _size;
00029 size_t _position;
00030
00031 public:
00032 Buffer() :
00033 _buffer(0),
00034 _size(0),
00035 _position(0)
00036 {
00037 }
00038
00039 ~Buffer() {
00040 free( _buffer );
00041 }
00042
00043 size_t size() const {
00044 return _size;
00045 }
00046
00047 size_t position() const {
00048 return _position;
00049 }
00050
00051 void clear() {
00052 _position = 0;
00053 }
00054
00055 char* front() {
00056 return _buffer;
00057 }
00058
00059 char* write( size_t length ) {
00060 grow( _position + length );
00061 char* spot = _buffer + _position;
00062 _position += length;
00063 return spot;
00064 }
00065
00066 void unwrite( size_t length ) {
00067 assert( length <= _position );
00068 _position -= length;
00069 }
00070
00071 void grow( size_t newSize ) {
00072 if( newSize > _size ) {
00073 if( newSize < 1024*1024 ) {
00074
00075 size_t powSize;
00076 for( powSize = 64; powSize < newSize; powSize *= 2 )
00077 ;
00078 newSize = powSize;
00079 } else {
00080
00081 newSize = (newSize + 1024*1024) & ~(1024*1024-1);
00082 }
00083
00084 char* newBuffer = (char*) malloc( newSize );
00085 memcpy( newBuffer, _buffer, _position );
00086 free( _buffer );
00087 _buffer = newBuffer;
00088 _size = newSize;
00089 }
00090 }
00091
00092 void grow() {
00093 if( _size == 0 )
00094 grow(64);
00095 else
00096 grow(_size*2);
00097 }
00098
00099 void remove( size_t start ) {
00100 memmove( _buffer, _buffer + start, _position - start );
00101 _position -= start;
00102 }
00103
00104 void detach() {
00105 _size = 0;
00106 _buffer = 0;
00107 }
00108 };
00109
00110 #endif // INDRI_BUFFER_HPP