Lunchbox
1.6.0
|
00001 00002 /* Copyright (c) 2007-2012, Stefan Eilemann <eile@equalizergraphics.com> 00003 * 2011-2012, Daniel Nachbaur <danielnachbaur@gmail.com> 00004 * 00005 * This library is free software; you can redistribute it and/or modify it under 00006 * the terms of the GNU Lesser General Public License version 2.1 as published 00007 * by the Free Software Foundation. 00008 * 00009 * This library is distributed in the hope that it will be useful, but WITHOUT 00010 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 00011 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 00012 * details. 00013 * 00014 * You should have received a copy of the GNU Lesser General Public License 00015 * along with this library; if not, write to the Free Software Foundation, Inc., 00016 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 00017 */ 00018 00019 #ifndef LUNCHBOX_BUFFER_H 00020 #define LUNCHBOX_BUFFER_H 00021 00022 #include <lunchbox/debug.h> // LBASSERT macro 00023 #include <lunchbox/types.h> 00024 00025 #include <cstdlib> // for malloc 00026 #include <cstring> // for memcpy 00027 00028 namespace lunchbox 00029 { 00040 template< class T > class Buffer 00041 { 00042 public: 00044 Buffer() : _data(0), _size(0), _maxSize(0) {} 00045 00047 Buffer( const uint64_t size ) : _data(0), _size(0), _maxSize(0) 00048 { reset( size ); } 00049 00051 Buffer( Buffer& from ) 00052 { 00053 _data = from._data; _size = from._size; _maxSize =from._maxSize; 00054 from._data = 0; from._size = 0; from._maxSize = 0; 00055 } 00056 00058 ~Buffer() { clear(); } 00059 00061 void clear() 00062 { if( _data ) free( _data ); _data=0; _size=0; _maxSize=0; } 00063 00069 T* pack() 00070 { 00071 if( _maxSize != _size ) 00072 { 00073 _data = static_cast< T* >( realloc( _data, 00074 _size * sizeof( T ))); 00075 _maxSize = _size; 00076 } 00077 return _data; 00078 } 00079 00081 const Buffer& operator = ( const Buffer& from ) 00082 { 00083 replace( from ); 00084 return *this; 00085 } 00086 00088 T& operator [] ( const uint64_t position ) 00089 { LBASSERT( _size > position ); return _data[ position ]; } 00090 00092 const T& operator [] ( const uint64_t position ) const 00093 { LBASSERT( _size > position ); return _data[ position ]; } 00094 00102 T* resize( const uint64_t newSize ) 00103 { 00104 _size = newSize; 00105 if( newSize <= _maxSize ) 00106 return _data; 00107 00108 // avoid excessive reallocs 00109 const uint64_t nElems = newSize + (newSize >> 3); 00110 const uint64_t nBytes = nElems * sizeof( T ); 00111 _data = static_cast< T* >( realloc( _data, nBytes )); 00112 _maxSize = nElems; 00113 return _data; 00114 } 00115 00122 void grow( const uint64_t newSize ) 00123 { 00124 if( newSize > _size ) 00125 resize( newSize ); 00126 } 00127 00135 T* reserve( const uint64_t newSize ) 00136 { 00137 if( newSize <= _maxSize ) 00138 return _data; 00139 00140 _data = static_cast< T* >( realloc( _data, newSize*sizeof(T))); 00141 _maxSize = newSize; 00142 return _data; 00143 } 00144 00152 T* reset( const uint64_t newSize ) 00153 { 00154 reserve( newSize ); 00155 setSize( newSize ); 00156 return _data; 00157 } 00158 00160 void append( const T* data, const uint64_t size ) 00161 { 00162 LBASSERT( data ); 00163 LBASSERT( size ); 00164 00165 const uint64_t oldSize = _size; 00166 resize( oldSize + size ); 00167 memcpy( _data + oldSize, data, size * sizeof( T )); 00168 } 00169 00171 void append( const T& element ) 00172 { 00173 resize( _size + 1 ); 00174 _data[ _size - 1 ] = element; 00175 } 00176 00178 void replace( const void* data, const uint64_t size ) 00179 { 00180 LBASSERT( data ); 00181 LBASSERT( size ); 00182 00183 reserve( size ); 00184 memcpy( _data, data, size * sizeof( T )); 00185 _size = size; 00186 } 00187 00189 void replace( const Buffer& from ) 00190 { replace( from._data, from._size ); } 00191 00193 void swap( Buffer& buffer ) 00194 { 00195 T* tmpData = buffer._data; 00196 const uint64_t tmpSize = buffer._size; 00197 const uint64_t tmpMaxSize = buffer._maxSize; 00198 00199 buffer._data = _data; 00200 buffer._size = _size; 00201 buffer._maxSize = _maxSize; 00202 00203 _data = tmpData; 00204 _size = tmpSize; 00205 _maxSize = tmpMaxSize; 00206 } 00207 00209 T* getData() { return _data; } 00210 00212 const T* getData() const { return _data; } 00213 00222 bool setSize( const uint64_t size ) 00223 { 00224 LBASSERT( size <= _maxSize ); 00225 if( size > _maxSize ) 00226 return false; 00227 00228 _size = size; 00229 return true; 00230 } 00231 00233 uint64_t getSize() const { return _size; } 00234 00236 uint64_t getNumBytes() const { return _size * sizeof( T ); } 00237 00239 bool isEmpty() const { return (_size==0); } 00240 00242 uint64_t getMaxSize() const { return _maxSize; } 00243 00244 private: 00246 T* _data; 00247 00249 uint64_t _size; 00250 00252 uint64_t _maxSize; 00253 }; 00254 } 00255 #endif //LUNCHBOX_BUFFER_H