Lunchbox  1.8.0
buffer.h
1 
2 /* Copyright (c) 2007-2012, Stefan Eilemann <eile@equalizergraphics.com>
3  * 2011-2012, Daniel Nachbaur <danielnachbaur@gmail.com>
4  *
5  * This library is free software; you can redistribute it and/or modify it under
6  * the terms of the GNU Lesser General Public License version 2.1 as published
7  * by the Free Software Foundation.
8  *
9  * This library is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11  * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12  * details.
13  *
14  * You should have received a copy of the GNU Lesser General Public License
15  * along with this library; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17  */
18 
19 #ifndef LUNCHBOX_BUFFER_H
20 #define LUNCHBOX_BUFFER_H
21 
22 #include <lunchbox/debug.h> // LBASSERT macro
23 #include <lunchbox/types.h>
24 
25 #include <cstdlib> // for malloc
26 #include <cstring> // for memcpy
27 
28 namespace lunchbox
29 {
40  template< class T > class Buffer
41  {
42  public:
44  Buffer() : _data(0), _size(0), _maxSize(0) {}
45 
47  Buffer( const uint64_t size ) : _data(0), _size(0), _maxSize(0)
48  { reset( size ); }
49 
51  Buffer( Buffer& from )
52  {
53  _data = from._data; _size = from._size; _maxSize =from._maxSize;
54  from._data = 0; from._size = 0; from._maxSize = 0;
55  }
56 
58  ~Buffer() { clear(); }
59 
61  void clear()
62  { if( _data ) free( _data ); _data=0; _size=0; _maxSize=0; }
63 
69  T* pack()
70  {
71  if( _maxSize != _size )
72  {
73  _data = static_cast< T* >( realloc( _data,
74  _size * sizeof( T )));
75  _maxSize = _size;
76  }
77  return _data;
78  }
79 
81  const Buffer& operator = ( const Buffer& from )
82  {
83  replace( from );
84  return *this;
85  }
86 
88  T& operator [] ( const uint64_t position )
89  { LBASSERT( _size > position ); return _data[ position ]; }
90 
92  const T& operator [] ( const uint64_t position ) const
93  { LBASSERT( _size > position ); return _data[ position ]; }
94 
102  T* resize( const uint64_t newSize )
103  {
104  _size = newSize;
105  if( newSize <= _maxSize )
106  return _data;
107 
108  // avoid excessive reallocs
109  const uint64_t nElems = newSize + (newSize >> 3);
110  const uint64_t nBytes = nElems * sizeof( T );
111  _data = static_cast< T* >( realloc( _data, nBytes ));
112  _maxSize = nElems;
113  return _data;
114  }
115 
122  void grow( const uint64_t newSize )
123  {
124  if( newSize > _size )
125  resize( newSize );
126  }
127 
135  T* reserve( const uint64_t newSize )
136  {
137  if( newSize <= _maxSize )
138  return _data;
139 
140  _data = static_cast< T* >( realloc( _data, newSize*sizeof(T)));
141  _maxSize = newSize;
142  return _data;
143  }
144 
152  T* reset( const uint64_t newSize )
153  {
154  reserve( newSize );
155  setSize( newSize );
156  return _data;
157  }
158 
160  void append( const T* data, const uint64_t size )
161  {
162  LBASSERT( data );
163  LBASSERT( size );
164 
165  const uint64_t oldSize = _size;
166  resize( oldSize + size );
167  memcpy( _data + oldSize, data, size * sizeof( T ));
168  }
169 
171  void append( const T& element )
172  {
173  resize( _size + 1 );
174  _data[ _size - 1 ] = element;
175  }
176 
178  void replace( const void* data, const uint64_t size )
179  {
180  LBASSERT( data );
181  LBASSERT( size );
182 
183  reserve( size );
184  memcpy( _data, data, size * sizeof( T ));
185  _size = size;
186  }
187 
189  void replace( const Buffer& from )
190  { replace( from._data, from._size ); }
191 
193  void swap( Buffer& buffer )
194  {
195  T* tmpData = buffer._data;
196  const uint64_t tmpSize = buffer._size;
197  const uint64_t tmpMaxSize = buffer._maxSize;
198 
199  buffer._data = _data;
200  buffer._size = _size;
201  buffer._maxSize = _maxSize;
202 
203  _data = tmpData;
204  _size = tmpSize;
205  _maxSize = tmpMaxSize;
206  }
207 
209  T* getData() { return _data; }
210 
212  const T* getData() const { return _data; }
213 
222  bool setSize( const uint64_t size )
223  {
224  LBASSERT( size <= _maxSize );
225  if( size > _maxSize )
226  return false;
227 
228  _size = size;
229  return true;
230  }
231 
233  uint64_t getSize() const { return _size; }
234 
236  uint64_t getNumBytes() const { return _size * sizeof( T ); }
237 
239  bool isEmpty() const { return (_size==0); }
240 
242  uint64_t getMaxSize() const { return _maxSize; }
243 
244  private:
246  T* _data;
247 
249  uint64_t _size;
250 
252  uint64_t _maxSize;
253  };
254 }
255 #endif //LUNCHBOX_BUFFER_H