00001 /*========================================================================== 00002 * Copyright (c) 2004 University of Massachusetts. All Rights Reserved. 00003 * 00004 * Use of the Lemur Toolkit for Language Modeling and Information Retrieval 00005 * is subject to the terms of the software license set forth in the LICENSE 00006 * file included with this software, and also available at 00007 * http://www.lemurproject.org/license.html 00008 * 00009 *========================================================================== 00010 */ 00011 00012 00013 // 00014 // Buffer 00015 // 00016 // 14 May 2004 -- tds 00017 // 00018 00019 #ifndef INDRI_BUFFER_HPP 00020 #define INDRI_BUFFER_HPP 00021 00022 #include <assert.h> 00023 #include "lemur-compat.hpp" 00024 namespace indri 00025 { 00027 namespace utility 00028 { 00029 00030 class Buffer { 00031 private: 00032 char* _buffer; 00033 size_t _size; 00034 size_t _position; 00035 00036 public: 00037 Buffer( size_t length ) : 00038 _buffer( (char*) malloc( length ) ), 00039 _size( length ), 00040 _position(0) 00041 { 00042 } 00043 00044 Buffer() : 00045 _buffer(0), 00046 _size(0), 00047 _position(0) 00048 { 00049 } 00050 00051 ~Buffer() { 00052 free( _buffer ); 00053 } 00054 00055 inline size_t size() const { 00056 return _size; 00057 } 00058 00059 inline size_t position() const { 00060 return _position; 00061 } 00062 00063 inline void clear() { 00064 _position = 0; 00065 } 00066 00067 inline char* front() { 00068 return _buffer; 00069 } 00070 00071 inline char* write( size_t length ) { 00072 if( _position + length > _size ) 00073 grow( _position + length ); 00074 char* spot = _buffer + _position; 00075 _position += length; 00076 return spot; 00077 } 00078 00079 inline void unwrite( size_t length ) { 00080 assert( length >= 0 ); 00081 assert( length <= _position ); 00082 _position -= length; 00083 } 00084 00085 void grow( size_t newSize ) { 00086 if( newSize > _size ) { 00087 if( newSize < 1024*1024 ) { 00088 // find next larger power of two, up to one megabyte 00089 size_t powSize; 00090 for( powSize = 64; powSize < newSize; powSize *= 2 ) 00091 ; 00092 newSize = powSize; 00093 } else { 00094 // round to nearest megabyte 00095 newSize = (newSize + 1024*1024) & ~(1024*1024-1); 00096 } 00097 00098 char* newBuffer = (char*) malloc( newSize ); 00099 memcpy( newBuffer, _buffer, _position ); 00100 free( _buffer ); 00101 _buffer = newBuffer; 00102 _size = newSize; 00103 } 00104 } 00105 00106 void grow() { 00107 if( _size == 0 ) 00108 grow(64); 00109 else 00110 grow(_size*2); 00111 } 00112 00113 size_t remaining() { 00114 return size() - position(); 00115 } 00116 00117 void remove( size_t start ) { 00118 memmove( _buffer, _buffer + start, _position - start ); 00119 _position -= start; 00120 } 00121 00122 void detach() { 00123 _size = 0; 00124 _buffer = 0; 00125 } 00126 }; 00127 } 00128 } 00129 00130 #endif // INDRI_BUFFER_HPP