Small library for using circular buffers (forked from François Berder's implementation in order to add methods and fix problems)

Dependents:   CircularBufferTest XBeeApi

Fork of CircularBuffer by Francois Berder

Test suite can be found in this application, CircularBufferTest

Committer:
johnb
Date:
Sat Jan 18 18:01:03 2014 +0000
Revision:
6:242d0e9f13d1
Parent:
5:abe8909f9603
Child:
7:e2d532183250
Attempt to fix bug whereby getSize() would not return correctly.  Previously:; ; char c;; // getSize == 0; x.write( &c, 1 );; // getSize == 1; w.read( &c, 1 );; // getSize() == 512 !

Who changed what in which revision?

UserRevisionLine numberNew contents of line
feb11 0:5d058c917599 1 #ifndef CIRCULAR_BUFFER_H
feb11 0:5d058c917599 2 #define CIRCULAR_BUFFER_H
feb11 0:5d058c917599 3
johnb 5:abe8909f9603 4 #include <cstddef>
johnb 5:abe8909f9603 5 #include <stdint.h>
johnb 5:abe8909f9603 6
feb11 4:e15dee1d59ee 7 /** This class implements a static circular buffer.
johnb 5:abe8909f9603 8
johnb 5:abe8909f9603 9 CirularBuffer class originally by François Berder ( see http://mbed.org/users/feb11/code/CircularBuffer/ )
johnb 5:abe8909f9603 10 Additions by John Bailey ( http://mbed.org/users/johnb/ )
feb11 4:e15dee1d59ee 11 */
feb11 0:5d058c917599 12 template<size_t T>
feb11 0:5d058c917599 13 class CircularBuffer
feb11 0:5d058c917599 14 {
feb11 0:5d058c917599 15 public :
johnb 5:abe8909f9603 16
feb11 4:e15dee1d59ee 17 /** Default constructor
feb11 4:e15dee1d59ee 18 */
feb11 0:5d058c917599 19 CircularBuffer();
feb11 0:5d058c917599 20
johnb 5:abe8909f9603 21 /** Reads data from buffer (data is removed from the buffer as
johnb 5:abe8909f9603 22 opposed to the peek method which allows inspection of the
johnb 5:abe8909f9603 23 contents without modifying the buffer)
feb11 4:e15dee1d59ee 24
feb11 4:e15dee1d59ee 25 \param data output buffer
feb11 4:e15dee1d59ee 26 \param length Maximum number of bytes to read
feb11 4:e15dee1d59ee 27 \return Number of bytes read
feb11 4:e15dee1d59ee 28
feb11 4:e15dee1d59ee 29 \note The return value cannot exceed max(length,capacity)
feb11 4:e15dee1d59ee 30 */
feb11 2:6f3630f5fa06 31 uint32_t read(uint8_t *data, uint32_t length);
johnb 5:abe8909f9603 32
johnb 5:abe8909f9603 33 /** Reads data from buffer leaving the data in the buffer
johnb 5:abe8909f9603 34 (as opposed to the read method which removed the returned
johnb 5:abe8909f9603 35 data from the buffer)
johnb 5:abe8909f9603 36
johnb 5:abe8909f9603 37 \param data output buffer
johnb 5:abe8909f9603 38 \param length Maximum number of bytes to read
johnb 5:abe8909f9603 39 \return Number of bytes read
johnb 5:abe8909f9603 40
johnb 5:abe8909f9603 41 \note The return value cannot exceed max(length,capacity)
johnb 5:abe8909f9603 42 */
johnb 5:abe8909f9603 43 uint32_t peek(uint8_t *data, uint32_t length) const;
feb11 4:e15dee1d59ee 44
feb11 4:e15dee1d59ee 45 /** Writes data in buffer
feb11 4:e15dee1d59ee 46
feb11 4:e15dee1d59ee 47 \param data input buffer
feb11 4:e15dee1d59ee 48 \param length Maximum number of bytes to write
feb11 4:e15dee1d59ee 49 \return Number of bytes wrote
feb11 4:e15dee1d59ee 50
feb11 4:e15dee1d59ee 51 \note The return value cannot exceed max(length,capacity)
feb11 4:e15dee1d59ee 52 */
feb11 2:6f3630f5fa06 53 uint32_t write(uint8_t *data, uint32_t length);
feb11 3:9a45d6675e65 54
feb11 4:e15dee1d59ee 55 /** Returns the total capacity of this buffer
feb11 4:e15dee1d59ee 56 \return Capacity of buffer
feb11 4:e15dee1d59ee 57 */
feb11 2:6f3630f5fa06 58 uint32_t getCapacity() const;
feb11 4:e15dee1d59ee 59
feb11 4:e15dee1d59ee 60 /** Returns the number of bytes available in the buffer
feb11 4:e15dee1d59ee 61 \return Number of bytes available in the buffer
feb11 4:e15dee1d59ee 62 */
feb11 3:9a45d6675e65 63 uint32_t getSize() const;
feb11 4:e15dee1d59ee 64
feb11 4:e15dee1d59ee 65 /** Checks if this buffer is empty
feb11 4:e15dee1d59ee 66 \return True if the buffer is empty, false otherwise
feb11 4:e15dee1d59ee 67 */
feb11 3:9a45d6675e65 68 bool isEmpty() const;
feb11 4:e15dee1d59ee 69
feb11 4:e15dee1d59ee 70 /** Checks if this buffer is full
feb11 4:e15dee1d59ee 71 \return True if the buffer is full, false otherwise
feb11 4:e15dee1d59ee 72 */
feb11 3:9a45d6675e65 73 bool isFull() const;
feb11 2:6f3630f5fa06 74
feb11 0:5d058c917599 75 private :
johnb 5:abe8909f9603 76
johnb 5:abe8909f9603 77 typedef uint16_t CircularBufferIndex_t;
feb11 0:5d058c917599 78
johnb 5:abe8909f9603 79 CircularBufferIndex_t readIndex, writeIndex;
feb11 0:5d058c917599 80 uint8_t buffer[T];
feb11 0:5d058c917599 81
feb11 0:5d058c917599 82 };
feb11 0:5d058c917599 83
feb11 0:5d058c917599 84 template<size_t T>
feb11 0:5d058c917599 85 CircularBuffer<T>::CircularBuffer():
johnb 6:242d0e9f13d1 86 readIndex(0),
feb11 1:9953890d59e2 87 writeIndex(0)
feb11 0:5d058c917599 88 {
feb11 0:5d058c917599 89 }
feb11 0:5d058c917599 90
feb11 0:5d058c917599 91 template<size_t T>
feb11 2:6f3630f5fa06 92 uint32_t CircularBuffer<T>::read(uint8_t *data, uint32_t length)
feb11 0:5d058c917599 93 {
feb11 2:6f3630f5fa06 94 uint32_t n = 0;
feb11 3:9a45d6675e65 95 while(n < length && getSize() > 0)
feb11 0:5d058c917599 96 {
feb11 2:6f3630f5fa06 97 if(readIndex == T)
feb11 2:6f3630f5fa06 98 readIndex = 0;
feb11 2:6f3630f5fa06 99 data[n++] = buffer[readIndex++];
feb11 0:5d058c917599 100 }
feb11 0:5d058c917599 101
feb11 2:6f3630f5fa06 102 return n;
feb11 0:5d058c917599 103 }
feb11 0:5d058c917599 104
feb11 0:5d058c917599 105 template<size_t T>
johnb 5:abe8909f9603 106 uint32_t CircularBuffer<T>::peek(uint8_t *data, uint32_t length) const
johnb 5:abe8909f9603 107 {
johnb 5:abe8909f9603 108 uint32_t n = 0;
johnb 5:abe8909f9603 109 CircularBufferIndex_t src = readIndex;
johnb 5:abe8909f9603 110 while(n < length && getSize() > 0)
johnb 5:abe8909f9603 111 {
johnb 5:abe8909f9603 112 if(src == T) {
johnb 5:abe8909f9603 113 src = 0;
johnb 5:abe8909f9603 114 }
johnb 5:abe8909f9603 115 data[n++] = buffer[src++];
johnb 5:abe8909f9603 116 }
johnb 5:abe8909f9603 117
johnb 5:abe8909f9603 118 return n;
johnb 5:abe8909f9603 119 }
johnb 5:abe8909f9603 120
johnb 5:abe8909f9603 121 template<size_t T>
feb11 2:6f3630f5fa06 122 uint32_t CircularBuffer<T>::write(uint8_t *data, uint32_t length)
feb11 0:5d058c917599 123 {
feb11 2:6f3630f5fa06 124 uint32_t n = 0;
feb11 3:9a45d6675e65 125 while(n < length && getSize() < T)
feb11 0:5d058c917599 126 {
feb11 0:5d058c917599 127 if(writeIndex == T)
feb11 0:5d058c917599 128 writeIndex = 0;
feb11 2:6f3630f5fa06 129 buffer[writeIndex++] = data[n++];
feb11 0:5d058c917599 130 }
feb11 0:5d058c917599 131
feb11 2:6f3630f5fa06 132 return n;
feb11 2:6f3630f5fa06 133 }
feb11 2:6f3630f5fa06 134
feb11 2:6f3630f5fa06 135 template<size_t T>
feb11 2:6f3630f5fa06 136 uint32_t CircularBuffer<T>::getCapacity() const
feb11 2:6f3630f5fa06 137 {
feb11 2:6f3630f5fa06 138 return T;
feb11 2:6f3630f5fa06 139 }
feb11 2:6f3630f5fa06 140
feb11 2:6f3630f5fa06 141 template<size_t T>
feb11 2:6f3630f5fa06 142 uint32_t CircularBuffer<T>::getSize() const
feb11 2:6f3630f5fa06 143 {
johnb 6:242d0e9f13d1 144 return ((writeIndex >= readIndex) ? (writeIndex - readIndex) : (T + writeIndex - readIndex));
feb11 3:9a45d6675e65 145 }
feb11 3:9a45d6675e65 146
feb11 3:9a45d6675e65 147 template<size_t T>
feb11 3:9a45d6675e65 148 bool CircularBuffer<T>::isEmpty() const
feb11 3:9a45d6675e65 149 {
feb11 3:9a45d6675e65 150 return getSize() == 0;
feb11 3:9a45d6675e65 151 }
feb11 3:9a45d6675e65 152
feb11 3:9a45d6675e65 153 template<size_t T>
feb11 3:9a45d6675e65 154 bool CircularBuffer<T>::isFull() const
feb11 3:9a45d6675e65 155 {
feb11 3:9a45d6675e65 156 return getSize() == T;
feb11 0:5d058c917599 157 }
feb11 0:5d058c917599 158
feb11 0:5d058c917599 159 typedef CircularBuffer<32> SmallCircularBuffer;
feb11 0:5d058c917599 160 typedef CircularBuffer<128> MediumCircularBuffer;
feb11 2:6f3630f5fa06 161 typedef CircularBuffer<512> BigCircularBuffer;
feb11 0:5d058c917599 162
feb11 0:5d058c917599 163 #endif