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