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