69 lines
1.4 KiB
C
69 lines
1.4 KiB
C
![]() |
// SPDX-License-Identifier: MIT
|
||
|
/**
|
||
|
Copyright (c) 2015 - 2022 Beckhoff Automation GmbH & Co. KG
|
||
|
*/
|
||
|
|
||
|
#pragma once
|
||
|
|
||
|
#include <cassert>
|
||
|
#include <cstdint>
|
||
|
#include <memory>
|
||
|
|
||
|
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<class T> 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<uint8_t[]> 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;
|
||
|
};
|