diff options
Diffstat (limited to 'drivers/bluetooth/ringbuffer.hpp')
| -rw-r--r-- | drivers/bluetooth/ringbuffer.hpp | 66 | 
1 files changed, 66 insertions, 0 deletions
| diff --git a/drivers/bluetooth/ringbuffer.hpp b/drivers/bluetooth/ringbuffer.hpp new file mode 100644 index 0000000000..70a3c4881d --- /dev/null +++ b/drivers/bluetooth/ringbuffer.hpp @@ -0,0 +1,66 @@ +#pragma once +// A simple ringbuffer holding Size elements of type T +template <typename T, uint8_t Size> +class RingBuffer { + protected: +  T buf_[Size]; +  uint8_t head_{0}, tail_{0}; + public: +  inline uint8_t nextPosition(uint8_t position) { +    return (position + 1) % Size; +  } + +  inline uint8_t prevPosition(uint8_t position) { +    if (position == 0) { +      return Size - 1; +    } +    return position - 1; +  } + +  inline bool enqueue(const T &item) { +    static_assert(Size > 1, "RingBuffer size must be > 1"); +    uint8_t next = nextPosition(head_); +    if (next == tail_) { +      // Full +      return false; +    } + +    buf_[head_] = item; +    head_ = next; +    return true; +  } + +  inline bool get(T &dest, bool commit = true) { +    auto tail = tail_; +    if (tail == head_) { +      // No more data +      return false; +    } + +    dest = buf_[tail]; +    tail = nextPosition(tail); + +    if (commit) { +      tail_ = tail; +    } +    return true; +  } + +  inline bool empty() const { return head_ == tail_; } + +  inline uint8_t size() const { +    int diff = head_ - tail_; +    if (diff >= 0) { +      return diff; +    } +    return Size + diff; +  } + +  inline T& front() { +    return buf_[tail_]; +  } + +  inline bool peek(T &item) { +    return get(item, false); +  } +}; | 
