Skip to content

Commit e952b68

Browse files
committed
Make RingBuffer class template-based
This commit allows enlarging the ringbuffer for specific needs (at compile time). Cherry-picked from arduino/ArduinoCore-samd@503a9b3
1 parent b5faca5 commit e952b68

File tree

2 files changed

+103
-136
lines changed

2 files changed

+103
-136
lines changed

Diff for: api/RingBuffer.cpp

-112
This file was deleted.

Diff for: api/RingBuffer.h

+103-24
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1717
*/
1818

19+
#ifdef __cplusplus
20+
1921
#ifndef _RING_BUFFER_
2022
#define _RING_BUFFER_
2123

@@ -25,39 +27,116 @@
2527
// using a ring buffer (I think), in which head is the index of the location
2628
// to which to write the next incoming character and tail is the index of the
2729
// location from which to read.
30+
#define SERIAL_BUFFER_SIZE 64
2831

29-
#define RINGBUFFER_HAS_ADDITIONAL_STORAGE_API
30-
31-
#ifdef RINGBUFFER_FORCE_SMALL_SIZE
32-
typedef uint8_t rb_index_type;
33-
#else
34-
typedef unsigned int rb_index_type;
35-
#endif
36-
37-
class RingBuffer
32+
template <int N>
33+
class RingBufferN
3834
{
39-
public:
40-
RingBuffer( rb_index_type size = 64 ) ;
35+
public:
36+
uint8_t _aucBuffer[N] ;
37+
volatile int _iHead ;
38+
volatile int _iTail ;
39+
40+
public:
41+
RingBufferN( void ) ;
4142
void store_char( uint8_t c ) ;
4243
void clear();
4344
int read_char();
4445
int available();
4546
int availableForStore();
4647
int peek();
4748
bool isFull();
48-
void addStorage(uint8_t* _buffer, rb_index_type _size) {
49-
additionalSize = _size;
50-
additionalBuffer = _buffer;
51-
};
52-
53-
private:
54-
rb_index_type nextIndex(rb_index_type index);
55-
uint8_t* additionalBuffer;
56-
int additionalSize = 0;
57-
rb_index_type size;
58-
uint8_t* _aucBuffer;
59-
volatile rb_index_type _iHead ;
60-
volatile rb_index_type _iTail ;
49+
50+
private:
51+
int nextIndex(int index);
6152
};
6253

54+
typedef RingBufferN<SERIAL_BUFFER_SIZE> RingBuffer;
55+
56+
57+
template <int N>
58+
RingBufferN<N>::RingBufferN( void )
59+
{
60+
memset( _aucBuffer, 0, N ) ;
61+
clear();
62+
}
63+
64+
template <int N>
65+
void RingBufferN<N>::store_char( uint8_t c )
66+
{
67+
int i = nextIndex(_iHead);
68+
69+
// if we should be storing the received character into the location
70+
// just before the tail (meaning that the head would advance to the
71+
// current location of the tail), we're about to overflow the buffer
72+
// and so we don't write the character or advance the head.
73+
if ( i != _iTail )
74+
{
75+
_aucBuffer[_iHead] = c ;
76+
_iHead = i ;
77+
}
78+
}
79+
80+
template <int N>
81+
void RingBufferN<N>::clear()
82+
{
83+
_iHead = 0;
84+
_iTail = 0;
85+
}
86+
87+
template <int N>
88+
int RingBufferN<N>::read_char()
89+
{
90+
if(_iTail == _iHead)
91+
return -1;
92+
93+
uint8_t value = _aucBuffer[_iTail];
94+
_iTail = nextIndex(_iTail);
95+
96+
return value;
97+
}
98+
99+
template <int N>
100+
int RingBufferN<N>::available()
101+
{
102+
int delta = _iHead - _iTail;
103+
104+
if(delta < 0)
105+
return N + delta;
106+
else
107+
return delta;
108+
}
109+
110+
template <int N>
111+
int RingBufferN<N>::availableForStore()
112+
{
113+
if (_iHead >= _iTail)
114+
return N - 1 - _iHead + _iTail;
115+
else
116+
return _iTail - _iHead - 1;
117+
}
118+
119+
template <int N>
120+
int RingBufferN<N>::peek()
121+
{
122+
if(_iTail == _iHead)
123+
return -1;
124+
125+
return _aucBuffer[_iTail];
126+
}
127+
128+
template <int N>
129+
int RingBufferN<N>::nextIndex(int index)
130+
{
131+
return (uint32_t)(index + 1) % N;
132+
}
133+
134+
template <int N>
135+
bool RingBufferN<N>::isFull()
136+
{
137+
return (nextIndex(_iHead) == _iTail);
138+
}
139+
63140
#endif /* _RING_BUFFER_ */
141+
142+
#endif /* __cplusplus */

0 commit comments

Comments
 (0)