1
1
#include "RingBuffer.h"
4
#define err_on_full(S) {\
3
/* These are just to reduce code redundancy.
5
#define err_on_full(S, E) {\
5
6
if (self->len >= S->size) {\
7
8
s_err_print ("Buffer full. Needs to be reallocated.\n"\
8
9
" (This is not done automatically. Returning.)");\
13
#define err_seems_full() {\
14
#define err_seems_full(E) {\
14
15
s_err_print ("Array seems to be full... Returning.");\
19
#define nothing_to_ret() {\
20
s_warn_print ("Ring buffer is empty, nothing to return");\
20
#define err_on_empty(S, E) {\
21
if (s_ring_buffer_is_empty (S)) {\
22
s_warn_print ("Ring buffer is empty, nothing to return");\
25
29
struct SRingBuffer {
30
size_t size; /* The number of elemets in the array */
31
size_t len; /* The "length" of the buffered data */
33
size_t start; /* The index of the "first" element in the buffer in the array
35
size_t end; /* The index of the "last" element in the buffer in the array
38
sbyte * array; /* The array that is used to implement the buffer */
56
63
s_ring_buffer_is_empty (SRingBuffer * self) {
64
/* If the data data two pointers are the same and the the length is zero,
65
* the array is most likely empty... */
57
66
return ((self->start == self->end) && self->len == 0 );
74
err_on_full (self, *err);
75
/* The buffer should only have three different states so this should do.
76
* (exept there are five states... Idiot...)
78
* The first state here is the normal state where the end is after the start.
80
* The second state is when the end pointer is at the end of the array.
81
* This has two substates, one where the array is full (the start pointer
82
* is zero and the end pointer points to the last lement of the array), the
83
* second state is when the stat pointer does not point to zero and is thus
84
* free to use so we set the end pointer to zero.
86
* The third state is when the array loops back on itself (see headerfile).
87
* This has two substates, one where the next element that should be set is
88
* actially the start element, thus the array is full. The second substates
89
* is when that is not true and we can use that slot.
67
91
if (self->end <= self->size) {
68
92
self->end = self->end + 1;
69
93
} else if (self->end == self->size) {
70
94
if (self->start == 0) {
95
err_seems_full (*err);
75
99
} else if (self->end < self->start) {
76
100
if ((self->end + 1) == self->start ) {
101
err_seems_full (*err);
79
103
self->end = self->end + 1;
106
/* This is an unknown state... some bad shit has gone down if you end up
82
108
s_err_print ("Reaching a place that should not be reached. Returning");
122
err_on_full (self, *err);
98
if ((self->start - 1) < 0) {
124
/* This is pretty much the same as s_ring_buffer_push (), save for the states
125
* beeing in a different order order is different to make it actially work as
130
if (self->start == 0) {
99
131
if (self->end == self->size) {
132
err_seems_full (*err);
102
134
self->start = self->size;
104
136
} else if (self->start <= self-end) {
105
137
self->start = self->start - 1;
106
} else if (self->start > self->end) {
138
} else if (self->start > self->end) {
107
139
if ((self->start - 1) == self->end ) {
140
err_seems_full (*err);
110
142
self->start = self->start - 1;
122
154
* When doing poping we do not override the data in the buffer.
123
* This to alleviate some prosessing time form usage of the data structure.
155
* This to alleviate some processing time form usage of the data structure.
126
158
s_ring_buffer_pop (SRingBuffer * self, sboolean * err) {
127
if (s_ring_buffer_is_empty (self)) {
159
err_on_empty (self, *err);
131
160
sbyte ret_val = self->array[self->end];
132
161
self->len = self->len - 1;
133
162
self->end = self->end - 1;
139
168
s_ring_buffer_pop_front (SRingBuffer * self, sboolean * err) {
140
if (s_ring_buffer_is_empty (self)) {
169
err_on_empty (self, *err);
144
171
sbyte ret_val = self->array[self->start];
145
172
self->start = self->start + 1;
152
179
s_ring_buffer_peek (SRingBuffer * self, sboolean * err) {
153
if (s_ring_buffer_is_empty (self)) {
180
err_on_empty (self, *err);
157
182
return self->array[self->end];
161
186
s_ring_buffer_peek_front (SRingBuffer * self, sboolean * err) {
162
if (s_ring_buffer_is_empty (self)) {
187
err_on_empty (self, *err);
166
189
return self->array[self->start];