diff --git a/container/DynamicFIFO.h b/container/DynamicFIFO.h new file mode 100644 index 000000000..abb533308 --- /dev/null +++ b/container/DynamicFIFO.h @@ -0,0 +1,42 @@ +#ifndef FSFW_CONTAINER_DYNAMICFIFO_H_ +#define FSFW_CONTAINER_DYNAMICFIFO_H_ + +#include "FIFOBase.h" +#include + +/** + * @brief Simple First-In-First-Out data structure. The maximum size + * can be set in the constructor. + * @details + * The maximum capacity can be determined at run-time, so this container + * performs dynamic memory allocation! + * The public interface of FIFOBase exposes the user interface for the FIFO. + * @tparam T Entry Type + * @tparam capacity Maximum capacity + */ +template +class DynamicFIFO: public FIFOBase { +public: + DynamicFIFO(size_t maxCapacity): FIFOBase(nullptr, maxCapacity), + fifoVector(maxCapacity) { + // trying to pass the pointer of the uninitialized vector + // to the FIFOBase constructor directly lead to a super evil bug. + // So we do it like this now. + this->setContainer(fifoVector.data()); + }; + + /** + * @brief Custom copy constructor which prevents setting the + * underlying pointer wrong. + */ + DynamicFIFO(const DynamicFIFO& other): FIFOBase(other), + fifoVector(other.maxCapacity) { + this->setContainer(fifoVector.data()); + } + + +private: + std::vector fifoVector; +}; + +#endif /* FSFW_CONTAINER_DYNAMICFIFO_H_ */ diff --git a/container/FIFO.h b/container/FIFO.h index 3172d9d12..19f763fc8 100644 --- a/container/FIFO.h +++ b/container/FIFO.h @@ -1,82 +1,35 @@ -#ifndef FIFO_H_ -#define FIFO_H_ +#ifndef FSFW_CONTAINER_FIFO_H_ +#define FSFW_CONTAINER_FIFO_H_ -#include "../returnvalues/HasReturnvaluesIF.h" +#include "FIFOBase.h" +#include /** - * @brief Simple First-In-First-Out data structure + * @brief Simple First-In-First-Out data structure with size fixed at + * compile time + * @details + * Performs no dynamic memory allocation. + * The public interface of FIFOBase exposes the user interface for the FIFO. * @tparam T Entry Type * @tparam capacity Maximum capacity */ -template -class FIFO { -private: - uint8_t readIndex, writeIndex, currentSize; - T data[capacity]; - - uint8_t next(uint8_t current) { - ++current; - if (current == capacity) { - current = 0; - } - return current; - } +template +class FIFO: public FIFOBase { public: - FIFO() : - readIndex(0), writeIndex(0), currentSize(0) { + FIFO(): FIFOBase(nullptr, capacity) { + this->setContainer(fifoArray.data()); + }; + + /** + * @brief Custom copy constructor to set pointer correctly. + * @param other + */ + FIFO(const FIFO& other): FIFOBase(other) { + this->setContainer(fifoArray.data()); } - bool empty() { - return (currentSize == 0); - } - - bool full() { - return (currentSize == capacity); - } - - uint8_t size(){ - return currentSize; - } - - ReturnValue_t insert(T value) { - if (full()) { - return FULL; - } else { - data[writeIndex] = value; - writeIndex = next(writeIndex); - ++currentSize; - return HasReturnvaluesIF::RETURN_OK; - } - } - - ReturnValue_t retrieve(T *value) { - if (empty()) { - return EMPTY; - } else { - *value = data[readIndex]; - readIndex = next(readIndex); - --currentSize; - return HasReturnvaluesIF::RETURN_OK; - } - } - - ReturnValue_t peek(T * value) { - if(empty()) { - return EMPTY; - } else { - *value = data[readIndex]; - return HasReturnvaluesIF::RETURN_OK; - } - } - - ReturnValue_t pop() { - T value; - return this->retrieve(&value); - } - - static const uint8_t INTERFACE_ID = CLASS_ID::FIFO_CLASS; - static const ReturnValue_t FULL = MAKE_RETURN_CODE(1); - static const ReturnValue_t EMPTY = MAKE_RETURN_CODE(2); +private: + std::array fifoArray; }; -#endif /* FIFO_H_ */ +#endif /* FSFW_CONTAINER_FIFO_H_ */ diff --git a/container/FIFOBase.h b/container/FIFOBase.h new file mode 100644 index 000000000..b744706d4 --- /dev/null +++ b/container/FIFOBase.h @@ -0,0 +1,65 @@ +#ifndef FSFW_CONTAINER_FIFOBASE_H_ +#define FSFW_CONTAINER_FIFOBASE_H_ + +#include "../returnvalues/HasReturnvaluesIF.h" +#include +#include + +template +class FIFOBase { +public: + static const uint8_t INTERFACE_ID = CLASS_ID::FIFO_CLASS; + static const ReturnValue_t FULL = MAKE_RETURN_CODE(1); + static const ReturnValue_t EMPTY = MAKE_RETURN_CODE(2); + + /** Default ctor, takes pointer to first entry of underlying container + * and maximum capacity */ + FIFOBase(T* values, const size_t maxCapacity); + + /** + * Insert value into FIFO + * @param value + * @return + */ + ReturnValue_t insert(T value); + /** + * Retrieve item from FIFO. This removes the item from the FIFO. + * @param value + * @return + */ + ReturnValue_t retrieve(T *value); + /** + * Retrieve item from FIFO without removing it from FIFO. + * @param value + * @return + */ + ReturnValue_t peek(T * value); + /** + * Remove item from FIFO. + * @return + */ + ReturnValue_t pop(); + + bool empty(); + bool full(); + size_t size(); + + + size_t getMaxCapacity() const; + +protected: + void setContainer(T* data); + size_t maxCapacity = 0; + + T* values; + + size_t readIndex = 0; + size_t writeIndex = 0; + size_t currentSize = 0; + + size_t next(size_t current); +}; + +#include "FIFOBase.tpp" + +#endif /* FSFW_CONTAINER_FIFOBASE_H_ */ diff --git a/container/FIFOBase.tpp b/container/FIFOBase.tpp new file mode 100644 index 000000000..d54b3f8f9 --- /dev/null +++ b/container/FIFOBase.tpp @@ -0,0 +1,87 @@ +#ifndef FSFW_CONTAINER_FIFOBASE_TPP_ +#define FSFW_CONTAINER_FIFOBASE_TPP_ + +#ifndef FSFW_CONTAINER_FIFOBASE_H_ +#error Include FIFOBase.h before FIFOBase.tpp! +#endif + +template +inline FIFOBase::FIFOBase(T* values, const size_t maxCapacity): + maxCapacity(maxCapacity), values(values){}; + +template +inline ReturnValue_t FIFOBase::insert(T value) { + if (full()) { + return FULL; + } else { + values[writeIndex] = value; + writeIndex = next(writeIndex); + ++currentSize; + return HasReturnvaluesIF::RETURN_OK; + } +}; + +template +inline ReturnValue_t FIFOBase::retrieve(T* value) { + if (empty()) { + return EMPTY; + } else { + *value = values[readIndex]; + readIndex = next(readIndex); + --currentSize; + return HasReturnvaluesIF::RETURN_OK; + } +}; + +template +inline ReturnValue_t FIFOBase::peek(T* value) { + if(empty()) { + return EMPTY; + } else { + *value = values[readIndex]; + return HasReturnvaluesIF::RETURN_OK; + } +}; + +template +inline ReturnValue_t FIFOBase::pop() { + T value; + return this->retrieve(&value); +}; + +template +inline bool FIFOBase::empty() { + return (currentSize == 0); +}; + +template +inline bool FIFOBase::full() { + return (currentSize == maxCapacity); +} + +template +inline size_t FIFOBase::size() { + return currentSize; +} + +template +inline size_t FIFOBase::next(size_t current) { + ++current; + if (current == maxCapacity) { + current = 0; + } + return current; +} + +template +inline size_t FIFOBase::getMaxCapacity() const { + return maxCapacity; +} + + +template +inline void FIFOBase::setContainer(T *data) { + this->values = data; +} + +#endif diff --git a/tmtcservices/CommandingServiceBase.h b/tmtcservices/CommandingServiceBase.h index c0453f2f2..864a0614b 100644 --- a/tmtcservices/CommandingServiceBase.h +++ b/tmtcservices/CommandingServiceBase.h @@ -1,5 +1,5 @@ -#ifndef FRAMEWORK_TMTCSERVICES_COMMANDINGSERVICEBASE_H_ -#define FRAMEWORK_TMTCSERVICES_COMMANDINGSERVICEBASE_H_ +#ifndef FSFW_TMTCSERVICES_COMMANDINGSERVICEBASE_H_ +#define FSFW_TMTCSERVICES_COMMANDINGSERVICEBASE_H_ #include "../objectmanager/SystemObject.h" #include "../storagemanager/StorageManagerIF.h" @@ -345,4 +345,4 @@ private: void checkTimeout(); }; -#endif /* COMMANDINGSERVICEBASE_H_ */ +#endif /* FSFW_TMTCSERVICES_COMMANDINGSERVICEBASE_H_ */