2021-07-13 20:22:54 +02:00
|
|
|
#include "fsfw/container/SimpleRingBuffer.h"
|
|
|
|
|
2020-09-04 15:04:53 +02:00
|
|
|
#include <cstring>
|
|
|
|
|
2022-07-25 14:36:18 +02:00
|
|
|
#include "fsfw/FSFW.h"
|
|
|
|
#include "fsfw/serviceinterface.h"
|
|
|
|
|
2022-02-02 10:29:30 +01:00
|
|
|
SimpleRingBuffer::SimpleRingBuffer(const size_t size, bool overwriteOld, 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
|
|
|
}
|
|
|
|
|
2022-02-02 10:29:30 +01:00
|
|
|
SimpleRingBuffer::SimpleRingBuffer(uint8_t* buffer, const size_t size, bool overwriteOld,
|
|
|
|
size_t maxExcessBytes)
|
|
|
|
: RingBufferBase<>(0, size, overwriteOld), buffer(buffer) {
|
|
|
|
if (maxExcessBytes > size) {
|
|
|
|
this->maxExcessBytes = size;
|
|
|
|
} else {
|
|
|
|
this->maxExcessBytes = maxExcessBytes;
|
|
|
|
}
|
2020-09-04 15:04:53 +02:00
|
|
|
}
|
|
|
|
|
2022-02-02 10:29:30 +01:00
|
|
|
SimpleRingBuffer::~SimpleRingBuffer() { delete[] buffer; }
|
2020-09-04 15:04:53 +02:00
|
|
|
|
2022-02-02 10:29:30 +01: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) {
|
2022-08-16 01:08:26 +02:00
|
|
|
return returnvalue::FAILED;
|
2022-02-02 10:29:30 +01:00
|
|
|
}
|
|
|
|
excessBytes = amount - amountTillWrap;
|
2020-09-04 15:04:53 +02:00
|
|
|
}
|
2022-02-02 10:29:30 +01:00
|
|
|
*writePointer = &buffer[write];
|
2022-08-16 01:08:26 +02:00
|
|
|
return returnvalue::OK;
|
2022-02-02 10:29:30 +01:00
|
|
|
} else {
|
2022-08-16 01:08:26 +02:00
|
|
|
return returnvalue::FAILED;
|
2022-02-02 10:29:30 +01:00
|
|
|
}
|
2020-09-04 15:04:53 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void SimpleRingBuffer::confirmBytesWritten(size_t amount) {
|
2022-02-02 10:29:30 +01:00
|
|
|
if (getExcessBytes() > 0) {
|
|
|
|
moveExcessBytesToStart();
|
|
|
|
}
|
|
|
|
incrementWrite(amount);
|
2020-09-04 15:04:53 +02:00
|
|
|
}
|
|
|
|
|
2022-02-02 10:29:30 +01:00
|
|
|
ReturnValue_t SimpleRingBuffer::writeData(const uint8_t* data, size_t amount) {
|
2022-07-25 14:36:18 +02:00
|
|
|
if (data == nullptr) {
|
2022-08-16 01:08:26 +02:00
|
|
|
return returnvalue::FAILED;
|
2022-03-24 20:57:42 +01:00
|
|
|
}
|
2022-07-25 14:36:18 +02:00
|
|
|
if (amount > getMaxSize()) {
|
2022-03-24 11:32:27 +01:00
|
|
|
#if FSFW_VERBOSE_LEVEL >= 1
|
|
|
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
2022-07-25 14:36:18 +02:00
|
|
|
sif::error << "SimpleRingBuffer::writeData: Amount of data too large" << std::endl;
|
2022-03-24 11:32:27 +01:00
|
|
|
#else
|
2022-07-25 14:36:18 +02:00
|
|
|
sif::printError("SimpleRingBuffer::writeData: Amount of data too large\n");
|
2022-03-24 11:32:27 +01:00
|
|
|
#endif
|
|
|
|
#endif
|
2022-08-16 01:08:26 +02:00
|
|
|
return returnvalue::FAILED;
|
2022-03-23 16:48:17 +01:00
|
|
|
}
|
2022-02-02 10:29:30 +01:00
|
|
|
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);
|
2021-01-28 11:50:33 +01:00
|
|
|
} else {
|
2022-02-02 10:29:30 +01:00
|
|
|
memcpy(&buffer[write], data, amountTillWrap);
|
|
|
|
memcpy(buffer, data + amountTillWrap, amount - amountTillWrap);
|
2021-01-28 11:50:33 +01:00
|
|
|
}
|
2022-02-02 10:29:30 +01:00
|
|
|
incrementWrite(amount);
|
2022-08-16 01:08:26 +02:00
|
|
|
return returnvalue::OK;
|
2022-02-02 10:29:30 +01:00
|
|
|
} else {
|
2022-08-16 01:08:26 +02:00
|
|
|
return returnvalue::FAILED;
|
2022-02-02 10:29:30 +01:00
|
|
|
}
|
2020-09-04 15:04:53 +02:00
|
|
|
}
|
|
|
|
|
2022-02-02 10:29:30 +01:00
|
|
|
ReturnValue_t SimpleRingBuffer::readData(uint8_t* data, size_t amount, 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;
|
2021-01-28 11:50:33 +01:00
|
|
|
} else {
|
2022-08-16 01:08:26 +02:00
|
|
|
return returnvalue::FAILED;
|
2021-01-28 11:50:33 +01:00
|
|
|
}
|
2022-02-02 10:29:30 +01:00
|
|
|
}
|
|
|
|
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
|
|
|
|
2022-02-02 10:29:30 +01:00
|
|
|
if (incrementReadPtr) {
|
|
|
|
deleteData(amount, readRemaining);
|
|
|
|
}
|
2022-08-16 01:08:26 +02:00
|
|
|
return returnvalue::OK;
|
2020-09-04 15:04:53 +02:00
|
|
|
}
|
|
|
|
|
2022-02-02 10:29:30 +01:00
|
|
|
size_t SimpleRingBuffer::getExcessBytes() const { return excessBytes; }
|
2020-09-04 15:04:53 +02:00
|
|
|
|
|
|
|
void SimpleRingBuffer::moveExcessBytesToStart() {
|
2022-02-02 10:29:30 +01:00
|
|
|
if (excessBytes > 0) {
|
|
|
|
std::memcpy(buffer, &buffer[size], excessBytes);
|
|
|
|
excessBytes = 0;
|
|
|
|
}
|
2020-09-04 15:04:53 +02:00
|
|
|
}
|
|
|
|
|
2022-02-02 10:29:30 +01:00
|
|
|
ReturnValue_t SimpleRingBuffer::deleteData(size_t amount, bool deleteRemaining,
|
|
|
|
size_t* trueAmount) {
|
|
|
|
size_t availableData = getAvailableReadData(READ_PTR);
|
|
|
|
if (availableData < amount) {
|
|
|
|
if (deleteRemaining) {
|
|
|
|
amount = availableData;
|
|
|
|
} else {
|
2022-08-16 01:08:26 +02:00
|
|
|
return returnvalue::FAILED;
|
2021-01-28 11:50:33 +01:00
|
|
|
}
|
2022-02-02 10:29:30 +01:00
|
|
|
}
|
|
|
|
if (trueAmount != nullptr) {
|
|
|
|
*trueAmount = amount;
|
|
|
|
}
|
|
|
|
incrementRead(amount, READ_PTR);
|
2022-08-16 01:08:26 +02:00
|
|
|
return returnvalue::OK;
|
2020-09-04 15:04:53 +02:00
|
|
|
}
|