tabs replaced by spaces

This commit is contained in:
Robin Müller 2021-01-28 11:44:49 +01:00
parent 76d81b5b49
commit 98f89302c4
19 changed files with 1984 additions and 1984 deletions

View File

@ -6,7 +6,7 @@
#include "../serialize/SerializeIF.h" #include "../serialize/SerializeIF.h"
/** /**
* @brief A List that stores its values in an array. * @brief A List that stores its values in an array.
* @details * @details
* The underlying storage is an array that can be allocated by the class * The underlying storage is an array that can be allocated by the class
* itself or supplied via ctor. * itself or supplied via ctor.
@ -15,237 +15,237 @@
*/ */
template<typename T, typename count_t = uint8_t> template<typename T, typename count_t = uint8_t>
class ArrayList { class ArrayList {
template<typename U, typename count> friend class SerialArrayListAdapter; template<typename U, typename count> friend class SerialArrayListAdapter;
public: public:
static const uint8_t INTERFACE_ID = CLASS_ID::ARRAY_LIST; static const uint8_t INTERFACE_ID = CLASS_ID::ARRAY_LIST;
static const ReturnValue_t FULL = MAKE_RETURN_CODE(0x01); static const ReturnValue_t FULL = MAKE_RETURN_CODE(0x01);
/** /**
* This is the allocating constructor. * This is the allocating constructor.
* It allocates an array of the specified size. * It allocates an array of the specified size.
* @param maxSize * @param maxSize
*/ */
ArrayList(count_t maxSize) : ArrayList(count_t maxSize) :
size(0), maxSize_(maxSize), allocated(true) { size(0), maxSize_(maxSize), allocated(true) {
entries = new T[maxSize]; entries = new T[maxSize];
} }
/** /**
* This is the non-allocating constructor * This is the non-allocating constructor
* *
* It expects a pointer to an array of a certain size and initializes * It expects a pointer to an array of a certain size and initializes
* itself to it. * itself to it.
* *
* @param storage the array to use as backend * @param storage the array to use as backend
* @param maxSize size of storage * @param maxSize size of storage
* @param size size of data already present in storage * @param size size of data already present in storage
*/ */
ArrayList(T *storage, count_t maxSize, count_t size = 0) : ArrayList(T *storage, count_t maxSize, count_t size = 0) :
size(size), entries(storage), maxSize_(maxSize), allocated(false) { size(size), entries(storage), maxSize_(maxSize), allocated(false) {
} }
/** /**
* Copying is forbiden by declaring copy ctor and copy assignment deleted * Copying is forbiden by declaring copy ctor and copy assignment deleted
* It is too ambigous in this case. * It is too ambigous in this case.
* (Allocate a new backend? Use the same? What to do in an modifying call?) * (Allocate a new backend? Use the same? What to do in an modifying call?)
*/ */
ArrayList(const ArrayList& other) = delete; ArrayList(const ArrayList& other) = delete;
const ArrayList& operator=(const ArrayList& other) = delete; const ArrayList& operator=(const ArrayList& other) = delete;
/** /**
* Number of Elements stored in this List * Number of Elements stored in this List
*/ */
count_t size; count_t size;
/** /**
* Destructor, if the allocating constructor was used, it deletes the array. * Destructor, if the allocating constructor was used, it deletes the array.
*/ */
virtual ~ArrayList() { virtual ~ArrayList() {
if (allocated) { if (allocated) {
delete[] entries; delete[] entries;
} }
} }
/** /**
* An Iterator to go trough an ArrayList * An Iterator to go trough an ArrayList
* *
* It stores a pointer to an element and increments the * It stores a pointer to an element and increments the
* pointer when incremented itself. * pointer when incremented itself.
*/ */
class Iterator { class Iterator {
public: public:
/** /**
* Empty ctor, points to NULL * Empty ctor, points to NULL
*/ */
Iterator(): value(0) {} Iterator(): value(0) {}
/** /**
* Initializes the Iterator to point to an element * Initializes the Iterator to point to an element
* *
* @param initialize * @param initialize
*/ */
Iterator(T *initialize) { Iterator(T *initialize) {
value = initialize; value = initialize;
} }
/** /**
* The current element the iterator points to * The current element the iterator points to
*/ */
T *value; T *value;
Iterator& operator++() { Iterator& operator++() {
value++; value++;
return *this; return *this;
} }
Iterator operator++(int) { Iterator operator++(int) {
Iterator tmp(*this); Iterator tmp(*this);
operator++(); operator++();
return tmp; return tmp;
} }
Iterator& operator--() { Iterator& operator--() {
value--; value--;
return *this; return *this;
} }
Iterator operator--(int) { Iterator operator--(int) {
Iterator tmp(*this); Iterator tmp(*this);
operator--(); operator--();
return tmp; return tmp;
} }
T& operator*() { T& operator*() {
return *value; return *value;
} }
const T& operator*() const { const T& operator*() const {
return *value; return *value;
} }
T *operator->() { T *operator->() {
return value; return value;
} }
const T *operator->() const { const T *operator->() const {
return value; return value;
} }
}; };
friend bool operator==(const ArrayList::Iterator& lhs, friend bool operator==(const ArrayList::Iterator& lhs,
const ArrayList::Iterator& rhs) { const ArrayList::Iterator& rhs) {
return (lhs.value == rhs.value); return (lhs.value == rhs.value);
} }
friend bool operator!=(const ArrayList::Iterator& lhs, friend bool operator!=(const ArrayList::Iterator& lhs,
const ArrayList::Iterator& rhs) { const ArrayList::Iterator& rhs) {
return not (lhs.value == rhs.value); return not (lhs.value == rhs.value);
} }
/** /**
* Iterator pointing to the first stored elmement * Iterator pointing to the first stored elmement
* *
* @return Iterator to the first element * @return Iterator to the first element
*/ */
Iterator begin() const { Iterator begin() const {
return Iterator(&entries[0]); return Iterator(&entries[0]);
} }
/** /**
* returns an Iterator pointing to the element after the last stored entry * returns an Iterator pointing to the element after the last stored entry
* *
* @return Iterator to the element after the last entry * @return Iterator to the element after the last entry
*/ */
Iterator end() const { Iterator end() const {
return Iterator(&entries[size]); return Iterator(&entries[size]);
} }
T & operator[](count_t i) const { T & operator[](count_t i) const {
return entries[i]; return entries[i];
} }
/** /**
* The first element * The first element
* *
* @return pointer to the first stored element * @return pointer to the first stored element
*/ */
T *front() { T *front() {
return entries; return entries;
} }
/** /**
* The last element * The last element
* *
* does not return a valid pointer if called on an empty list. * does not return a valid pointer if called on an empty list.
* *
* @return pointer to the last stored element * @return pointer to the last stored element
*/ */
T *back() { T *back() {
return &entries[size - 1]; return &entries[size - 1];
//Alternative solution //Alternative solution
//return const_cast<T*>(static_cast<const T*>(*this).back()); //return const_cast<T*>(static_cast<const T*>(*this).back());
} }
const T* back() const{ const T* back() const{
return &entries[size-1]; return &entries[size-1];
} }
/** /**
* The maximum number of elements this List can contain * The maximum number of elements this List can contain
* *
* @return maximum number of elements * @return maximum number of elements
*/ */
size_t maxSize() const { size_t maxSize() const {
return this->maxSize_; return this->maxSize_;
} }
/** /**
* Insert a new element into the list. * Insert a new element into the list.
* *
* The new element is inserted after the last stored element. * The new element is inserted after the last stored element.
* *
* @param entry * @param entry
* @return * @return
* -@c FULL if the List is full * -@c FULL if the List is full
* -@c RETURN_OK else * -@c RETURN_OK else
*/ */
ReturnValue_t insert(T entry) { ReturnValue_t insert(T entry) {
if (size >= maxSize_) { if (size >= maxSize_) {
return FULL; return FULL;
} }
entries[size] = entry; entries[size] = entry;
++size; ++size;
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
/** /**
* clear the List * clear the List
* *
* This does not actually clear all entries, it only sets the size to 0. * This does not actually clear all entries, it only sets the size to 0.
*/ */
void clear() { void clear() {
size = 0; size = 0;
} }
count_t remaining() { count_t remaining() {
return (maxSize_ - size); return (maxSize_ - size);
} }
protected: protected:
/** /**
* pointer to the array in which the entries are stored * pointer to the array in which the entries are stored
*/ */
T *entries; T *entries;
/** /**
* remembering the maximum size * remembering the maximum size
*/ */
size_t maxSize_; size_t maxSize_;
/** /**
* true if the array was allocated and needs to be deleted in the destructor. * true if the array was allocated and needs to be deleted in the destructor.
*/ */
bool allocated; bool allocated;
}; };

View File

@ -7,65 +7,65 @@
template<typename Tp> template<typename Tp>
class BinaryNode { class BinaryNode {
public: public:
BinaryNode(Tp* setValue) : BinaryNode(Tp* setValue) :
value(setValue), left(NULL), right(NULL), parent(NULL) { value(setValue), left(NULL), right(NULL), parent(NULL) {
} }
Tp *value; Tp *value;
BinaryNode* left; BinaryNode* left;
BinaryNode* right; BinaryNode* right;
BinaryNode* parent; BinaryNode* parent;
}; };
template<typename Tp> template<typename Tp>
class ExplicitNodeIterator { class ExplicitNodeIterator {
public: public:
typedef ExplicitNodeIterator<Tp> _Self; typedef ExplicitNodeIterator<Tp> _Self;
typedef BinaryNode<Tp> _Node; typedef BinaryNode<Tp> _Node;
typedef Tp value_type; typedef Tp value_type;
typedef Tp* pointer; typedef Tp* pointer;
typedef Tp& reference; typedef Tp& reference;
ExplicitNodeIterator() : ExplicitNodeIterator() :
element(NULL) { element(NULL) {
} }
ExplicitNodeIterator(_Node* node) : ExplicitNodeIterator(_Node* node) :
element(node) { element(node) {
} }
BinaryNode<Tp>* element; BinaryNode<Tp>* element;
_Self up() { _Self up() {
return _Self(element->parent); return _Self(element->parent);
} }
_Self left() { _Self left() {
if (element != NULL) { if (element != NULL) {
return _Self(element->left); return _Self(element->left);
} else { } else {
return _Self(NULL); return _Self(NULL);
} }
} }
_Self right() { _Self right() {
if (element != NULL) { if (element != NULL) {
return _Self(element->right); return _Self(element->right);
} else { } else {
return _Self(NULL); return _Self(NULL);
} }
} }
bool operator==(const _Self& __x) const { bool operator==(const _Self& __x) const {
return element == __x.element; return element == __x.element;
} }
bool operator!=(const _Self& __x) const { bool operator!=(const _Self& __x) const {
return element != __x.element; return element != __x.element;
} }
pointer pointer
operator->() const { operator->() const {
if (element != NULL) { if (element != NULL) {
return element->value; return element->value;
} else { } else {
return NULL; return NULL;
} }
} }
pointer operator*() const { pointer operator*() const {
return this->operator->(); return this->operator->();
} }
}; };
@ -75,77 +75,77 @@ public:
template<typename Tp> template<typename Tp>
class BinaryTree { class BinaryTree {
public: public:
typedef ExplicitNodeIterator<Tp> iterator; typedef ExplicitNodeIterator<Tp> iterator;
typedef BinaryNode<Tp> Node; typedef BinaryNode<Tp> Node;
typedef std::pair<iterator, iterator> children; typedef std::pair<iterator, iterator> children;
BinaryTree() : BinaryTree() :
rootNode(NULL) { rootNode(NULL) {
} }
BinaryTree(Node* rootNode) : BinaryTree(Node* rootNode) :
rootNode(rootNode) { rootNode(rootNode) {
} }
iterator begin() const { iterator begin() const {
return iterator(rootNode); return iterator(rootNode);
} }
static iterator end() { static iterator end() {
return iterator(NULL); return iterator(NULL);
} }
iterator insert(bool insertLeft, iterator parentNode, Node* newNode ) { iterator insert(bool insertLeft, iterator parentNode, Node* newNode ) {
newNode->parent = parentNode.element; newNode->parent = parentNode.element;
if (parentNode.element != NULL) { if (parentNode.element != NULL) {
if (insertLeft) { if (insertLeft) {
parentNode.element->left = newNode; parentNode.element->left = newNode;
} else { } else {
parentNode.element->right = newNode; parentNode.element->right = newNode;
} }
} else { } else {
//Insert first element. //Insert first element.
rootNode = newNode; rootNode = newNode;
} }
return iterator(newNode); return iterator(newNode);
} }
//No recursion to children. Needs to be done externally. //No recursion to children. Needs to be done externally.
children erase(iterator node) { children erase(iterator node) {
if (node.element == rootNode) { if (node.element == rootNode) {
//We're root node //We're root node
rootNode = NULL; rootNode = NULL;
} else { } else {
//Delete parent's reference //Delete parent's reference
if (node.up().left() == node) { if (node.up().left() == node) {
node.up().element->left = NULL; node.up().element->left = NULL;
} else { } else {
node.up().element->right = NULL; node.up().element->right = NULL;
} }
} }
return children(node.element->left, node.element->right); return children(node.element->left, node.element->right);
} }
static uint32_t countLeft(iterator start) { static uint32_t countLeft(iterator start) {
if (start == end()) { if (start == end()) {
return 0; return 0;
} }
//We also count the start node itself. //We also count the start node itself.
uint32_t count = 1; uint32_t count = 1;
while (start.left() != end()) { while (start.left() != end()) {
count++; count++;
start = start.left(); start = start.left();
} }
return count; return count;
} }
static uint32_t countRight(iterator start) { static uint32_t countRight(iterator start) {
if (start == end()) { if (start == end()) {
return 0; return 0;
} }
//We also count the start node itself. //We also count the start node itself.
uint32_t count = 1; uint32_t count = 1;
while (start.right() != end()) { while (start.right() != end()) {
count++; count++;
start = start.right(); start = start.right();
} }
return count; return count;
} }
protected: protected:
Node* rootNode; Node* rootNode;
}; };

View File

@ -5,8 +5,8 @@
#include <vector> #include <vector>
/** /**
* @brief Simple First-In-First-Out data structure. The maximum size * @brief Simple First-In-First-Out data structure. The maximum size
* can be set in the constructor. * can be set in the constructor.
* @details * @details
* The maximum capacity can be determined at run-time, so this container * The maximum capacity can be determined at run-time, so this container
* performs dynamic memory allocation! * performs dynamic memory allocation!
@ -17,39 +17,39 @@
template<typename T> template<typename T>
class DynamicFIFO: public FIFOBase<T> { class DynamicFIFO: public FIFOBase<T> {
public: public:
DynamicFIFO(size_t maxCapacity): FIFOBase<T>(nullptr, maxCapacity), DynamicFIFO(size_t maxCapacity): FIFOBase<T>(nullptr, maxCapacity),
fifoVector(maxCapacity) { fifoVector(maxCapacity) {
// trying to pass the pointer of the uninitialized vector // trying to pass the pointer of the uninitialized vector
// to the FIFOBase constructor directly lead to a super evil bug. // to the FIFOBase constructor directly lead to a super evil bug.
// So we do it like this now. // So we do it like this now.
this->setContainer(fifoVector.data()); this->setContainer(fifoVector.data());
}; };
/** /**
* @brief Custom copy constructor which prevents setting the * @brief Custom copy constructor which prevents setting the
* underlying pointer wrong. This function allocates memory! * underlying pointer wrong. This function allocates memory!
* @details This is a very heavy operation so try to avoid this! * @details This is a very heavy operation so try to avoid this!
* *
*/ */
DynamicFIFO(const DynamicFIFO& other): FIFOBase<T>(other), DynamicFIFO(const DynamicFIFO& other): FIFOBase<T>(other),
fifoVector(other.maxCapacity) { fifoVector(other.maxCapacity) {
this->fifoVector = other.fifoVector; this->fifoVector = other.fifoVector;
this->setContainer(fifoVector.data()); this->setContainer(fifoVector.data());
} }
/** /**
* @brief Custom assignment operator * @brief Custom assignment operator
* @details This is a very heavy operation so try to avoid this! * @details This is a very heavy operation so try to avoid this!
* @param other DyamicFIFO to copy from * @param other DyamicFIFO to copy from
*/ */
DynamicFIFO& operator=(const DynamicFIFO& other){ DynamicFIFO& operator=(const DynamicFIFO& other){
FIFOBase<T>::operator=(other); FIFOBase<T>::operator=(other);
this->fifoVector = other.fifoVector; this->fifoVector = other.fifoVector;
this->setContainer(fifoVector.data()); this->setContainer(fifoVector.data());
return *this; return *this;
} }
private: private:
std::vector<T> fifoVector; std::vector<T> fifoVector;
}; };
#endif /* FSFW_CONTAINER_DYNAMICFIFO_H_ */ #endif /* FSFW_CONTAINER_DYNAMICFIFO_H_ */

View File

@ -5,8 +5,8 @@
#include <array> #include <array>
/** /**
* @brief Simple First-In-First-Out data structure with size fixed at * @brief Simple First-In-First-Out data structure with size fixed at
* compile time * compile time
* @details * @details
* Performs no dynamic memory allocation. * Performs no dynamic memory allocation.
* The public interface of FIFOBase exposes the user interface for the FIFO. * The public interface of FIFOBase exposes the user interface for the FIFO.
@ -16,32 +16,32 @@
template<typename T, size_t capacity> template<typename T, size_t capacity>
class FIFO: public FIFOBase<T> { class FIFO: public FIFOBase<T> {
public: public:
FIFO(): FIFOBase<T>(nullptr, capacity) { FIFO(): FIFOBase<T>(nullptr, capacity) {
this->setContainer(fifoArray.data()); this->setContainer(fifoArray.data());
}; };
/** /**
* @brief Custom copy constructor to set pointer correctly. * @brief Custom copy constructor to set pointer correctly.
* @param other * @param other
*/ */
FIFO(const FIFO& other): FIFOBase<T>(other) { FIFO(const FIFO& other): FIFOBase<T>(other) {
this->fifoArray = other.fifoArray; this->fifoArray = other.fifoArray;
this->setContainer(fifoArray.data()); this->setContainer(fifoArray.data());
} }
/** /**
* @brief Custom assignment operator * @brief Custom assignment operator
* @param other * @param other
*/ */
FIFO& operator=(const FIFO& other){ FIFO& operator=(const FIFO& other){
FIFOBase<T>::operator=(other); FIFOBase<T>::operator=(other);
this->fifoArray = other.fifoArray; this->fifoArray = other.fifoArray;
this->setContainer(fifoArray.data()); this->setContainer(fifoArray.data());
return *this; return *this;
} }
private: private:
std::array<T, capacity> fifoArray; std::array<T, capacity> fifoArray;
}; };
#endif /* FSFW_CONTAINER_FIFO_H_ */ #endif /* FSFW_CONTAINER_FIFO_H_ */

View File

@ -8,70 +8,70 @@
template <typename T> template <typename T>
class FIFOBase { class FIFOBase {
public: public:
static const uint8_t INTERFACE_ID = CLASS_ID::FIFO_CLASS; static const uint8_t INTERFACE_ID = CLASS_ID::FIFO_CLASS;
static const ReturnValue_t FULL = MAKE_RETURN_CODE(1); static const ReturnValue_t FULL = MAKE_RETURN_CODE(1);
static const ReturnValue_t EMPTY = MAKE_RETURN_CODE(2); static const ReturnValue_t EMPTY = MAKE_RETURN_CODE(2);
/** Default ctor, takes pointer to first entry of underlying container /** Default ctor, takes pointer to first entry of underlying container
* and maximum capacity */ * and maximum capacity */
FIFOBase(T* values, const size_t maxCapacity); FIFOBase(T* values, const size_t maxCapacity);
/** /**
* Insert value into FIFO * Insert value into FIFO
* @param value * @param value
* @return RETURN_OK on success, FULL if full * @return RETURN_OK on success, FULL if full
*/ */
ReturnValue_t insert(T value); ReturnValue_t insert(T value);
/** /**
* Retrieve item from FIFO. This removes the item from the FIFO. * Retrieve item from FIFO. This removes the item from the FIFO.
* @param value Must point to a valid T * @param value Must point to a valid T
* @return RETURN_OK on success, EMPTY if empty and FAILED if nullptr check failed * @return RETURN_OK on success, EMPTY if empty and FAILED if nullptr check failed
*/ */
ReturnValue_t retrieve(T *value); ReturnValue_t retrieve(T *value);
/** /**
* Retrieve item from FIFO without removing it from FIFO. * Retrieve item from FIFO without removing it from FIFO.
* @param value Must point to a valid T * @param value Must point to a valid T
* @return RETURN_OK on success, EMPTY if empty and FAILED if nullptr check failed * @return RETURN_OK on success, EMPTY if empty and FAILED if nullptr check failed
*/ */
ReturnValue_t peek(T * value); ReturnValue_t peek(T * value);
/** /**
* Remove item from FIFO. * Remove item from FIFO.
* @return RETURN_OK on success, EMPTY if empty * @return RETURN_OK on success, EMPTY if empty
*/ */
ReturnValue_t pop(); ReturnValue_t pop();
/*** /***
* Check if FIFO is empty * Check if FIFO is empty
* @return True if empty, False if not * @return True if empty, False if not
*/ */
bool empty(); bool empty();
/*** /***
* Check if FIFO is Full * Check if FIFO is Full
* @return True if full, False if not * @return True if full, False if not
*/ */
bool full(); bool full();
/*** /***
* Current used size (elements) used * Current used size (elements) used
* @return size_t in elements * @return size_t in elements
*/ */
size_t size(); size_t size();
/*** /***
* Get maximal capacity of fifo * Get maximal capacity of fifo
* @return size_t with max capacity of this fifo * @return size_t with max capacity of this fifo
*/ */
size_t getMaxCapacity() const; size_t getMaxCapacity() const;
protected: protected:
void setContainer(T* data); void setContainer(T* data);
size_t maxCapacity = 0; size_t maxCapacity = 0;
T* values; T* values;
size_t readIndex = 0; size_t readIndex = 0;
size_t writeIndex = 0; size_t writeIndex = 0;
size_t currentSize = 0; size_t currentSize = 0;
size_t next(size_t current); size_t next(size_t current);
}; };
#include "FIFOBase.tpp" #include "FIFOBase.tpp"

View File

@ -7,87 +7,87 @@
template<typename T> template<typename T>
inline FIFOBase<T>::FIFOBase(T* values, const size_t maxCapacity): inline FIFOBase<T>::FIFOBase(T* values, const size_t maxCapacity):
maxCapacity(maxCapacity), values(values){}; maxCapacity(maxCapacity), values(values){};
template<typename T> template<typename T>
inline ReturnValue_t FIFOBase<T>::insert(T value) { inline ReturnValue_t FIFOBase<T>::insert(T value) {
if (full()) { if (full()) {
return FULL; return FULL;
} else { } else {
values[writeIndex] = value; values[writeIndex] = value;
writeIndex = next(writeIndex); writeIndex = next(writeIndex);
++currentSize; ++currentSize;
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
}; };
template<typename T> template<typename T>
inline ReturnValue_t FIFOBase<T>::retrieve(T* value) { inline ReturnValue_t FIFOBase<T>::retrieve(T* value) {
if (empty()) { if (empty()) {
return EMPTY; return EMPTY;
} else { } else {
if (value == nullptr){ if (value == nullptr){
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
*value = values[readIndex]; *value = values[readIndex];
readIndex = next(readIndex); readIndex = next(readIndex);
--currentSize; --currentSize;
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
}; };
template<typename T> template<typename T>
inline ReturnValue_t FIFOBase<T>::peek(T* value) { inline ReturnValue_t FIFOBase<T>::peek(T* value) {
if(empty()) { if(empty()) {
return EMPTY; return EMPTY;
} else { } else {
if (value == nullptr){ if (value == nullptr){
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
*value = values[readIndex]; *value = values[readIndex];
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
}; };
template<typename T> template<typename T>
inline ReturnValue_t FIFOBase<T>::pop() { inline ReturnValue_t FIFOBase<T>::pop() {
T value; T value;
return this->retrieve(&value); return this->retrieve(&value);
}; };
template<typename T> template<typename T>
inline bool FIFOBase<T>::empty() { inline bool FIFOBase<T>::empty() {
return (currentSize == 0); return (currentSize == 0);
}; };
template<typename T> template<typename T>
inline bool FIFOBase<T>::full() { inline bool FIFOBase<T>::full() {
return (currentSize == maxCapacity); return (currentSize == maxCapacity);
} }
template<typename T> template<typename T>
inline size_t FIFOBase<T>::size() { inline size_t FIFOBase<T>::size() {
return currentSize; return currentSize;
} }
template<typename T> template<typename T>
inline size_t FIFOBase<T>::next(size_t current) { inline size_t FIFOBase<T>::next(size_t current) {
++current; ++current;
if (current == maxCapacity) { if (current == maxCapacity) {
current = 0; current = 0;
} }
return current; return current;
} }
template<typename T> template<typename T>
inline size_t FIFOBase<T>::getMaxCapacity() const { inline size_t FIFOBase<T>::getMaxCapacity() const {
return maxCapacity; return maxCapacity;
} }
template<typename T> template<typename T>
inline void FIFOBase<T>::setContainer(T *data) { inline void FIFOBase<T>::setContainer(T *data) {
this->values = data; this->values = data;
} }
#endif #endif

View File

@ -8,30 +8,30 @@
*/ */
template<typename T, size_t MAX_SIZE, typename count_t = uint8_t> template<typename T, size_t MAX_SIZE, typename count_t = uint8_t>
class FixedArrayList: public ArrayList<T, count_t> { class FixedArrayList: public ArrayList<T, count_t> {
static_assert(MAX_SIZE <= (pow(2,sizeof(count_t)*8)-1), "count_t is not large enough to hold MAX_SIZE"); static_assert(MAX_SIZE <= (pow(2,sizeof(count_t)*8)-1), "count_t is not large enough to hold MAX_SIZE");
private: private:
T data[MAX_SIZE]; T data[MAX_SIZE];
public: public:
FixedArrayList() : FixedArrayList() :
ArrayList<T, count_t>(data, MAX_SIZE) { ArrayList<T, count_t>(data, MAX_SIZE) {
} }
FixedArrayList(const FixedArrayList& other) : FixedArrayList(const FixedArrayList& other) :
ArrayList<T, count_t>(data, MAX_SIZE) { ArrayList<T, count_t>(data, MAX_SIZE) {
memcpy(this->data, other.data, sizeof(this->data)); memcpy(this->data, other.data, sizeof(this->data));
this->entries = data; this->entries = data;
this->size = other.size; this->size = other.size;
} }
FixedArrayList& operator=(FixedArrayList other) { FixedArrayList& operator=(FixedArrayList other) {
memcpy(this->data, other.data, sizeof(this->data)); memcpy(this->data, other.data, sizeof(this->data));
this->entries = data; this->entries = data;
this->size = other.size; this->size = other.size;
return *this; return *this;
} }
virtual ~FixedArrayList() { virtual ~FixedArrayList() {
} }
}; };

View File

@ -18,212 +18,212 @@
*/ */
template<typename key_t, typename T> template<typename key_t, typename T>
class FixedMap: public SerializeIF { class FixedMap: public SerializeIF {
static_assert (std::is_trivially_copyable<T>::value or static_assert (std::is_trivially_copyable<T>::value or
std::is_base_of<SerializeIF, T>::value, std::is_base_of<SerializeIF, T>::value,
"Types used in FixedMap must either be trivial copy-able or a " "Types used in FixedMap must either be trivial copy-able or a "
"derived class from SerializeIF to be serialize-able"); "derived class from SerializeIF to be serialize-able");
public: public:
static const uint8_t INTERFACE_ID = CLASS_ID::FIXED_MAP; static const uint8_t INTERFACE_ID = CLASS_ID::FIXED_MAP;
static const ReturnValue_t KEY_ALREADY_EXISTS = MAKE_RETURN_CODE(0x01); static const ReturnValue_t KEY_ALREADY_EXISTS = MAKE_RETURN_CODE(0x01);
static const ReturnValue_t MAP_FULL = MAKE_RETURN_CODE(0x02); static const ReturnValue_t MAP_FULL = MAKE_RETURN_CODE(0x02);
static const ReturnValue_t KEY_DOES_NOT_EXIST = MAKE_RETURN_CODE(0x03); static const ReturnValue_t KEY_DOES_NOT_EXIST = MAKE_RETURN_CODE(0x03);
private: private:
static const key_t EMPTY_SLOT = -1; static const key_t EMPTY_SLOT = -1;
ArrayList<std::pair<key_t, T>, uint32_t> theMap; ArrayList<std::pair<key_t, T>, uint32_t> theMap;
uint32_t _size; uint32_t _size;
uint32_t findIndex(key_t key) const { uint32_t findIndex(key_t key) const {
if (_size == 0) { if (_size == 0) {
return 1; return 1;
} }
uint32_t i = 0; uint32_t i = 0;
for (i = 0; i < _size; ++i) { for (i = 0; i < _size; ++i) {
if (theMap[i].first == key) { if (theMap[i].first == key) {
return i; return i;
} }
} }
return i; return i;
} }
public: public:
FixedMap(uint32_t maxSize) : FixedMap(uint32_t maxSize) :
theMap(maxSize), _size(0) { theMap(maxSize), _size(0) {
} }
class Iterator: public ArrayList<std::pair<key_t, T>, uint32_t>::Iterator { class Iterator: public ArrayList<std::pair<key_t, T>, uint32_t>::Iterator {
public: public:
Iterator() : Iterator() :
ArrayList<std::pair<key_t, T>, uint32_t>::Iterator() { ArrayList<std::pair<key_t, T>, uint32_t>::Iterator() {
} }
Iterator(std::pair<key_t, T> *pair) : Iterator(std::pair<key_t, T> *pair) :
ArrayList<std::pair<key_t, T>, uint32_t>::Iterator(pair) { ArrayList<std::pair<key_t, T>, uint32_t>::Iterator(pair) {
} }
}; };
friend bool operator==(const typename FixedMap::Iterator& lhs, friend bool operator==(const typename FixedMap::Iterator& lhs,
const typename FixedMap::Iterator& rhs) { const typename FixedMap::Iterator& rhs) {
return (lhs.value == rhs.value); return (lhs.value == rhs.value);
} }
friend bool operator!=(const typename FixedMap::Iterator& lhs, friend bool operator!=(const typename FixedMap::Iterator& lhs,
const typename FixedMap::Iterator& rhs) { const typename FixedMap::Iterator& rhs) {
return not (lhs.value == rhs.value); return not (lhs.value == rhs.value);
} }
Iterator begin() const { Iterator begin() const {
return Iterator(&theMap[0]); return Iterator(&theMap[0]);
} }
Iterator end() const { Iterator end() const {
return Iterator(&theMap[_size]); return Iterator(&theMap[_size]);
} }
uint32_t size() const { uint32_t size() const {
return _size; return _size;
} }
ReturnValue_t insert(key_t key, T value, Iterator *storedValue = nullptr) { ReturnValue_t insert(key_t key, T value, Iterator *storedValue = nullptr) {
if (exists(key) == HasReturnvaluesIF::RETURN_OK) { if (exists(key) == HasReturnvaluesIF::RETURN_OK) {
return KEY_ALREADY_EXISTS; return KEY_ALREADY_EXISTS;
} }
if (_size == theMap.maxSize()) { if (_size == theMap.maxSize()) {
return MAP_FULL; return MAP_FULL;
} }
theMap[_size].first = key; theMap[_size].first = key;
theMap[_size].second = value; theMap[_size].second = value;
if (storedValue != nullptr) { if (storedValue != nullptr) {
*storedValue = Iterator(&theMap[_size]); *storedValue = Iterator(&theMap[_size]);
} }
++_size; ++_size;
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
ReturnValue_t insert(std::pair<key_t, T> pair) { ReturnValue_t insert(std::pair<key_t, T> pair) {
return insert(pair.first, pair.second); return insert(pair.first, pair.second);
} }
ReturnValue_t exists(key_t key) const { ReturnValue_t exists(key_t key) const {
ReturnValue_t result = KEY_DOES_NOT_EXIST; ReturnValue_t result = KEY_DOES_NOT_EXIST;
if (findIndex(key) < _size) { if (findIndex(key) < _size) {
result = HasReturnvaluesIF::RETURN_OK; result = HasReturnvaluesIF::RETURN_OK;
} }
return result; return result;
} }
ReturnValue_t erase(Iterator *iter) { ReturnValue_t erase(Iterator *iter) {
uint32_t i; uint32_t i;
if ((i = findIndex((*iter).value->first)) >= _size) { if ((i = findIndex((*iter).value->first)) >= _size) {
return KEY_DOES_NOT_EXIST; return KEY_DOES_NOT_EXIST;
} }
theMap[i] = theMap[_size - 1]; theMap[i] = theMap[_size - 1];
--_size; --_size;
--((*iter).value); --((*iter).value);
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
ReturnValue_t erase(key_t key) { ReturnValue_t erase(key_t key) {
uint32_t i; uint32_t i;
if ((i = findIndex(key)) >= _size) { if ((i = findIndex(key)) >= _size) {
return KEY_DOES_NOT_EXIST; return KEY_DOES_NOT_EXIST;
} }
theMap[i] = theMap[_size - 1]; theMap[i] = theMap[_size - 1];
--_size; --_size;
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
T *findValue(key_t key) const { T *findValue(key_t key) const {
return &theMap[findIndex(key)].second; return &theMap[findIndex(key)].second;
} }
Iterator find(key_t key) const { Iterator find(key_t key) const {
ReturnValue_t result = exists(key); ReturnValue_t result = exists(key);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
return end(); return end();
} }
return Iterator(&theMap[findIndex(key)]); return Iterator(&theMap[findIndex(key)]);
} }
ReturnValue_t find(key_t key, T **value) const { ReturnValue_t find(key_t key, T **value) const {
ReturnValue_t result = exists(key); ReturnValue_t result = exists(key);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
return result; return result;
} }
*value = &theMap[findIndex(key)].second; *value = &theMap[findIndex(key)].second;
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
bool empty() { bool empty() {
if(_size == 0) { if(_size == 0) {
return true; return true;
} }
else { else {
return false; return false;
} }
} }
bool full() { bool full() {
if(_size >= theMap.maxSize()) { if(_size >= theMap.maxSize()) {
return true; return true;
} }
else { else {
return false; return false;
} }
} }
void clear() { void clear() {
_size = 0; _size = 0;
} }
uint32_t maxSize() const { uint32_t maxSize() const {
return theMap.maxSize(); return theMap.maxSize();
} }
virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size, virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size,
size_t maxSize, Endianness streamEndianness) const { size_t maxSize, Endianness streamEndianness) const {
ReturnValue_t result = SerializeAdapter::serialize(&this->_size, ReturnValue_t result = SerializeAdapter::serialize(&this->_size,
buffer, size, maxSize, streamEndianness); buffer, size, maxSize, streamEndianness);
uint32_t i = 0; uint32_t i = 0;
while ((result == HasReturnvaluesIF::RETURN_OK) && (i < this->_size)) { while ((result == HasReturnvaluesIF::RETURN_OK) && (i < this->_size)) {
result = SerializeAdapter::serialize(&theMap[i].first, buffer, result = SerializeAdapter::serialize(&theMap[i].first, buffer,
size, maxSize, streamEndianness); size, maxSize, streamEndianness);
result = SerializeAdapter::serialize(&theMap[i].second, buffer, size, result = SerializeAdapter::serialize(&theMap[i].second, buffer, size,
maxSize, streamEndianness); maxSize, streamEndianness);
++i; ++i;
} }
return result; return result;
} }
virtual size_t getSerializedSize() const { virtual size_t getSerializedSize() const {
uint32_t printSize = sizeof(_size); uint32_t printSize = sizeof(_size);
uint32_t i = 0; uint32_t i = 0;
for (i = 0; i < _size; ++i) { for (i = 0; i < _size; ++i) {
printSize += SerializeAdapter::getSerializedSize( printSize += SerializeAdapter::getSerializedSize(
&theMap[i].first); &theMap[i].first);
printSize += SerializeAdapter::getSerializedSize(&theMap[i].second); printSize += SerializeAdapter::getSerializedSize(&theMap[i].second);
} }
return printSize; return printSize;
} }
virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
Endianness streamEndianness) { Endianness streamEndianness) {
ReturnValue_t result = SerializeAdapter::deSerialize(&this->_size, ReturnValue_t result = SerializeAdapter::deSerialize(&this->_size,
buffer, size, streamEndianness); buffer, size, streamEndianness);
if (this->_size > theMap.maxSize()) { if (this->_size > theMap.maxSize()) {
return SerializeIF::TOO_MANY_ELEMENTS; return SerializeIF::TOO_MANY_ELEMENTS;
} }
uint32_t i = 0; uint32_t i = 0;
while ((result == HasReturnvaluesIF::RETURN_OK) && (i < this->_size)) { while ((result == HasReturnvaluesIF::RETURN_OK) && (i < this->_size)) {
result = SerializeAdapter::deSerialize(&theMap[i].first, buffer, result = SerializeAdapter::deSerialize(&theMap[i].first, buffer,
size, streamEndianness); size, streamEndianness);
result = SerializeAdapter::deSerialize(&theMap[i].second, buffer, size, result = SerializeAdapter::deSerialize(&theMap[i].second, buffer, size,
streamEndianness); streamEndianness);
++i; ++i;
} }
return result; return result;
} }
}; };

View File

@ -34,172 +34,172 @@
template<typename key_t, typename T, typename KEY_COMPARE = std::less<key_t>> template<typename key_t, typename T, typename KEY_COMPARE = std::less<key_t>>
class FixedOrderedMultimap { class FixedOrderedMultimap {
public: public:
static const uint8_t INTERFACE_ID = CLASS_ID::FIXED_MULTIMAP; static const uint8_t INTERFACE_ID = CLASS_ID::FIXED_MULTIMAP;
static const ReturnValue_t MAP_FULL = MAKE_RETURN_CODE(0x01); static const ReturnValue_t MAP_FULL = MAKE_RETURN_CODE(0x01);
static const ReturnValue_t KEY_DOES_NOT_EXIST = MAKE_RETURN_CODE(0x02); static const ReturnValue_t KEY_DOES_NOT_EXIST = MAKE_RETURN_CODE(0x02);
/*** /***
* Constructor which needs a size_t for the maximum allowed size * Constructor which needs a size_t for the maximum allowed size
* *
* Can not be resized during runtime * Can not be resized during runtime
* *
* Allocates memory at construction * Allocates memory at construction
* @param maxSize size_t of Maximum allowed size * @param maxSize size_t of Maximum allowed size
*/ */
FixedOrderedMultimap(size_t maxSize):theMap(maxSize), _size(0){ FixedOrderedMultimap(size_t maxSize):theMap(maxSize), _size(0){
} }
/*** /***
* Virtual destructor frees Memory by deleting its member * Virtual destructor frees Memory by deleting its member
*/ */
virtual ~FixedOrderedMultimap() { virtual ~FixedOrderedMultimap() {
} }
/*** /***
* Special iterator for FixedOrderedMultimap * Special iterator for FixedOrderedMultimap
*/ */
class Iterator: public ArrayList<std::pair<key_t, T>, size_t>::Iterator { class Iterator: public ArrayList<std::pair<key_t, T>, size_t>::Iterator {
public: public:
Iterator() : Iterator() :
ArrayList<std::pair<key_t, T>, size_t>::Iterator() { ArrayList<std::pair<key_t, T>, size_t>::Iterator() {
} }
Iterator(std::pair<key_t, T> *pair) : Iterator(std::pair<key_t, T> *pair) :
ArrayList<std::pair<key_t, T>, size_t>::Iterator(pair) { ArrayList<std::pair<key_t, T>, size_t>::Iterator(pair) {
} }
}; };
/*** /***
* Returns an iterator pointing to the first element * Returns an iterator pointing to the first element
* @return Iterator pointing to first element * @return Iterator pointing to first element
*/ */
Iterator begin() const { Iterator begin() const {
return Iterator(&theMap[0]); return Iterator(&theMap[0]);
} }
/** /**
* Returns an iterator pointing to one element past the end * Returns an iterator pointing to one element past the end
* @return Iterator pointing to one element past the end * @return Iterator pointing to one element past the end
*/ */
Iterator end() const { Iterator end() const {
return Iterator(&theMap[_size]); return Iterator(&theMap[_size]);
} }
/*** /***
* Returns the current size of the map (not maximum size!) * Returns the current size of the map (not maximum size!)
* @return Current size * @return Current size
*/ */
size_t size() const{ size_t size() const{
return _size; return _size;
} }
/** /**
* Clears the map, does not deallocate any memory * Clears the map, does not deallocate any memory
*/ */
void clear(){ void clear(){
_size = 0; _size = 0;
} }
/** /**
* Returns the maximum size of the map * Returns the maximum size of the map
* @return Maximum size of the map * @return Maximum size of the map
*/ */
size_t maxSize() const{ size_t maxSize() const{
return theMap.maxSize(); return theMap.maxSize();
} }
/*** /***
* Used to insert a key and value separately. * Used to insert a key and value separately.
* *
* @param[in] key Key of the new element * @param[in] key Key of the new element
* @param[in] value Value of the new element * @param[in] value Value of the new element
* @param[in/out] (optional) storedValue On success this points to the new value, otherwise a nullptr * @param[in/out] (optional) storedValue On success this points to the new value, otherwise a nullptr
* @return RETURN_OK if insert was successful, MAP_FULL if no space is available * @return RETURN_OK if insert was successful, MAP_FULL if no space is available
*/ */
ReturnValue_t insert(key_t key, T value, Iterator *storedValue = nullptr); ReturnValue_t insert(key_t key, T value, Iterator *storedValue = nullptr);
/*** /***
* Used to insert new pair instead of single values * Used to insert new pair instead of single values
* *
* @param pair Pair to be inserted * @param pair Pair to be inserted
* @return RETURN_OK if insert was successful, MAP_FULL if no space is available * @return RETURN_OK if insert was successful, MAP_FULL if no space is available
*/ */
ReturnValue_t insert(std::pair<key_t, T> pair); ReturnValue_t insert(std::pair<key_t, T> pair);
/*** /***
* Can be used to check if a certain key is in the map * Can be used to check if a certain key is in the map
* @param key Key to be checked * @param key Key to be checked
* @return RETURN_OK if the key exists KEY_DOES_NOT_EXIST otherwise * @return RETURN_OK if the key exists KEY_DOES_NOT_EXIST otherwise
*/ */
ReturnValue_t exists(key_t key) const; ReturnValue_t exists(key_t key) const;
/*** /***
* Used to delete the element in the iterator * Used to delete the element in the iterator
* *
* The iterator will point to the element before or begin(), * The iterator will point to the element before or begin(),
* but never to one element in front of the map. * but never to one element in front of the map.
* *
* @warning The iterator needs to be valid and dereferenceable * @warning The iterator needs to be valid and dereferenceable
* @param[in/out] iter Pointer to iterator to the element that needs to be ereased * @param[in/out] iter Pointer to iterator to the element that needs to be ereased
* @return RETURN_OK if erased, KEY_DOES_NOT_EXIST if the there is no element like this * @return RETURN_OK if erased, KEY_DOES_NOT_EXIST if the there is no element like this
*/ */
ReturnValue_t erase(Iterator *iter); ReturnValue_t erase(Iterator *iter);
/*** /***
* Used to erase by key * Used to erase by key
* @param key Key to be erased * @param key Key to be erased
* @return RETURN_OK if erased, KEY_DOES_NOT_EXIST if the there is no element like this * @return RETURN_OK if erased, KEY_DOES_NOT_EXIST if the there is no element like this
*/ */
ReturnValue_t erase(key_t key); ReturnValue_t erase(key_t key);
/*** /***
* Find returns the first appearance of the key * Find returns the first appearance of the key
* *
* If the key does not exist, it points to end() * If the key does not exist, it points to end()
* *
* @param key Key to search for * @param key Key to search for
* @return Iterator pointing to the first entry of key * @return Iterator pointing to the first entry of key
*/ */
Iterator find(key_t key) const{ Iterator find(key_t key) const{
ReturnValue_t result = exists(key); ReturnValue_t result = exists(key);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
return end(); return end();
} }
return Iterator(&theMap[findFirstIndex(key)]); return Iterator(&theMap[findFirstIndex(key)]);
}; };
/*** /***
* Finds first entry of the given key and returns a * Finds first entry of the given key and returns a
* pointer to the value * pointer to the value
* *
* @param key Key to search for * @param key Key to search for
* @param value Found value * @param value Found value
* @return RETURN_OK if it points to the value, * @return RETURN_OK if it points to the value,
* KEY_DOES_NOT_EXIST if the key is not in the map * KEY_DOES_NOT_EXIST if the key is not in the map
*/ */
ReturnValue_t find(key_t key, T **value) const; ReturnValue_t find(key_t key, T **value) const;
friend bool operator==(const typename FixedOrderedMultimap::Iterator& lhs, friend bool operator==(const typename FixedOrderedMultimap::Iterator& lhs,
const typename FixedOrderedMultimap::Iterator& rhs) { const typename FixedOrderedMultimap::Iterator& rhs) {
return (lhs.value == rhs.value); return (lhs.value == rhs.value);
} }
friend bool operator!=(const typename FixedOrderedMultimap::Iterator& lhs, friend bool operator!=(const typename FixedOrderedMultimap::Iterator& lhs,
const typename FixedOrderedMultimap::Iterator& rhs) { const typename FixedOrderedMultimap::Iterator& rhs) {
return not (lhs.value == rhs.value); return not (lhs.value == rhs.value);
} }
private: private:
typedef KEY_COMPARE compare; typedef KEY_COMPARE compare;
compare myComp; compare myComp;
ArrayList<std::pair<key_t, T>, size_t> theMap; ArrayList<std::pair<key_t, T>, size_t> theMap;
size_t _size; size_t _size;
size_t findFirstIndex(key_t key, size_t startAt = 0) const; size_t findFirstIndex(key_t key, size_t startAt = 0) const;
size_t findNicePlace(key_t key) const; size_t findNicePlace(key_t key) const;
void removeFromPosition(size_t position); void removeFromPosition(size_t position);
}; };
#include "FixedOrderedMultimap.tpp" #include "FixedOrderedMultimap.tpp"

View File

@ -4,105 +4,105 @@
template<typename key_t, typename T, typename KEY_COMPARE> template<typename key_t, typename T, typename KEY_COMPARE>
inline ReturnValue_t FixedOrderedMultimap<key_t, T, KEY_COMPARE>::insert(key_t key, T value, Iterator *storedValue) { inline ReturnValue_t FixedOrderedMultimap<key_t, T, KEY_COMPARE>::insert(key_t key, T value, Iterator *storedValue) {
if (_size == theMap.maxSize()) { if (_size == theMap.maxSize()) {
return MAP_FULL; return MAP_FULL;
} }
size_t position = findNicePlace(key); size_t position = findNicePlace(key);
memmove(static_cast<void*>(&theMap[position + 1]),static_cast<void*>(&theMap[position]), memmove(static_cast<void*>(&theMap[position + 1]),static_cast<void*>(&theMap[position]),
(_size - position) * sizeof(std::pair<key_t,T>)); (_size - position) * sizeof(std::pair<key_t,T>));
theMap[position].first = key; theMap[position].first = key;
theMap[position].second = value; theMap[position].second = value;
++_size; ++_size;
if (storedValue != nullptr) { if (storedValue != nullptr) {
*storedValue = Iterator(&theMap[position]); *storedValue = Iterator(&theMap[position]);
} }
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
template<typename key_t, typename T, typename KEY_COMPARE> template<typename key_t, typename T, typename KEY_COMPARE>
inline ReturnValue_t FixedOrderedMultimap<key_t, T, KEY_COMPARE>::insert(std::pair<key_t, T> pair) { inline ReturnValue_t FixedOrderedMultimap<key_t, T, KEY_COMPARE>::insert(std::pair<key_t, T> pair) {
return insert(pair.first, pair.second); return insert(pair.first, pair.second);
} }
template<typename key_t, typename T, typename KEY_COMPARE> template<typename key_t, typename T, typename KEY_COMPARE>
inline ReturnValue_t FixedOrderedMultimap<key_t, T, KEY_COMPARE>::exists(key_t key) const { inline ReturnValue_t FixedOrderedMultimap<key_t, T, KEY_COMPARE>::exists(key_t key) const {
ReturnValue_t result = KEY_DOES_NOT_EXIST; ReturnValue_t result = KEY_DOES_NOT_EXIST;
if (findFirstIndex(key) < _size) { if (findFirstIndex(key) < _size) {
result = HasReturnvaluesIF::RETURN_OK; result = HasReturnvaluesIF::RETURN_OK;
} }
return result; return result;
} }
template<typename key_t, typename T, typename KEY_COMPARE> template<typename key_t, typename T, typename KEY_COMPARE>
inline ReturnValue_t FixedOrderedMultimap<key_t, T, KEY_COMPARE>::erase(Iterator *iter) { inline ReturnValue_t FixedOrderedMultimap<key_t, T, KEY_COMPARE>::erase(Iterator *iter) {
size_t i; size_t i;
if ((i = findFirstIndex((*iter).value->first)) >= _size) { if ((i = findFirstIndex((*iter).value->first)) >= _size) {
return KEY_DOES_NOT_EXIST; return KEY_DOES_NOT_EXIST;
} }
removeFromPosition(i); removeFromPosition(i);
if (*iter != begin()) { if (*iter != begin()) {
(*iter)--; (*iter)--;
} else { } else {
*iter = begin(); *iter = begin();
} }
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
template<typename key_t, typename T, typename KEY_COMPARE> template<typename key_t, typename T, typename KEY_COMPARE>
inline ReturnValue_t FixedOrderedMultimap<key_t, T, KEY_COMPARE>::erase(key_t key) { inline ReturnValue_t FixedOrderedMultimap<key_t, T, KEY_COMPARE>::erase(key_t key) {
size_t i; size_t i;
if ((i = findFirstIndex(key)) >= _size) { if ((i = findFirstIndex(key)) >= _size) {
return KEY_DOES_NOT_EXIST; return KEY_DOES_NOT_EXIST;
} }
do { do {
removeFromPosition(i); removeFromPosition(i);
i = findFirstIndex(key, i); i = findFirstIndex(key, i);
} while (i < _size); } while (i < _size);
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
template<typename key_t, typename T, typename KEY_COMPARE> template<typename key_t, typename T, typename KEY_COMPARE>
inline ReturnValue_t FixedOrderedMultimap<key_t, T, KEY_COMPARE>::find(key_t key, T **value) const { inline ReturnValue_t FixedOrderedMultimap<key_t, T, KEY_COMPARE>::find(key_t key, T **value) const {
ReturnValue_t result = exists(key); ReturnValue_t result = exists(key);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
return result; return result;
} }
*value = &theMap[findFirstIndex(key)].second; *value = &theMap[findFirstIndex(key)].second;
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
template<typename key_t, typename T, typename KEY_COMPARE> template<typename key_t, typename T, typename KEY_COMPARE>
inline size_t FixedOrderedMultimap<key_t, T, KEY_COMPARE>::findFirstIndex(key_t key, size_t startAt) const { inline size_t FixedOrderedMultimap<key_t, T, KEY_COMPARE>::findFirstIndex(key_t key, size_t startAt) const {
if (startAt >= _size) { if (startAt >= _size) {
return startAt + 1; return startAt + 1;
} }
size_t i = startAt; size_t i = startAt;
for (i = startAt; i < _size; ++i) { for (i = startAt; i < _size; ++i) {
if (theMap[i].first == key) { if (theMap[i].first == key) {
return i; return i;
} }
} }
return i; return i;
} }
template<typename key_t, typename T, typename KEY_COMPARE> template<typename key_t, typename T, typename KEY_COMPARE>
inline size_t FixedOrderedMultimap<key_t, T, KEY_COMPARE>::findNicePlace(key_t key) const { inline size_t FixedOrderedMultimap<key_t, T, KEY_COMPARE>::findNicePlace(key_t key) const {
size_t i = 0; size_t i = 0;
for (i = 0; i < _size; ++i) { for (i = 0; i < _size; ++i) {
if (myComp(key, theMap[i].first)) { if (myComp(key, theMap[i].first)) {
return i; return i;
} }
} }
return i; return i;
} }
template<typename key_t, typename T, typename KEY_COMPARE> template<typename key_t, typename T, typename KEY_COMPARE>
inline void FixedOrderedMultimap<key_t, T, KEY_COMPARE>::removeFromPosition(size_t position) { inline void FixedOrderedMultimap<key_t, T, KEY_COMPARE>::removeFromPosition(size_t position) {
if (_size <= position) { if (_size <= position) {
return; return;
} }
memmove(static_cast<void*>(&theMap[position]), static_cast<void*>(&theMap[position + 1]), memmove(static_cast<void*>(&theMap[position]), static_cast<void*>(&theMap[position + 1]),
(_size - position - 1) * sizeof(std::pair<key_t,T>)); (_size - position - 1) * sizeof(std::pair<key_t,T>));
--_size; --_size;
} }

View File

@ -6,85 +6,85 @@
template<typename T, typename count_t = uint8_t> template<typename T, typename count_t = uint8_t>
class HybridIterator: public LinkedElement<T>::Iterator, class HybridIterator: public LinkedElement<T>::Iterator,
public ArrayList<T, count_t>::Iterator { public ArrayList<T, count_t>::Iterator {
public: public:
HybridIterator() {} HybridIterator() {}
HybridIterator(typename LinkedElement<T>::Iterator *iter) : HybridIterator(typename LinkedElement<T>::Iterator *iter) :
LinkedElement<T>::Iterator(*iter), value(iter->value), LinkedElement<T>::Iterator(*iter), value(iter->value),
linked(true) { linked(true) {
} }
HybridIterator(LinkedElement<T> *start) : HybridIterator(LinkedElement<T> *start) :
LinkedElement<T>::Iterator(start), value(start->value), LinkedElement<T>::Iterator(start), value(start->value),
linked(true) { linked(true) {
} }
HybridIterator(typename ArrayList<T, count_t>::Iterator start, HybridIterator(typename ArrayList<T, count_t>::Iterator start,
typename ArrayList<T, count_t>::Iterator end) : typename ArrayList<T, count_t>::Iterator end) :
ArrayList<T, count_t>::Iterator(start), value(start.value), ArrayList<T, count_t>::Iterator(start), value(start.value),
linked(false), end(end.value) { linked(false), end(end.value) {
if (value == this->end) { if (value == this->end) {
value = NULL; value = NULL;
} }
} }
HybridIterator(T *firstElement, T *lastElement) : HybridIterator(T *firstElement, T *lastElement) :
ArrayList<T, count_t>::Iterator(firstElement), value(firstElement), ArrayList<T, count_t>::Iterator(firstElement), value(firstElement),
linked(false), end(++lastElement) { linked(false), end(++lastElement) {
if (value == end) { if (value == end) {
value = NULL; value = NULL;
} }
} }
HybridIterator& operator++() { HybridIterator& operator++() {
if (linked) { if (linked) {
LinkedElement<T>::Iterator::operator++(); LinkedElement<T>::Iterator::operator++();
if (LinkedElement<T>::Iterator::value != nullptr) { if (LinkedElement<T>::Iterator::value != nullptr) {
value = LinkedElement<T>::Iterator::value->value; value = LinkedElement<T>::Iterator::value->value;
} else { } else {
value = nullptr; value = nullptr;
} }
} else { } else {
ArrayList<T, count_t>::Iterator::operator++(); ArrayList<T, count_t>::Iterator::operator++();
value = ArrayList<T, count_t>::Iterator::value; value = ArrayList<T, count_t>::Iterator::value;
if (value == end) { if (value == end) {
value = nullptr; value = nullptr;
} }
} }
return *this; return *this;
} }
HybridIterator operator++(int) { HybridIterator operator++(int) {
HybridIterator tmp(*this); HybridIterator tmp(*this);
operator++(); operator++();
return tmp; return tmp;
} }
bool operator==(const HybridIterator& other) const { bool operator==(const HybridIterator& other) const {
return value == other.value; return value == other.value;
} }
bool operator!=(const HybridIterator& other) const { bool operator!=(const HybridIterator& other) const {
return !(*this == other); return !(*this == other);
} }
T operator*() { T operator*() {
return *value; return *value;
} }
T *operator->() { T *operator->() {
return value; return value;
} }
T* value = nullptr; T* value = nullptr;
private: private:
bool linked = false; bool linked = false;
T *end = nullptr; T *end = nullptr;
}; };
#endif /* FRAMEWORK_CONTAINER_HYBRIDITERATOR_H_ */ #endif /* FRAMEWORK_CONTAINER_HYBRIDITERATOR_H_ */

File diff suppressed because it is too large Load Diff

View File

@ -22,50 +22,50 @@
*/ */
class PlacementFactory { class PlacementFactory {
public: public:
PlacementFactory(StorageManagerIF* backend) : PlacementFactory(StorageManagerIF* backend) :
dataBackend(backend) { dataBackend(backend) {
} }
/*** /***
* Generates an object of type T in the backend storage. * Generates an object of type T in the backend storage.
* *
* @warning Do not use with any Type that allocates memory internally! * @warning Do not use with any Type that allocates memory internally!
* *
* @tparam T Type of Object * @tparam T Type of Object
* @param args Constructor Arguments to be passed * @param args Constructor Arguments to be passed
* @return A pointer to the new object or a nullptr in case of failure * @return A pointer to the new object or a nullptr in case of failure
*/ */
template<typename T, typename ... Args> template<typename T, typename ... Args>
T* generate(Args&&... args) { T* generate(Args&&... args) {
store_address_t tempId; store_address_t tempId;
uint8_t* pData = nullptr; uint8_t* pData = nullptr;
ReturnValue_t result = dataBackend->getFreeElement(&tempId, sizeof(T), ReturnValue_t result = dataBackend->getFreeElement(&tempId, sizeof(T),
&pData); &pData);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
return nullptr; return nullptr;
} }
T* temp = new (pData) T(std::forward<Args>(args)...); T* temp = new (pData) T(std::forward<Args>(args)...);
return temp; return temp;
} }
/*** /***
* Function to destroy the object allocated with generate and free space in backend. * Function to destroy the object allocated with generate and free space in backend.
* This must be called by the user. * This must be called by the user.
* *
* @param thisElement Element to be destroyed * @param thisElement Element to be destroyed
* @return RETURN_OK if the element was destroyed, different errors on failure * @return RETURN_OK if the element was destroyed, different errors on failure
*/ */
template<typename T> template<typename T>
ReturnValue_t destroy(T* thisElement) { ReturnValue_t destroy(T* thisElement) {
if (thisElement == nullptr){ if (thisElement == nullptr){
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
//Need to call destructor first, in case something was allocated by the object (shouldn't do that, however). //Need to call destructor first, in case something was allocated by the object (shouldn't do that, however).
thisElement->~T(); thisElement->~T();
uint8_t* pointer = (uint8_t*) (thisElement); uint8_t* pointer = (uint8_t*) (thisElement);
return dataBackend->deleteData(pointer, sizeof(T)); return dataBackend->deleteData(pointer, sizeof(T));
} }
private: private:
StorageManagerIF* dataBackend; StorageManagerIF* dataBackend;
}; };
#endif /* FRAMEWORK_CONTAINER_PLACEMENTFACTORY_H_ */ #endif /* FRAMEWORK_CONTAINER_PLACEMENTFACTORY_H_ */

View File

@ -7,107 +7,107 @@
template<uint8_t N_READ_PTRS = 1> template<uint8_t N_READ_PTRS = 1>
class RingBufferBase { class RingBufferBase {
public: public:
RingBufferBase(size_t startAddress, const size_t size, bool overwriteOld) : RingBufferBase(size_t startAddress, const size_t size, bool overwriteOld) :
start(startAddress), write(startAddress), size(size), start(startAddress), write(startAddress), size(size),
overwriteOld(overwriteOld) { overwriteOld(overwriteOld) {
for (uint8_t count = 0; count < N_READ_PTRS; count++) { for (uint8_t count = 0; count < N_READ_PTRS; count++) {
read[count] = startAddress; read[count] = startAddress;
} }
} }
virtual ~RingBufferBase() {} virtual ~RingBufferBase() {}
bool isFull(uint8_t n = 0) { bool isFull(uint8_t n = 0) {
return (availableWriteSpace(n) == 0); return (availableWriteSpace(n) == 0);
} }
bool isEmpty(uint8_t n = 0) { bool isEmpty(uint8_t n = 0) {
return (getAvailableReadData(n) == 0); return (getAvailableReadData(n) == 0);
} }
size_t getAvailableReadData(uint8_t n = 0) const { size_t getAvailableReadData(uint8_t n = 0) const {
return ((write + size) - read[n]) % size; return ((write + size) - read[n]) % size;
} }
size_t availableWriteSpace(uint8_t n = 0) const { size_t availableWriteSpace(uint8_t n = 0) const {
//One less to avoid ambiguous full/empty problem. //One less to avoid ambiguous full/empty problem.
return (((read[n] + size) - write - 1) % size); return (((read[n] + size) - write - 1) % size);
} }
bool overwritesOld() const { bool overwritesOld() const {
return overwriteOld; return overwriteOld;
} }
size_t getMaxSize() const { size_t getMaxSize() const {
return size - 1; return size - 1;
} }
void clear() { void clear() {
write = start; write = start;
for (uint8_t count = 0; count < N_READ_PTRS; count++) { for (uint8_t count = 0; count < N_READ_PTRS; count++) {
read[count] = start; read[count] = start;
} }
} }
size_t writeTillWrap() { size_t writeTillWrap() {
return (start + size) - write; return (start + size) - write;
} }
size_t readTillWrap(uint8_t n = 0) { size_t readTillWrap(uint8_t n = 0) {
return (start + size) - read[n]; return (start + size) - read[n];
} }
size_t getStart() const { size_t getStart() const {
return start; return start;
} }
protected: protected:
const size_t start; const size_t start;
size_t write; size_t write;
size_t read[N_READ_PTRS]; size_t read[N_READ_PTRS];
const size_t size; const size_t size;
const bool overwriteOld; const bool overwriteOld;
void incrementWrite(uint32_t amount) { void incrementWrite(uint32_t amount) {
write = ((write + amount - start) % size) + start; write = ((write + amount - start) % size) + start;
} }
void incrementRead(uint32_t amount, uint8_t n = 0) { void incrementRead(uint32_t amount, uint8_t n = 0) {
read[n] = ((read[n] + amount - start) % size) + start; read[n] = ((read[n] + amount - start) % size) + start;
} }
ReturnValue_t readData(uint32_t amount, uint8_t n = 0) { ReturnValue_t readData(uint32_t amount, uint8_t n = 0) {
if (getAvailableReadData(n) >= amount) { if (getAvailableReadData(n) >= amount) {
incrementRead(amount, n); incrementRead(amount, n);
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} else { } else {
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
} }
ReturnValue_t writeData(uint32_t amount) { ReturnValue_t writeData(uint32_t amount) {
if (availableWriteSpace() >= amount or overwriteOld) { if (availableWriteSpace() >= amount or overwriteOld) {
incrementWrite(amount); incrementWrite(amount);
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} else { } else {
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
} }
size_t getRead(uint8_t n = 0) const { size_t getRead(uint8_t n = 0) const {
return read[n]; return read[n];
} }
void setRead(uint32_t read, uint8_t n = 0) { void setRead(uint32_t read, uint8_t n = 0) {
if (read >= start && read < (start+size)) { if (read >= start && read < (start+size)) {
this->read[n] = read; this->read[n] = read;
} }
} }
uint32_t getWrite() const { uint32_t getWrite() const {
return write; return write;
} }
void setWrite(uint32_t write) { void setWrite(uint32_t write) {
this->write = write; this->write = write;
} }
}; };
#endif /* FSFW_CONTAINER_RINGBUFFERBASE_H_ */ #endif /* FSFW_CONTAINER_RINGBUFFERBASE_H_ */

View File

@ -3,23 +3,23 @@
#include "../ipc/MutexHelper.h" #include "../ipc/MutexHelper.h"
SharedRingBuffer::SharedRingBuffer(object_id_t objectId, const size_t size, SharedRingBuffer::SharedRingBuffer(object_id_t objectId, const size_t size,
bool overwriteOld, size_t maxExcessBytes): bool overwriteOld, size_t maxExcessBytes):
SystemObject(objectId), SimpleRingBuffer(size, overwriteOld, SystemObject(objectId), SimpleRingBuffer(size, overwriteOld,
maxExcessBytes) { maxExcessBytes) {
mutex = MutexFactory::instance()->createMutex(); mutex = MutexFactory::instance()->createMutex();
} }
SharedRingBuffer::SharedRingBuffer(object_id_t objectId, uint8_t *buffer, SharedRingBuffer::SharedRingBuffer(object_id_t objectId, uint8_t *buffer,
const size_t size, bool overwriteOld, size_t maxExcessBytes): const size_t size, bool overwriteOld, size_t maxExcessBytes):
SystemObject(objectId), SimpleRingBuffer(buffer, size, overwriteOld, SystemObject(objectId), SimpleRingBuffer(buffer, size, overwriteOld,
maxExcessBytes) { maxExcessBytes) {
mutex = MutexFactory::instance()->createMutex(); mutex = MutexFactory::instance()->createMutex();
} }
void SharedRingBuffer::setToUseReceiveSizeFIFO(size_t fifoDepth) { void SharedRingBuffer::setToUseReceiveSizeFIFO(size_t fifoDepth) {
this->fifoDepth = fifoDepth; this->fifoDepth = fifoDepth;
} }
ReturnValue_t SharedRingBuffer::lockRingBufferMutex( ReturnValue_t SharedRingBuffer::lockRingBufferMutex(
@ -38,20 +38,20 @@ MutexIF* SharedRingBuffer::getMutexHandle() const {
} }
ReturnValue_t SharedRingBuffer::initialize() { ReturnValue_t SharedRingBuffer::initialize() {
if(fifoDepth > 0) { if(fifoDepth > 0) {
receiveSizesFIFO = new DynamicFIFO<size_t>(fifoDepth); receiveSizesFIFO = new DynamicFIFO<size_t>(fifoDepth);
} }
return SystemObject::initialize(); return SystemObject::initialize();
} }
DynamicFIFO<size_t>* SharedRingBuffer::getReceiveSizesFIFO() { DynamicFIFO<size_t>* SharedRingBuffer::getReceiveSizesFIFO() {
if(receiveSizesFIFO == nullptr) { if(receiveSizesFIFO == nullptr) {
// Configuration error. // Configuration error.
#if FSFW_CPP_OSTREAM_ENABLED == 1 #if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "SharedRingBuffer::getReceiveSizesFIFO: Ring buffer" sif::warning << "SharedRingBuffer::getReceiveSizesFIFO: Ring buffer"
<< " was not configured to have sizes FIFO, returning nullptr!" << " was not configured to have sizes FIFO, returning nullptr!"
<< std::endl; << std::endl;
#endif #endif
} }
return receiveSizesFIFO; return receiveSizesFIFO;
} }

View File

@ -15,76 +15,76 @@
* and unlock operations. * and unlock operations.
*/ */
class SharedRingBuffer: public SystemObject, class SharedRingBuffer: public SystemObject,
public SimpleRingBuffer { public SimpleRingBuffer {
public: public:
/** /**
* This constructor allocates a new internal buffer with the supplied size. * This constructor allocates a new internal buffer with the supplied size.
* @param size * @param size
* @param overwriteOld * @param overwriteOld
* If the ring buffer is overflowing at a write operartion, the oldest data * If the ring buffer is overflowing at a write operartion, the oldest data
* will be overwritten. * will be overwritten.
*/ */
SharedRingBuffer(object_id_t objectId, const size_t size, SharedRingBuffer(object_id_t objectId, const size_t size,
bool overwriteOld, size_t maxExcessBytes); bool overwriteOld, size_t maxExcessBytes);
/** /**
* @brief This function can be used to add an optional FIFO to the class * @brief This function can be used to add an optional FIFO to the class
* @details * @details
* This FIFO will be allocated in the initialize function (and will * This FIFO will be allocated in the initialize function (and will
* have a fixed maximum size after that). It can be used to store * have a fixed maximum size after that). It can be used to store
* values like packet sizes, for example for a shared ring buffer * values like packet sizes, for example for a shared ring buffer
* used by producer/consumer tasks. * used by producer/consumer tasks.
*/ */
void setToUseReceiveSizeFIFO(size_t fifoDepth); void setToUseReceiveSizeFIFO(size_t fifoDepth);
/** /**
* This constructor takes an external buffer with the specified size. * This constructor takes an external buffer with the specified size.
* @param buffer * @param buffer
* @param size * @param size
* @param overwriteOld * @param overwriteOld
* If the ring buffer is overflowing at a write operartion, the oldest data * If the ring buffer is overflowing at a write operartion, the oldest data
* will be overwritten. * will be overwritten.
*/ */
SharedRingBuffer(object_id_t objectId, uint8_t* buffer, const size_t size, SharedRingBuffer(object_id_t objectId, uint8_t* buffer, const size_t size,
bool overwriteOld, size_t maxExcessBytes); bool overwriteOld, size_t maxExcessBytes);
/** /**
* Unless a read-only constant value is read, all operations on the * Unless a read-only constant value is read, all operations on the
* shared ring buffer should be protected by calling this function. * shared ring buffer should be protected by calling this function.
* @param timeoutType * @param timeoutType
* @param timeout * @param timeout
* @return * @return
*/ */
virtual ReturnValue_t lockRingBufferMutex(MutexIF::TimeoutType timeoutType, virtual ReturnValue_t lockRingBufferMutex(MutexIF::TimeoutType timeoutType,
dur_millis_t timeout); dur_millis_t timeout);
/** /**
* Any locked mutex also has to be unlocked, otherwise, access to the * Any locked mutex also has to be unlocked, otherwise, access to the
* shared ring buffer will be blocked. * shared ring buffer will be blocked.
* @return * @return
*/ */
virtual ReturnValue_t unlockRingBufferMutex(); virtual ReturnValue_t unlockRingBufferMutex();
/** /**
* The mutex handle can be accessed directly, for example to perform * The mutex handle can be accessed directly, for example to perform
* the lock with the #MutexHelper for a RAII compliant lock operation. * the lock with the #MutexHelper for a RAII compliant lock operation.
* @return * @return
*/ */
MutexIF* getMutexHandle() const; MutexIF* getMutexHandle() const;
ReturnValue_t initialize() override; ReturnValue_t initialize() override;
/** /**
* If the shared ring buffer was configured to have a sizes FIFO, a handle * If the shared ring buffer was configured to have a sizes FIFO, a handle
* to that FIFO can be retrieved with this function. * to that FIFO can be retrieved with this function.
* Do not forget to protect access with a lock if required! * Do not forget to protect access with a lock if required!
* @return * @return
*/ */
DynamicFIFO<size_t>* getReceiveSizesFIFO(); DynamicFIFO<size_t>* getReceiveSizesFIFO();
private: private:
MutexIF* mutex = nullptr; MutexIF* mutex = nullptr;
size_t fifoDepth = 0; size_t fifoDepth = 0;
DynamicFIFO<size_t>* receiveSizesFIFO = nullptr; DynamicFIFO<size_t>* receiveSizesFIFO = nullptr;
}; };

View File

@ -2,31 +2,31 @@
#include <cstring> #include <cstring>
SimpleRingBuffer::SimpleRingBuffer(const size_t size, bool overwriteOld, SimpleRingBuffer::SimpleRingBuffer(const size_t size, bool overwriteOld,
size_t maxExcessBytes) : size_t maxExcessBytes) :
RingBufferBase<>(0, size, overwriteOld), RingBufferBase<>(0, size, overwriteOld),
maxExcessBytes(maxExcessBytes) { maxExcessBytes(maxExcessBytes) {
if(maxExcessBytes > size) { if(maxExcessBytes > size) {
this->maxExcessBytes = size; this->maxExcessBytes = size;
} }
else { else {
this->maxExcessBytes = maxExcessBytes; this->maxExcessBytes = maxExcessBytes;
} }
buffer = new uint8_t[size + maxExcessBytes]; buffer = new uint8_t[size + maxExcessBytes];
} }
SimpleRingBuffer::SimpleRingBuffer(uint8_t *buffer, const size_t size, SimpleRingBuffer::SimpleRingBuffer(uint8_t *buffer, const size_t size,
bool overwriteOld, size_t maxExcessBytes): bool overwriteOld, size_t maxExcessBytes):
RingBufferBase<>(0, size, overwriteOld), buffer(buffer) { RingBufferBase<>(0, size, overwriteOld), buffer(buffer) {
if(maxExcessBytes > size) { if(maxExcessBytes > size) {
this->maxExcessBytes = size; this->maxExcessBytes = size;
} }
else { else {
this->maxExcessBytes = maxExcessBytes; this->maxExcessBytes = maxExcessBytes;
} }
} }
SimpleRingBuffer::~SimpleRingBuffer() { SimpleRingBuffer::~SimpleRingBuffer() {
delete[] buffer; delete[] buffer;
} }
ReturnValue_t SimpleRingBuffer::getFreeElement(uint8_t **writePointer, ReturnValue_t SimpleRingBuffer::getFreeElement(uint8_t **writePointer,
@ -48,58 +48,58 @@ ReturnValue_t SimpleRingBuffer::getFreeElement(uint8_t **writePointer,
} }
void SimpleRingBuffer::confirmBytesWritten(size_t amount) { void SimpleRingBuffer::confirmBytesWritten(size_t amount) {
if(getExcessBytes() > 0) { if(getExcessBytes() > 0) {
moveExcessBytesToStart(); moveExcessBytesToStart();
} }
incrementWrite(amount); incrementWrite(amount);
} }
ReturnValue_t SimpleRingBuffer::writeData(const uint8_t* data, ReturnValue_t SimpleRingBuffer::writeData(const uint8_t* data,
size_t amount) { size_t amount) {
if (availableWriteSpace() >= amount or overwriteOld) { if (availableWriteSpace() >= amount or overwriteOld) {
size_t amountTillWrap = writeTillWrap(); size_t amountTillWrap = writeTillWrap();
if (amountTillWrap >= amount) { if (amountTillWrap >= amount) {
// remaining size in buffer is sufficient to fit full amount. // remaining size in buffer is sufficient to fit full amount.
memcpy(&buffer[write], data, amount); memcpy(&buffer[write], data, amount);
} }
else { else {
memcpy(&buffer[write], data, amountTillWrap); memcpy(&buffer[write], data, amountTillWrap);
memcpy(buffer, data + amountTillWrap, amount - amountTillWrap); memcpy(buffer, data + amountTillWrap, amount - amountTillWrap);
} }
incrementWrite(amount); incrementWrite(amount);
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} else { } else {
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
} }
ReturnValue_t SimpleRingBuffer::readData(uint8_t* data, size_t amount, ReturnValue_t SimpleRingBuffer::readData(uint8_t* data, size_t amount,
bool incrementReadPtr, bool readRemaining, size_t* trueAmount) { bool incrementReadPtr, bool readRemaining, size_t* trueAmount) {
size_t availableData = getAvailableReadData(READ_PTR); size_t availableData = getAvailableReadData(READ_PTR);
size_t amountTillWrap = readTillWrap(READ_PTR); size_t amountTillWrap = readTillWrap(READ_PTR);
if (availableData < amount) { if (availableData < amount) {
if (readRemaining) { if (readRemaining) {
// more data available than amount specified. // more data available than amount specified.
amount = availableData; amount = availableData;
} else { } else {
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
} }
if (trueAmount != nullptr) { if (trueAmount != nullptr) {
*trueAmount = amount; *trueAmount = amount;
} }
if (amountTillWrap >= amount) { if (amountTillWrap >= amount) {
memcpy(data, &buffer[read[READ_PTR]], amount); memcpy(data, &buffer[read[READ_PTR]], amount);
} else { } else {
memcpy(data, &buffer[read[READ_PTR]], amountTillWrap); memcpy(data, &buffer[read[READ_PTR]], amountTillWrap);
memcpy(data + amountTillWrap, buffer, amount - amountTillWrap); memcpy(data + amountTillWrap, buffer, amount - amountTillWrap);
} }
if(incrementReadPtr) { if(incrementReadPtr) {
deleteData(amount, readRemaining); deleteData(amount, readRemaining);
} }
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
size_t SimpleRingBuffer::getExcessBytes() const { size_t SimpleRingBuffer::getExcessBytes() const {
@ -114,18 +114,18 @@ void SimpleRingBuffer::moveExcessBytesToStart() {
} }
ReturnValue_t SimpleRingBuffer::deleteData(size_t amount, ReturnValue_t SimpleRingBuffer::deleteData(size_t amount,
bool deleteRemaining, size_t* trueAmount) { bool deleteRemaining, size_t* trueAmount) {
size_t availableData = getAvailableReadData(READ_PTR); size_t availableData = getAvailableReadData(READ_PTR);
if (availableData < amount) { if (availableData < amount) {
if (deleteRemaining) { if (deleteRemaining) {
amount = availableData; amount = availableData;
} else { } else {
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
} }
if (trueAmount != nullptr) { if (trueAmount != nullptr) {
*trueAmount = amount; *trueAmount = amount;
} }
incrementRead(amount, READ_PTR); incrementRead(amount, READ_PTR);
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }

View File

@ -5,7 +5,7 @@
#include <cstddef> #include <cstddef>
/** /**
* @brief Circular buffer implementation, useful for buffering * @brief Circular buffer implementation, useful for buffering
* into data streams. * into data streams.
* @details * @details
* Note that the deleteData() has to be called to increment the read pointer. * Note that the deleteData() has to be called to increment the read pointer.
@ -25,104 +25,104 @@ public:
* with getFreeElement. * with getFreeElement.
* *
*/ */
SimpleRingBuffer(const size_t size, bool overwriteOld, SimpleRingBuffer(const size_t size, bool overwriteOld,
size_t maxExcessBytes = 0); size_t maxExcessBytes = 0);
/** /**
* This constructor takes an external buffer with the specified size. * This constructor takes an external buffer with the specified size.
* @param buffer * @param buffer
* @param size * @param size
* @param overwriteOld * @param overwriteOld
* If the ring buffer is overflowing at a write operartion, the oldest data * If the ring buffer is overflowing at a write operartion, the oldest data
* will be overwritten. * will be overwritten.
* @param maxExcessBytes * @param maxExcessBytes
* If the buffer can accomodate additional bytes for contigous write * If the buffer can accomodate additional bytes for contigous write
* operations with getFreeElement, this is the maximum allowed additional * operations with getFreeElement, this is the maximum allowed additional
* size * size
*/ */
SimpleRingBuffer(uint8_t* buffer, const size_t size, bool overwriteOld, SimpleRingBuffer(uint8_t* buffer, const size_t size, bool overwriteOld,
size_t maxExcessBytes = 0); size_t maxExcessBytes = 0);
virtual ~SimpleRingBuffer(); virtual ~SimpleRingBuffer();
/** /**
* Write to circular buffer and increment write pointer by amount. * Write to circular buffer and increment write pointer by amount.
* @param data * @param data
* @param amount * @param amount
* @return -@c RETURN_OK if write operation was successfull * @return -@c RETURN_OK if write operation was successfull
* -@c RETURN_FAILED if * -@c RETURN_FAILED if
*/ */
ReturnValue_t writeData(const uint8_t* data, size_t amount); ReturnValue_t writeData(const uint8_t* data, size_t amount);
/** /**
* Returns a pointer to a free element. If the remaining buffer is * Returns a pointer to a free element. If the remaining buffer is
* not large enough, the data will be written past the actual size * not large enough, the data will be written past the actual size
* and the amount of excess bytes will be cached. This function * and the amount of excess bytes will be cached. This function
* does not increment the write pointer! * does not increment the write pointer!
* @param writePointer Pointer to a pointer which can be used to write * @param writePointer Pointer to a pointer which can be used to write
* contiguous blocks into the ring buffer * contiguous blocks into the ring buffer
* @param amount * @param amount
* @return * @return
*/ */
ReturnValue_t getFreeElement(uint8_t** writePointer, size_t amount); ReturnValue_t getFreeElement(uint8_t** writePointer, size_t amount);
/** /**
* This increments the write pointer and also copies the excess bytes * This increments the write pointer and also copies the excess bytes
* to the beginning. It should be called if the write operation * to the beginning. It should be called if the write operation
* conducted after calling getFreeElement() was performed. * conducted after calling getFreeElement() was performed.
* @return * @return
*/ */
void confirmBytesWritten(size_t amount); void confirmBytesWritten(size_t amount);
virtual size_t getExcessBytes() const; virtual size_t getExcessBytes() const;
/** /**
* Helper functions which moves any excess bytes to the start * Helper functions which moves any excess bytes to the start
* of the ring buffer. * of the ring buffer.
* @return * @return
*/ */
virtual void moveExcessBytesToStart(); virtual void moveExcessBytesToStart();
/** /**
* Read from circular buffer at read pointer. * Read from circular buffer at read pointer.
* @param data * @param data
* @param amount * @param amount
* @param incrementReadPtr * @param incrementReadPtr
* If this is set to true, the read pointer will be incremented. * If this is set to true, the read pointer will be incremented.
* If readRemaining is set to true, the read pointer will be incremented * If readRemaining is set to true, the read pointer will be incremented
* accordingly. * accordingly.
* @param readRemaining * @param readRemaining
* If this is set to true, the data will be read even if the amount * If this is set to true, the data will be read even if the amount
* specified exceeds the read data available. * specified exceeds the read data available.
* @param trueAmount [out] * @param trueAmount [out]
* If readRemaining was set to true, the true amount read will be assigned * If readRemaining was set to true, the true amount read will be assigned
* to the passed value. * to the passed value.
* @return * @return
* - @c RETURN_OK if data was read successfully * - @c RETURN_OK if data was read successfully
* - @c RETURN_FAILED if not enough data was available and readRemaining * - @c RETURN_FAILED if not enough data was available and readRemaining
* was set to false. * was set to false.
*/ */
ReturnValue_t readData(uint8_t* data, size_t amount, ReturnValue_t readData(uint8_t* data, size_t amount,
bool incrementReadPtr = false, bool readRemaining = false, bool incrementReadPtr = false, bool readRemaining = false,
size_t* trueAmount = nullptr); size_t* trueAmount = nullptr);
/** /**
* Delete data by incrementing read pointer. * Delete data by incrementing read pointer.
* @param amount * @param amount
* @param deleteRemaining * @param deleteRemaining
* If the amount specified is larger than the remaing size to read and this * If the amount specified is larger than the remaing size to read and this
* is set to true, the remaining amount will be deleted as well * is set to true, the remaining amount will be deleted as well
* @param trueAmount [out] * @param trueAmount [out]
* If deleteRemaining was set to true, the amount deleted will be assigned * If deleteRemaining was set to true, the amount deleted will be assigned
* to the passed value. * to the passed value.
* @return * @return
*/ */
ReturnValue_t deleteData(size_t amount, bool deleteRemaining = false, ReturnValue_t deleteData(size_t amount, bool deleteRemaining = false,
size_t* trueAmount = nullptr); size_t* trueAmount = nullptr);
private: private:
static const uint8_t READ_PTR = 0; static const uint8_t READ_PTR = 0;
uint8_t* buffer = nullptr; uint8_t* buffer = nullptr;
size_t maxExcessBytes; size_t maxExcessBytes;
size_t excessBytes = 0; size_t excessBytes = 0;
}; };
#endif /* FSFW_CONTAINER_SIMPLERINGBUFFER_H_ */ #endif /* FSFW_CONTAINER_SIMPLERINGBUFFER_H_ */

View File

@ -5,71 +5,71 @@
#include <cstdint> #include <cstdint>
/** /**
* @brief Linked list data structure, * @brief Linked list data structure,
* each entry has a pointer to the next entry (singly) * each entry has a pointer to the next entry (singly)
* @ingroup container * @ingroup container
*/ */
template<typename T> template<typename T>
class LinkedElement { class LinkedElement {
public: public:
T *value; T *value;
class Iterator { class Iterator {
public: public:
LinkedElement<T> *value = nullptr; LinkedElement<T> *value = nullptr;
Iterator() {} Iterator() {}
Iterator(LinkedElement<T> *element) : Iterator(LinkedElement<T> *element) :
value(element) { value(element) {
} }
Iterator& operator++() { Iterator& operator++() {
value = value->getNext(); value = value->getNext();
return *this; return *this;
} }
Iterator operator++(int) { Iterator operator++(int) {
Iterator tmp(*this); Iterator tmp(*this);
operator++(); operator++();
return tmp; return tmp;
} }
bool operator==(Iterator other) { bool operator==(Iterator other) {
return value == other.value; return value == other.value;
} }
bool operator!=(Iterator other) { bool operator!=(Iterator other) {
return !(*this == other); return !(*this == other);
} }
T *operator->() { T *operator->() {
return value->value; return value->value;
} }
}; };
LinkedElement(T* setElement, LinkedElement<T>* setNext = nullptr): LinkedElement(T* setElement, LinkedElement<T>* setNext = nullptr):
value(setElement), next(setNext) {} value(setElement), next(setNext) {}
virtual ~LinkedElement(){} virtual ~LinkedElement(){}
virtual LinkedElement* getNext() const { virtual LinkedElement* getNext() const {
return next; return next;
} }
virtual void setNext(LinkedElement* next) { virtual void setNext(LinkedElement* next) {
this->next = next; this->next = next;
} }
virtual void setEnd() { virtual void setEnd() {
this->next = nullptr; this->next = nullptr;
} }
LinkedElement* begin() { LinkedElement* begin() {
return this; return this;
} }
LinkedElement* end() { LinkedElement* end() {
return nullptr; return nullptr;
} }
private: private:
LinkedElement *next; LinkedElement *next;
}; };
template<typename T> template<typename T>
@ -77,52 +77,52 @@ class SinglyLinkedList {
public: public:
using ElementIterator = typename LinkedElement<T>::Iterator; using ElementIterator = typename LinkedElement<T>::Iterator;
SinglyLinkedList() {} SinglyLinkedList() {}
SinglyLinkedList(ElementIterator start) : SinglyLinkedList(ElementIterator start) :
start(start.value) {} start(start.value) {}
SinglyLinkedList(LinkedElement<T>* startElement) : SinglyLinkedList(LinkedElement<T>* startElement) :
start(startElement) {} start(startElement) {}
ElementIterator begin() const { ElementIterator begin() const {
return ElementIterator::Iterator(start); return ElementIterator::Iterator(start);
} }
/** Returns iterator to nulltr */ /** Returns iterator to nulltr */
ElementIterator end() const { ElementIterator end() const {
return ElementIterator::Iterator(); return ElementIterator::Iterator();
} }
/** /**
* Returns last element in singly linked list. * Returns last element in singly linked list.
* @return * @return
*/ */
ElementIterator back() const { ElementIterator back() const {
LinkedElement<T> *element = start; LinkedElement<T> *element = start;
while (element->getNext() != nullptr) { while (element->getNext() != nullptr) {
element = element->getNext(); element = element->getNext();
} }
return ElementIterator::Iterator(element); return ElementIterator::Iterator(element);
} }
size_t getSize() const { size_t getSize() const {
size_t size = 0; size_t size = 0;
LinkedElement<T> *element = start; LinkedElement<T> *element = start;
while (element != nullptr) { while (element != nullptr) {
size++; size++;
element = element->getNext(); element = element->getNext();
} }
return size; return size;
} }
void setStart(LinkedElement<T>* firstElement) { void setStart(LinkedElement<T>* firstElement) {
start = firstElement; start = firstElement;
} }
void setNext(LinkedElement<T>* currentElement, void setNext(LinkedElement<T>* currentElement,
LinkedElement<T>* nextElement) { LinkedElement<T>* nextElement) {
currentElement->setNext(nextElement); currentElement->setNext(nextElement);
} }
void setLast(LinkedElement<T>* lastElement) { void setLast(LinkedElement<T>* lastElement) {
lastElement->setEnd(); lastElement->setEnd();
@ -148,7 +148,7 @@ public:
} }
protected: protected:
LinkedElement<T> *start = nullptr; LinkedElement<T> *start = nullptr;
}; };
#endif /* SINGLYLINKEDLIST_H_ */ #endif /* SINGLYLINKEDLIST_H_ */