Line data Source code
1 :
2 : /* Copyright (c) 2007-2014, 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/os.h> // setZero used inline
24 : #include <lunchbox/types.h>
25 :
26 : #include <cstdlib> // for malloc
27 : #include <cstring> // for memcpy
28 :
29 : namespace lunchbox
30 : {
31 : /**
32 : * A simple memory buffer with some helper functions.
33 : *
34 : * std::vector does not implement optimizations for growing bitwise-movable
35 : * vectors, i.e., it copy-constructs each element on growth.
36 : *
37 : * This buffer just memcpy's elements, i.e., it should only be used for PODs
38 : * since the copy constructor or assignment operator is not called on the copied
39 : * elements. Primarily used for binary data, e.g., in eq::Image. The
40 : * implementation works like a pool, that is, data is only released when the
41 : * buffer is deleted or clear() is called.
42 : */
43 : template< class T > class Buffer
44 : {
45 : public:
46 : /** Construct a new, empty buffer. @version 1.0 */
47 718 : Buffer() : _data(0), _size(0), _maxSize(0) {}
48 :
49 : /** Construct a new buffer of the given size. @version 1.0 */
50 : explicit Buffer( const uint64_t size ) : _data(0), _size(0), _maxSize(0)
51 : { reset( size ); }
52 :
53 : /** "Move" constructor, transfers ownership to new Buffer. @version 1.0 */
54 : explicit Buffer( Buffer& from );
55 :
56 : /** Destruct the buffer. @version 1.0 */
57 718 : ~Buffer() { clear(); }
58 :
59 : /** Flush the buffer, deleting all data. @version 1.0 */
60 718 : void clear() { if( _data ) free( _data ); _data=0; _size=0; _maxSize=0; }
61 :
62 : /**
63 : * Tighten the allocated memory to the size of the buffer.
64 : * @return the new pointer to the first element.
65 : * @version 1.0
66 : */
67 : T* pack();
68 :
69 : /** Assignment operator, copies data from Buffer. @version 1.0 */
70 : Buffer& operator = ( const Buffer& from );
71 :
72 : /** Direct access to the element at the given index. @version 1.0 */
73 : T& operator [] ( const uint64_t position )
74 : { LBASSERT( _size > position ); return _data[ position ]; }
75 :
76 : /** Direct const access to an element. @version 1.0 */
77 : const T& operator [] ( const uint64_t position ) const
78 : { LBASSERT( _size > position ); return _data[ position ]; }
79 :
80 : /**
81 : * Ensure that the buffer contains at least newSize elements.
82 : *
83 : * Existing data is retained. The size is set.
84 : * @return the new pointer to the first element.
85 : * @version 1.0
86 : */
87 : T* resize( const uint64_t newSize );
88 :
89 : /**
90 : * Ensure that the buffer contains at least newSize elements.
91 : *
92 : * Existing data is retained. The size is increased, if necessary.
93 : * @version 1.0
94 : */
95 : void grow( const uint64_t newSize );
96 :
97 : /**
98 : * Ensure that the buffer contains at least newSize elements.
99 : *
100 : * Existing data is preserved.
101 : * @return the new pointer to the first element.
102 : * @version 1.0
103 : */
104 : T* reserve( const uint64_t newSize );
105 :
106 : /**
107 : * Set the buffer size and malloc enough memory.
108 : *
109 : * Existing data may be deleted.
110 : * @return the new pointer to the first element.
111 : * @version 1.0
112 : */
113 : T* reset( const uint64_t newSize );
114 :
115 : /** Set the buffer content to 0. @version 1.9.1 */
116 : void setZero() { ::lunchbox::setZero( _data, _size ); }
117 :
118 : /** Append elements to the buffer, increasing the size. @version 1.0 */
119 : void append( const T* data, const uint64_t size );
120 :
121 : /** Append one element to the buffer. @version 1.0 */
122 : void append( const T& element );
123 :
124 : /** Replace the existing data with new data. @version 1.0 */
125 : void replace( const void* data, const uint64_t size );
126 :
127 : /** Replace the existing data. @version 1.5.1 */
128 : void replace( const Buffer& from ) { replace( from._data, from._size ); }
129 :
130 : /** Swap the buffer contents with another Buffer. @version 1.0 */
131 : void swap( Buffer& buffer );
132 :
133 : /** @return a pointer to the data. @version 1.0 */
134 2462 : T* getData() { return _data; }
135 :
136 : /** @return a const pointer to the data. @version 1.0 */
137 : const T* getData() const { return _data; }
138 :
139 : /**
140 : * Set the size of the buffer without changing its allocation.
141 : *
142 : * This method only modifies the size parameter. If the current
143 : * allocation of the buffer is too small, it asserts, returns false and
144 : * does not change the size.
145 : * @version 1.0
146 : */
147 : bool setSize( const uint64_t size );
148 :
149 : /** @return the current number of elements. @version 1.0 */
150 1132 : uint64_t getSize() const { return _size; }
151 :
152 : /** @return the current storage size. @version 1.5.1 */
153 : uint64_t getNumBytes() const { return _size * sizeof( T ); }
154 :
155 : /** @return true if the buffer is empty, false if not. @version 1.0 */
156 : bool isEmpty() const { return (_size==0); }
157 :
158 : /** @return the maximum size of the buffer. @version 1.0 */
159 566 : uint64_t getMaxSize() const { return _maxSize; }
160 :
161 : private:
162 : /** A pointer to the data. */
163 : T* _data;
164 :
165 : /** The number of valid items in _data. */
166 : uint64_t _size;
167 :
168 : /** The allocation _size of the buffer. */
169 : uint64_t _maxSize;
170 : };
171 : }
172 :
173 : #include "buffer.ipp" // template implementation
174 :
175 : #endif //LUNCHBOX_BUFFER_H
|