Xyris  0.5
RingBuffer.hpp
Go to the documentation of this file.
1 /**
2  * @file RingBuffer.hpp
3  * @author Keeton Feavel ([email protected])
4  * @brief A ring buffer is a buffer method where the same
5  * memory used to contain data is reused. Inserting and removing
6  * data is done in a queue-like fashion.
7  * @version 0.3
8  * @date 2020-09-12
9  *
10  * @copyright Copyright the Xyris Contributors (c) 2020
11  *
12  */
13 #pragma once
14 
15 #include <stdint.h>
16 #include <Library/errno.hpp>
17 
18 template <typename T, size_t S>
19 class RingBuffer {
20 public:
21  /**
22  * @brief Initializes the circular buffer and allocates
23  * the data memory.
24  */
25  explicit RingBuffer()
26  : head(0)
27  , tail(0)
28  , length(0)
29  , error(0)
30  {
31  // Default constructor
32  }
33 
34  /**
35  * @brief Writes a byte into the circular buffer.
36  *
37  * @param val Data to write to the buffer
38  */
39  int Enqueue(T val)
40  {
41  int status = 0;
42  // Check if the buffer is full. If so, we can't enqueue.
43  if (IsFull()) {
44  status = -1;
45  error = BufferFull;
46  } else {
47  // Write the data at the write index
48  this->data[this->head] = val;
49  this->head = ((this->head + 1) % S);
50  ++this->length;
51  }
52  // Return the status code
53  return status;
54  }
55 
56  /**
57  * @brief Dequeues from the circular buffer and writes
58  * the value to the data pointer.
59  *
60  * @param buf Buffer to contain the data
61  * @return int Returns 0 on success and -1 on error.
62  */
63  int Dequeue(T* buf)
64  {
65  int status = 0;
66  // Check if the buffer is empty. If so, we can't dequeue
67  if (IsEmpty()) {
68  status = -1;
70  } else {
71  // Read out the data and decrement the position
72  *buf = this->data[this->tail];
73  this->tail = ((this->tail + 1) % S);
74  --this->length;
75  }
76  // Return the status code
77  return status;
78  }
79 
80  /**
81  * @brief Dequeues from the circular buffer and returns
82  * the data.
83  *
84  * @return T Returns dequeued data.
85  */
86  T Dequeue()
87  {
88  T val = 0;
89  // Check if the buffer is empty. If so, we can't dequeue
90  if (IsEmpty()) {
92  } else {
93  // Read out the data and decrement the position
94  val = this->data[this->tail];
95  this->tail = ((this->tail + 1) % S);
96  --this->length;
97  }
98  // Return the status code
99  return val;
100  }
101 
102  /**
103  * @brief Grab the latest bytes of data from the buffer without
104  * removing it.
105  *
106  * @param buf Buffer to contain the data
107  * @return int Returns 0 on success and -1 on error.
108  */
109  int Peek(T* buf)
110  {
111  int status = 0;
112  // Check if the buffer is empty. If so, we can't dequeue
113  if (IsEmpty()) {
114  status = -1;
116  } else {
117  // Read out the data and don't decrement the position
118  *buf = this->data[this->tail];
119  }
120  // Return the status code
121  return status;
122  }
123 
124  /**
125  *
126  * @brief Query whether the circular buffer is empty.
127  *
128  * @return true The buffer is empty
129  * @return false The buffer is not empty
130  */
131  bool IsEmpty()
132  {
133  return this->length == 0;
134  }
135 
136  /**
137  * @brief Query whether the circular buffer is full.
138  *
139  * @return true The buffer is full
140  * @return false The buffer is not full
141  */
142  bool IsFull()
143  {
144  return this->length == S;
145  }
146 
147  /**
148  * @brief Returns the number of items (bytes) in the buffer.
149  *
150  * @return int Number of bytes available for reading.
151  */
152  int Length()
153  {
154  return this->length;
155  }
156 
157  /**
158  * @brief Returns the buffer capacity (in number of bytes).
159  *
160  * @return int Buffer capacity in bytes
161  */
162  int Capacity()
163  {
164  return S;
165  }
166 
167  /**
168  * @brief Returns the ring buffer error code.
169  *
170  * @return int Error code
171  */
172  int Error()
173  {
174  return error;
175  }
176 
177 private:
178  T data[S];
179  size_t head;
180  size_t tail;
181  size_t length;
182  int error;
183 };
BufferFull
@ BufferFull
Definition: errno.hpp:19
RingBuffer::data
T data[S]
Definition: RingBuffer.hpp:178
errno.hpp
Kernel error definitions.
RingBuffer::Dequeue
int Dequeue(T *buf)
Dequeues from the circular buffer and writes the value to the data pointer.
Definition: RingBuffer.hpp:63
RingBuffer::RingBuffer
RingBuffer()
Initializes the circular buffer and allocates the data memory.
Definition: RingBuffer.hpp:25
RingBuffer::Peek
int Peek(T *buf)
Grab the latest bytes of data from the buffer without removing it.
Definition: RingBuffer.hpp:109
RingBuffer::head
size_t head
Definition: RingBuffer.hpp:179
RingBuffer::Error
int Error()
Returns the ring buffer error code.
Definition: RingBuffer.hpp:172
RingBuffer::Enqueue
int Enqueue(T val)
Writes a byte into the circular buffer.
Definition: RingBuffer.hpp:39
RingBuffer::error
int error
Definition: RingBuffer.hpp:182
RingBuffer::Capacity
int Capacity()
Returns the buffer capacity (in number of bytes).
Definition: RingBuffer.hpp:162
RingBuffer::tail
size_t tail
Definition: RingBuffer.hpp:180
RingBuffer::Length
int Length()
Returns the number of items (bytes) in the buffer.
Definition: RingBuffer.hpp:152
RingBuffer
Definition: RingBuffer.hpp:19
RingBuffer::Dequeue
T Dequeue()
Dequeues from the circular buffer and returns the data.
Definition: RingBuffer.hpp:86
RingBuffer::IsEmpty
bool IsEmpty()
Query whether the circular buffer is empty.
Definition: RingBuffer.hpp:131
RingBuffer::length
size_t length
Definition: RingBuffer.hpp:181
InvalidValue
@ InvalidValue
Definition: errno.hpp:20
RingBuffer::IsFull
bool IsFull()
Query whether the circular buffer is full.
Definition: RingBuffer.hpp:142