Add FIFO buffer type

This commit is contained in:
Henrik Stickann 2022-04-27 18:34:42 +02:00
parent bbcb3d9d21
commit 48976fff88
2 changed files with 200 additions and 0 deletions

View File

@ -0,0 +1,97 @@
#ifndef STA_FIFO_BUFFER_HPP
#define STA_FIFO_BUFFER_HPP
namespace sta
{
/**
* @brief FIFO buffer.
*
* @tparam Size Size type
* @tparam N Buffer size
*/
template <typename Size, Size N>
class FifoBuffer
{
public:
using size_type = Size;
static constexpr size_type MAX_SIZE = N;
public:
FifoBuffer();
FifoBuffer(const uint8_t * buffer, Size size);
/**
* @brief Clear buffer content.
*/
void clear();
/**
* @brief Set data in buffer.
*
* @param buffer Source buffer
* @param size Number of bytes to write
*/
void set(const uint8_t * buffer, size_type size);
/**
* @brief Append value to end of buffer.
*
* @param value Value
*/
void pushBack(uint8_t value);
/**
* @brief Append data to end of buffer.
*
* @param buffer Source buffer
* @param size Number of bytes to write
*/
void pushBack(const uint8_t * buffer, size_type size);
/**
* @brief Append value repeatedly to end of buffer.
*
* @param value Fill value
* @param count Repeat count
*/
void pushBack(uint8_t value, size_type count);
/**
* @brief Take data from start of buffer.
*
* @param buffer Destination buffer
* @param size Number of bytes to read
*/
void popFront(uint8_t * buffer, size_type size);
/**
* @brief Get size of data in buffer.
*
* @return Data size
*/
size_type size() const;
/**
* @brief Check if buffer is full.
*
* @return True if buffer is full
*/
bool isFull() const;
/**
* @brief Check if buffer is empty.
*
* @return True if buffer is empty
*/
bool isEmpty() const;
private:
uint8_t * head_; /**< Read position */
uint8_t * tail_; /**< Write position */
uint8_t buffer_[N]; /**< Buffer data */
};
} // namespace sta
#include <sta/fifo_buffer.tpp>
#endif // STA_FIFO_BUFFER_HPP

103
include/sta/fifo_buffer.tpp Normal file
View File

@ -0,0 +1,103 @@
#ifndef STA_FIFO_BUFFER_TPP
#define STA_FIFO_BUFFER_TPP
#ifndef STA_FIFO_BUFFER_HPP
# error "Internal header. Include <sta/fifo_buffer.hpp> instead"
#endif // !STA_FIFO_BUFFER_HPP
#include <cstring>
namespace sta
{
template <typename Size, Size N>
FifoBuffer<Size, N>::FifoBuffer()
: head_{buffer_}, tail_{buffer_}
{}
template <typename Size, Size N>
FifoBuffer<Size, N>::FifoBuffer(const uint8_t * buffer, size_type size)
{
set(buffer, size);
}
template <typename Size, Size N>
void FifoBuffer<Size, N>::set(const uint8_t * buffer, size_type bsize)
{
STA_ASSERT(bsize <= sizeof(buffer_));
STA_ASSERT(buffer != nullptr);
head_ = buffer_;
tail_ = buffer_ + bsize;
memcpy(buffer_, buffer, bsize);
}
template <typename Size, Size N>
void FifoBuffer<Size, N>::clear()
{
head_ = tail_ = buffer_;
}
template <typename Size, Size N>
void FifoBuffer<Size, N>::pushBack(uint8_t value)
{
STA_ASSERT_MSG(tail_ < buffer_ + sizeof(buffer_), "Buffer overflow");
*tail_++ = value;
}
template <typename Size, Size N>
void FifoBuffer<Size, N>::pushBack(const uint8_t * buffer, size_type bsize)
{
STA_ASSERT_MSG(size() + bsize <= sizeof(buffer_), "Buffer overflow");
STA_ASSERT(buffer != nullptr);
memcpy(tail_, buffer, bsize);
tail_ += bsize;
}
template <typename Size, Size N>
void FifoBuffer<Size, N>::pushBack(uint8_t value, size_type count)
{
STA_ASSERT_MSG(size() + count <= sizeof(buffer_), "Buffer overflow");
memset(tail_, value, count);
tail_ += count;
}
template <typename Size, Size N>
void FifoBuffer<Size, N>::popFront(uint8_t * buffer, size_type bsize)
{
STA_ASSERT_MSG(size() >= bsize, "Not enough data");
STA_ASSERT(buffer != nullptr);
memcpy(buffer, head_, bsize);
head_ += bsize;
}
template <typename Size, Size N>
typename FifoBuffer<Size, N>::size_type FifoBuffer<Size, N>::size() const
{
return (tail_ - head_);
}
template <typename Size, Size N>
bool FifoBuffer<Size, N>::isFull() const
{
return (tail_ == buffer_ + sizeof(buffer_));
}
template <typename Size, Size N>
bool FifoBuffer<Size, N>::isEmpty() const
{
return (head_ == tail_);
}
} // namespace sta
#endif // STA_FIFO_BUFFER_TPP