2222#define _RING_BUFFER_
2323
2424#include < stdint.h>
25+ #include < string.h>
2526
2627namespace arduino {
2728
@@ -38,6 +39,7 @@ class RingBufferN
3839uint8_t _aucBuffer[N] ;
3940volatile int _iHead ;
4041volatile int _iTail ;
42+ volatile int _numElems;
4143
4244public:
4345RingBufferN (void ) ;
@@ -51,6 +53,7 @@ class RingBufferN
5153
5254private:
5355int nextIndex (int index);
56+ inline bool isEmpty ()const {return (_numElems ==0 ); }
5457};
5558
5659typedef RingBufferN<SERIAL_BUFFER_SIZE> RingBuffer;
@@ -66,16 +69,15 @@ RingBufferN<N>::RingBufferN( void )
6669template <int N>
6770void RingBufferN<N>::store_char(uint8_t c )
6871{
69- int i =nextIndex (_iHead);
70-
7172// if we should be storing the received character into the location
7273// just before the tail (meaning that the head would advance to the
7374// current location of the tail), we're about to overflow the buffer
7475// and so we don't write the character or advance the head.
75- if ( i != _iTail )
76+ if (! isFull () )
7677 {
7778 _aucBuffer[_iHead] = c ;
78- _iHead = i ;
79+ _iHead =nextIndex (_iHead);
80+ _numElems++;
7981 }
8082}
8183
@@ -84,44 +86,38 @@ void RingBufferN<N>::clear()
8486{
8587 _iHead =0 ;
8688 _iTail =0 ;
89+ _numElems =0 ;
8790}
8891
8992template <int N>
9093int RingBufferN<N>::read_char()
9194{
92- if (_iTail == _iHead )
95+ if ( isEmpty () )
9396return -1 ;
9497
9598uint8_t value = _aucBuffer[_iTail];
9699 _iTail =nextIndex (_iTail);
100+ _numElems--;
97101
98102return value;
99103}
100104
101105template <int N>
102106int RingBufferN<N>::available()
103107{
104- int delta = _iHead - _iTail;
105-
106- if (delta <0 )
107- return N + delta;
108- else
109- return delta;
108+ return _numElems;
110109}
111110
112111template <int N>
113112int RingBufferN<N>::availableForStore()
114113{
115- if (_iHead >= _iTail)
116- return N -1 - _iHead + _iTail;
117- else
118- return _iTail - _iHead -1 ;
114+ return (N - _numElems);
119115}
120116
121117template <int N>
122118int RingBufferN<N>::peek()
123119{
124- if (_iTail == _iHead )
120+ if ( isEmpty () )
125121return -1 ;
126122
127123return _aucBuffer[_iTail];
@@ -136,7 +132,7 @@ int RingBufferN<N>::nextIndex(int index)
136132template <int N>
137133bool RingBufferN<N>::isFull()
138134{
139- return (nextIndex (_iHead) ==_iTail );
135+ return (_numElems ==N );
140136}
141137
142138}