/*UVOS*/ /* This file is part of TelemetrySystem. * * TelemetrySystem is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License (LGPL) version 3 as published by * the Free Software Foundation. * * TelemetrySystem is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with TelemetrySystem. If not, see . */ #pragma once #include template < int BUFFER_SIZE, typename T = uint8_t > class RingBuffer { private: volatile uint_fast16_t _headIndex = 0; volatile uint_fast16_t _tailIndex = 0; volatile bool _overrun = false; volatile T _buffer[BUFFER_SIZE]; public: RingBuffer() { flush(); } uint_fast16_t remaining() const volatile { return (_headIndex-_tailIndex); } uint_fast16_t remainingCapacity() const volatile { return BUFFER_SIZE - (_headIndex-_tailIndex); } bool isOverun() volatile { bool returnVal = _overrun; _overrun = false; return returnVal; } bool isEmpty() const volatile { return _tailIndex >= _headIndex; } T read() volatile { if(!isEmpty()) { _tailIndex++; return _buffer[(_tailIndex - 1) % BUFFER_SIZE]; } else return '\0'; } unsigned int read( T* buffer, unsigned int length ) volatile { unsigned int i = 0; for(; i < length && !isEmpty(); i++) { buffer[i] = read(); } return i; } void write( T in ) volatile { if (_headIndex - BUFFER_SIZE > 0 && _tailIndex - BUFFER_SIZE > 0) { _headIndex -= BUFFER_SIZE; _tailIndex -= BUFFER_SIZE; } _buffer[_headIndex % BUFFER_SIZE] = in; _headIndex++; if(remaining() > BUFFER_SIZE) { _overrun = true; _tailIndex = _headIndex - BUFFER_SIZE; } } void write( T* buffer, const unsigned int length ) volatile { for(unsigned int i = 0; i < length; i++) write(buffer[i]); } void flush(T flushCharacter = ' ') volatile { _headIndex = 0; _tailIndex = 0; for(int i = 0; i < BUFFER_SIZE; i++) _buffer[i] = flushCharacter; } unsigned int getString(T terminator, T* buffer, const unsigned int bufferLength) volatile { unsigned int i = 0; for(; i <= remaining() && i <= BUFFER_SIZE && _buffer[(_tailIndex+i) % BUFFER_SIZE] != terminator; i++); if( i < remaining() && i > 0) { if(i > bufferLength-1) i = bufferLength-1; read(buffer, i); buffer[i]='\0'; _tailIndex++; } else if(i == 0) _tailIndex++; else i = 0; return i; } };