tabs replaced by spaces
This commit is contained in:
parent
76d81b5b49
commit
98f89302c4
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -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_ */
|
||||||
|
@ -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_ */
|
||||||
|
@ -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"
|
||||||
|
@ -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
|
||||||
|
@ -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() {
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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"
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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
@ -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_ */
|
||||||
|
@ -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_ */
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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_ */
|
||||||
|
@ -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_ */
|
||||||
|
Loading…
Reference in New Issue
Block a user