22
22
#define _RING_BUFFER_
23
23
24
24
#include < stdint.h>
25
+ #include < string.h>
25
26
26
27
namespace arduino {
27
28
@@ -38,6 +39,7 @@ class RingBufferN
38
39
uint8_t _aucBuffer[N] ;
39
40
volatile int _iHead ;
40
41
volatile int _iTail ;
42
+ volatile int _numElems;
41
43
42
44
public:
43
45
RingBufferN ( void ) ;
@@ -51,6 +53,7 @@ class RingBufferN
51
53
52
54
private:
53
55
int nextIndex (int index);
56
+ inline bool isEmpty () const { return (_numElems == 0 ); }
54
57
};
55
58
56
59
typedef RingBufferN<SERIAL_BUFFER_SIZE> RingBuffer;
@@ -66,16 +69,15 @@ RingBufferN<N>::RingBufferN( void )
66
69
template <int N>
67
70
void RingBufferN<N>::store_char( uint8_t c )
68
71
{
69
- int i = nextIndex (_iHead);
70
-
71
72
// if we should be storing the received character into the location
72
73
// just before the tail (meaning that the head would advance to the
73
74
// current location of the tail), we're about to overflow the buffer
74
75
// and so we don't write the character or advance the head.
75
- if ( i != _iTail )
76
+ if (! isFull () )
76
77
{
77
78
_aucBuffer[_iHead] = c ;
78
- _iHead = i ;
79
+ _iHead = nextIndex (_iHead);
80
+ _numElems++;
79
81
}
80
82
}
81
83
@@ -84,44 +86,38 @@ void RingBufferN<N>::clear()
84
86
{
85
87
_iHead = 0 ;
86
88
_iTail = 0 ;
89
+ _numElems = 0 ;
87
90
}
88
91
89
92
template <int N>
90
93
int RingBufferN<N>::read_char()
91
94
{
92
- if (_iTail == _iHead )
95
+ if ( isEmpty () )
93
96
return -1 ;
94
97
95
98
uint8_t value = _aucBuffer[_iTail];
96
99
_iTail = nextIndex (_iTail);
100
+ _numElems--;
97
101
98
102
return value;
99
103
}
100
104
101
105
template <int N>
102
106
int RingBufferN<N>::available()
103
107
{
104
- int delta = _iHead - _iTail;
105
-
106
- if (delta < 0 )
107
- return N + delta;
108
- else
109
- return delta;
108
+ return _numElems;
110
109
}
111
110
112
111
template <int N>
113
112
int RingBufferN<N>::availableForStore()
114
113
{
115
- if (_iHead >= _iTail)
116
- return N - 1 - _iHead + _iTail;
117
- else
118
- return _iTail - _iHead - 1 ;
114
+ return (N - _numElems);
119
115
}
120
116
121
117
template <int N>
122
118
int RingBufferN<N>::peek()
123
119
{
124
- if (_iTail == _iHead )
120
+ if ( isEmpty () )
125
121
return -1 ;
126
122
127
123
return _aucBuffer[_iTail];
@@ -136,7 +132,7 @@ int RingBufferN<N>::nextIndex(int index)
136
132
template <int N>
137
133
bool RingBufferN<N>::isFull()
138
134
{
139
- return (nextIndex (_iHead) == _iTail );
135
+ return (_numElems == N );
140
136
}
141
137
142
138
}
0 commit comments