fsfw/serialize/SerialLinkedListAdapter.h

135 lines
4.8 KiB
C++

/**
* @file SerialLinkedListAdapter.h
* @brief This file defines the SerialLinkedListAdapter class.
* @date 22.07.2014
* @author baetz
*/
#ifndef SERIALLINKEDLISTADAPTER_H_
#define SERIALLINKEDLISTADAPTER_H_
#include <framework/container/SinglyLinkedList.h>
#include <framework/serialize/SerializeAdapter.h>
#include <framework/serialize/SerializeElement.h>
#include <framework/serialize/SerializeIF.h>
//This is where we need the SerializeAdapter!
/**
* @brief Implement the conversion of object data to data streams
* or vice-versa, using linked lists.
* @details
* An alternative to the AutoSerializeAdapter functions
* - All object members with a datatype are declared as SerializeElement<element_type>
* members inside the class implementing this adapter.
* - The element type can also be a SerialBufferAdapter to de-/serialize buffers,
* with a known size, where the size can also be serialized
* - The element type can also be a SerialFixedArrayListAdapter to de-/serialize buffers
* with a size header, which is scanned automatically
*
* The sequence of objects is defined in the constructor by using
* the setStart and setNext functions.
*
* - The serialization process is done by instantiating the class and
* calling serializ after all SerializeElement entries have been set by
* using the constructor or setter functions. An additional size variable can be supplied
* which is calculated/incremented automatically
* - The deserialization process is done by instantiating the class and supplying
* a buffer with the data which is converted into an object. The size of
* data to serialize can be supplied and is decremented in the function
*
* @ingroup serialize
*/
template<typename T, typename count_t = uint8_t>
class SerialLinkedListAdapter: public SinglyLinkedList<T>, public SerializeIF {
public:
SerialLinkedListAdapter(typename LinkedElement<T>::Iterator start,
bool printCount = false) :
SinglyLinkedList<T>(start), printCount(printCount) {
}
SerialLinkedListAdapter(LinkedElement<T>* first, bool printCount = false) :
SinglyLinkedList<T>(first), printCount(printCount) {
}
SerialLinkedListAdapter(bool printCount = false) :
SinglyLinkedList<T>(), printCount(printCount) {
}
/**
* Serialize object implementing this adapter into the supplied buffer
* and calculate the serialized size
* @param buffer [out] Object is serialized into this buffer. Note that the buffer pointer
* *buffer is incremented automatically inside the respective serialize functions
* @param size [out] Calculated serialized size. Don't forget to set to 0.
* @param max_size
* @param bigEndian Specify endianness
* @return
*/
virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size,
const size_t max_size, bool bigEndian) const {
if (printCount) {
count_t mySize = SinglyLinkedList<T>::getSize();
ReturnValue_t result = SerializeAdapter<count_t>::serialize(&mySize,
buffer, size, max_size, bigEndian);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
}
return serialize(SinglyLinkedList<T>::start, buffer, size, max_size,
bigEndian);
}
static ReturnValue_t serialize(const LinkedElement<T>* element,
uint8_t** buffer, size_t* size, const size_t max_size,
bool bigEndian) {
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
while ((result == HasReturnvaluesIF::RETURN_OK) && (element != NULL)) {
result = element->value->serialize(buffer, size, max_size,
bigEndian);
element = element->getNext();
}
return result;
}
virtual size_t getSerializedSize() const {
if (printCount) {
return SerialLinkedListAdapter<T>::getSerializedSize()
+ sizeof(count_t);
} else {
return getSerializedSize(SinglyLinkedList<T>::start);
}
}
static uint32_t getSerializedSize(const LinkedElement<T> *element) {
uint32_t size = 0;
while (element != NULL) {
size += element->value->getSerializedSize();
element = element->getNext();
}
return size;
}
/**
* Deserialize supplied buffer with supplied size into object implementing this adapter
* @param buffer
* @param size Decremented in respective deSerialize functions automatically
* @param bigEndian Specify endianness
* @return
*/
virtual ReturnValue_t deSerialize(const uint8_t** buffer, ssize_t* size,
bool bigEndian) {
return deSerialize(SinglyLinkedList<T>::start, buffer, size, bigEndian);
}
static ReturnValue_t deSerialize(LinkedElement<T>* element,
const uint8_t** buffer, ssize_t* size, bool bigEndian) {
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
while ((result == HasReturnvaluesIF::RETURN_OK) && (element != NULL)) {
result = element->value->deSerialize(buffer, size, bigEndian);
element = element->getNext();
}
return result;
}
bool printCount;
};
#endif /* SERIALLINKEDLISTADAPTER_H_ */