Lunchbox  1.4.0
buffer.h
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