fsfw/container/SimpleRingBuffer.cpp

132 lines
3.9 KiB
C++
Raw Normal View History

#include "SimpleRingBuffer.h"
2020-09-04 15:04:53 +02:00
#include <cstring>
SimpleRingBuffer::SimpleRingBuffer(const size_t size, bool overwriteOld,
2021-01-28 11:44:49 +01:00
size_t maxExcessBytes) :
RingBufferBase<>(0, size, overwriteOld),
maxExcessBytes(maxExcessBytes) {
if(maxExcessBytes > size) {
this->maxExcessBytes = size;
}
else {
this->maxExcessBytes = maxExcessBytes;
}
buffer = new uint8_t[size + maxExcessBytes];
2020-09-04 15:04:53 +02:00
}
SimpleRingBuffer::SimpleRingBuffer(uint8_t *buffer, const size_t size,
2021-01-28 11:44:49 +01:00
bool overwriteOld, size_t maxExcessBytes):
2020-09-04 15:04:53 +02:00
RingBufferBase<>(0, size, overwriteOld), buffer(buffer) {
2021-01-28 11:44:49 +01:00
if(maxExcessBytes > size) {
this->maxExcessBytes = size;
}
else {
this->maxExcessBytes = maxExcessBytes;
}
2020-09-04 15:04:53 +02:00
}
SimpleRingBuffer::~SimpleRingBuffer() {
2021-01-28 11:44:49 +01:00
delete[] buffer;
2020-09-04 15:04:53 +02:00
}
ReturnValue_t SimpleRingBuffer::getFreeElement(uint8_t **writePointer,
size_t amount) {
if (availableWriteSpace() >= amount or overwriteOld) {
size_t amountTillWrap = writeTillWrap();
if (amountTillWrap < amount) {
if((amount - amountTillWrap + excessBytes) > maxExcessBytes) {
return HasReturnvaluesIF::RETURN_FAILED;
}
excessBytes = amount - amountTillWrap;
}
*writePointer = &buffer[write];
return HasReturnvaluesIF::RETURN_OK;
}
else {
return HasReturnvaluesIF::RETURN_FAILED;
}
}
void SimpleRingBuffer::confirmBytesWritten(size_t amount) {
2021-01-28 11:44:49 +01:00
if(getExcessBytes() > 0) {
moveExcessBytesToStart();
}
incrementWrite(amount);
2020-09-04 15:04:53 +02:00
}
ReturnValue_t SimpleRingBuffer::writeData(const uint8_t* data,
2021-01-28 11:44:49 +01:00
size_t amount) {
if (availableWriteSpace() >= amount or overwriteOld) {
size_t amountTillWrap = writeTillWrap();
if (amountTillWrap >= amount) {
// remaining size in buffer is sufficient to fit full amount.
memcpy(&buffer[write], data, amount);
}
else {
memcpy(&buffer[write], data, amountTillWrap);
memcpy(buffer, data + amountTillWrap, amount - amountTillWrap);
}
incrementWrite(amount);
return HasReturnvaluesIF::RETURN_OK;
} else {
return HasReturnvaluesIF::RETURN_FAILED;
}
2020-09-04 15:04:53 +02:00
}
ReturnValue_t SimpleRingBuffer::readData(uint8_t* data, size_t amount,
2021-01-28 11:44:49 +01:00
bool incrementReadPtr, bool readRemaining, size_t* trueAmount) {
size_t availableData = getAvailableReadData(READ_PTR);
size_t amountTillWrap = readTillWrap(READ_PTR);
if (availableData < amount) {
if (readRemaining) {
// more data available than amount specified.
amount = availableData;
} else {
return HasReturnvaluesIF::RETURN_FAILED;
}
}
if (trueAmount != nullptr) {
*trueAmount = amount;
}
if (amountTillWrap >= amount) {
memcpy(data, &buffer[read[READ_PTR]], amount);
} else {
memcpy(data, &buffer[read[READ_PTR]], amountTillWrap);
memcpy(data + amountTillWrap, buffer, amount - amountTillWrap);
}
2020-09-04 15:04:53 +02:00
2021-01-28 11:44:49 +01:00
if(incrementReadPtr) {
deleteData(amount, readRemaining);
}
return HasReturnvaluesIF::RETURN_OK;
2020-09-04 15:04:53 +02:00
}
size_t SimpleRingBuffer::getExcessBytes() const {
return excessBytes;
}
void SimpleRingBuffer::moveExcessBytesToStart() {
if(excessBytes > 0) {
std::memcpy(buffer, &buffer[size], excessBytes);
excessBytes = 0;
}
}
ReturnValue_t SimpleRingBuffer::deleteData(size_t amount,
2021-01-28 11:44:49 +01:00
bool deleteRemaining, size_t* trueAmount) {
size_t availableData = getAvailableReadData(READ_PTR);
if (availableData < amount) {
if (deleteRemaining) {
amount = availableData;
} else {
return HasReturnvaluesIF::RETURN_FAILED;
}
}
if (trueAmount != nullptr) {
*trueAmount = amount;
}
incrementRead(amount, READ_PTR);
return HasReturnvaluesIF::RETURN_OK;
2020-09-04 15:04:53 +02:00
}