|
16 | 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
17 | 17 | */
|
18 | 18 |
|
| 19 | +#ifdef __cplusplus |
| 20 | + |
19 | 21 | #ifndef _RING_BUFFER_
|
20 | 22 | #define _RING_BUFFER_
|
21 | 23 |
|
|
27 | 29 | // location from which to read.
|
28 | 30 | #define SERIAL_BUFFER_SIZE 64
|
29 | 31 |
|
30 |
| -class RingBuffer |
| 32 | +template <int N> |
| 33 | +class RingBufferN |
31 | 34 | {
|
32 | 35 | public:
|
33 |
| - uint8_t _aucBuffer[SERIAL_BUFFER_SIZE] ; |
| 36 | + uint8_t _aucBuffer[N] ; |
34 | 37 | int _iHead ;
|
35 | 38 | int _iTail ;
|
36 | 39 |
|
37 | 40 | public:
|
38 |
| - RingBuffer( void ) ; |
| 41 | + RingBufferN( void ) ; |
39 | 42 | void store_char( uint8_t c ) ;
|
40 |
| - void clear(); |
41 |
| - int read_char(); |
42 |
| - int available(); |
43 |
| - int availableForStore(); |
44 |
| - int peek(); |
45 |
| - bool isFull(); |
| 43 | + void clear(); |
| 44 | + int read_char(); |
| 45 | + int available(); |
| 46 | + int availableForStore(); |
| 47 | + int peek(); |
| 48 | + bool isFull(); |
46 | 49 |
|
47 | 50 | private:
|
48 |
| - int nextIndex(int index); |
49 |
| -} ; |
| 51 | + int nextIndex(int index); |
| 52 | +}; |
| 53 | + |
| 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 | +} |
50 | 139 |
|
51 | 140 | #endif /* _RING_BUFFER_ */
|
| 141 | + |
| 142 | +#endif /* __cplusplus */ |
0 commit comments