Open Model Railroad Network (OpenMRN)
Loading...
Searching...
No Matches
RingBuffer.hxx
Go to the documentation of this file.
1
34#ifndef _UTILS_RINGBUFFER_HXX_
35#define _UTILS_RINGBUFFER_HXX_
36
37#include <new>
38#include "utils/macros.h"
39
42template <typename T> class RingBuffer
43{
44public:
49 static inline RingBuffer *create(size_t size)
50 {
51 RingBuffer *ring_buffer =
52 (RingBuffer*)malloc(sizeof(RingBuffer) + (size * sizeof(T)));
53 /* placement new allows for runtime ring buffer size */
54 new (ring_buffer) RingBuffer(size);
55
56 return ring_buffer;
57 }
58
61 void destroy()
62 {
63 free(this);
64 }
65
71 size_t put(const T *buf, size_t items)
72 {
74 size_t inserted = items < (_size - count) ? items : (_size - count);
75
76 for (size_t i = 0; i < inserted; ++i)
77 {
78 data[writeIndex++] = buf[i];
79
80 if (writeIndex == _size)
81 {
82 writeIndex = 0;
83 }
84 }
85
86 count += inserted;
87 return inserted;
88 }
89
95 size_t get(T *buf, size_t items)
96 {
98 size_t removed = items < count ? items : count;
99
100 for (size_t i = 0; i < removed; ++i)
101 {
102 buf[i] = data[readIndex++];
103
104 if (readIndex == _size)
105 {
106 readIndex = 0;
107 }
108 }
109
110 count -= removed;
111 return removed;
112 }
113
119 size_t data_read_pointer(T **buf)
120 {
121 size_t result = size - readIndex;
122 if (count < result)
123 {
124 result = count;
125 }
126 *buf = data + readIndex;
127 return result;
128 }
129
135 size_t data_write_pointer(T **buf)
136 {
137 size_t result = size - writeIndex;
138 if (space() < result)
139 {
140 result = space();
141 }
142 *buf = data + writeIndex;
143 return result;
144 }
145
150 size_t consume(size_t items)
151 {
152 if (items > count)
153 {
154 items = count;
155 }
156 size_t consumed = items;
157 count -= items;
158 if ((readIndex + items) >= size)
159 {
160 items -= (size - readIndex);
161 readIndex = 0;
162 }
163 readIndex += items;
164
165 // Try to align the buffer so that we have the most available space to
166 // write.
167 if (!count)
168 {
169 readIndex = writeIndex = 0;
170 }
171
172 return consumed;
173 }
174
179 size_t advance(size_t items)
180 {
181 if (items > space())
182 {
183 items = space();
184 }
185 size_t added = items;
186 count += items;
187 if ((writeIndex + items) >= size)
188 {
189 items -= (size - writeIndex);
190 writeIndex = 0;
191 }
192 writeIndex += items;
193
194 return added;
195 }
196
200 size_t items()
201 {
202 return count;
203 }
204
208 size_t size()
209 {
210 return _size;
211 }
212
216 size_t space()
217 {
218 return _size - count;
219 }
220
221private:
226 : _size(size),
227 count(0),
228 readIndex(0),
229 writeIndex(0)
230 {
231 }
232
236
240
242
244 size_t _size;
245
247 size_t count;
248
250 size_t readIndex;
251
254
256 T data[];
257};
258
259#endif /* _UTILS_RINGBUFFER_HXX_ */
Implements a vanilla ring buffer.
RingBuffer(size_t size)
Constructor.
size_t count
total number of items in ring buffer
size_t writeIndex
write index
size_t advance(size_t items)
Add a number of items to the buffer by advancing the writeIndex.
~RingBuffer()
Default destructor.
T data[]
ring buffer data
size_t readIndex
read index
size_t get(T *buf, size_t items)
remove a number of items from the buffer.
size_t consume(size_t items)
Remove a number of items from the buffer by advancing the readIndex.
void destroy()
Destroy an existing ring buffer instance.
size_t _size
size in items of ring buffer
size_t space()
space left in buffer of buffer in number items.
size_t size()
Size of buffer in number of items.
size_t put(const T *buf, size_t items)
Insert a number of items to the buffer.
size_t data_write_pointer(T **buf)
Get a reference to the current location in the buffer for write.
size_t data_read_pointer(T **buf)
Get a reference to the current location in the buffer for read.
static RingBuffer * create(size_t size)
Factory method to create a ring buffer instance.
size_t items()
Number of items in the buffer.
RingBuffer()
Default Constructor.
#define DISALLOW_COPY_AND_ASSIGN(TypeName)
Removes default copy-constructor and assignment added by C++.
Definition macros.h:171