// SPDX-License-Identifier: MIT /** Copyright (c) 2015 - 2022 Beckhoff Automation GmbH & Co. KG */ #pragma once #include #include #include struct RingBuffer { RingBuffer(size_t N) : dataSize(N + 1), data(new uint8_t[N + 1]), write(data.get()), read(data.get()) {} size_t BytesFree() const { return (write < read) ? read - write - 1 : dataSize - 1 - (write - read); } size_t BytesAvailable() const { return dataSize - BytesFree() - 1; } size_t WriteChunk() const { return (write < read) ? read - write - 1 : data.get() + dataSize - write - (data.get() == read); } void Write(size_t n) { assert(n <= BytesFree()); write = Increment(write, n); } template T ReadFromLittleEndian() { T result = 0; for (size_t i = 0; i < sizeof(T); ++i) { result += (((T)(*read)) << (8 * i)); read = Increment(read, 1); } return result; } void Read(size_t n) { assert(n <= BytesAvailable()); read = Increment(read, n); } private: const size_t dataSize; const std::unique_ptr data; inline uint8_t* Increment(const uint8_t* ptr, size_t n) { return data.get() + ((ptr - data.get() + n) % dataSize); } public: uint8_t* write; const uint8_t* read; };