diff --git a/serialize/SerializeAdapter.h b/serialize/SerializeAdapter.h index 24f6111e..a05b1791 100644 --- a/serialize/SerializeAdapter.h +++ b/serialize/SerializeAdapter.h @@ -1,47 +1,92 @@ -#ifndef FSFW_SERIALIZE_SERIALIZEADAPTER_H_ -#define FSFW_SERIALIZE_SERIALIZEADAPTER_H_ +#ifndef _FSFW_SERIALIZE_SERIALIZEADAPTER_H_ +#define _FSFW_SERIALIZE_SERIALIZEADAPTER_H_ +#include "../returnvalues/HasReturnvaluesIF.h" #include "EndianConverter.h" #include "SerializeIF.h" +#include +#include -#include "../container/IsDerivedFrom.h" -#include "../returnvalues/HasReturnvaluesIF.h" -#include - - /** - * @brief These adapters provides an interface to use the SerializeIF functions - * with arbitrary template objects to facilitate and simplify the - * serialization of classes with different multiple different data types - * into buffers and vice-versa. - * @details - * The correct serialization or deserialization function is chosen at - * compile time with template type deduction. - * - * @ingroup serialize +/** + * \ingroup serialize */ + class SerializeAdapter { public: + /*** + * This function can be used to serialize a trivial copy-able type or a child of SerializeIF. + * The right template to be called is determined in the function itself. + * For objects of non trivial copy-able type this function is almost never called by the user directly. + * Instead helpers for specific types like SerialArrayListAdapter or SerialLinkedListAdapter is the right choice here. + * + * @param[in] object Object to serialize, the used type is deduced from this pointer + * @param[in/out] buffer Buffer to serialize into. Will be moved by the function. + * @param[in/out] size Size of current written buffer. Will be incremented by the function. + * @param[in] maxSize Max size of Buffer + * @param[in] streamEndianness Endianness of serialized element as in according to SerializeIF::Endianness + * @return + * - @c BUFFER_TOO_SHORT The given buffer in is too short + * - @c RETURN_FAILED Generic Error + * - @c RETURN_OK Successful serialization + */ template static ReturnValue_t serialize(const T *object, uint8_t **buffer, - size_t *size, size_t maxSize, SerializeIF::Endianness streamEndianness) { - InternalSerializeAdapter::Is> adapter; + size_t *size, size_t maxSize, + SerializeIF::Endianness streamEndianness) { + InternalSerializeAdapter::value> adapter; return adapter.serialize(object, buffer, size, maxSize, streamEndianness); } + /** + * Function to return the serialized size of the object in the pointer. + * May be a trivially copy-able object or a Child of SerializeIF + * + * @param object Pointer to Object + * @return Serialized size of object + */ template - static uint32_t getSerializedSize(const T *object) { - InternalSerializeAdapter::Is> adapter; + static size_t getSerializedSize(const T *object){ + InternalSerializeAdapter::value> adapter; return adapter.getSerializedSize(object); } + /** + * @brief + * Deserializes a object from a given buffer of given size. + * Object Must be trivially copy-able or a child of SerializeIF. + * + * @details + * Buffer will be moved to the current read location. Size will be decreased by the function. + * + * @param[in/out] buffer Buffer to deSerialize from. Will be moved by the function. + * @param[in/out] size Remaining size of the buffer to read from. Will be decreased by function. + * @param[in] streamEndianness Endianness as in according to SerializeIF::Endianness + * @return + * - @c STREAM_TOO_SHORT The input stream is too short to deSerialize the object + * - @c TOO_MANY_ELEMENTS The buffer has more inputs than expected + * - @c RETURN_FAILED Generic Error + * - @c RETURN_OK Successful deserialization + */ template static ReturnValue_t deSerialize(T *object, const uint8_t **buffer, size_t *size, SerializeIF::Endianness streamEndianness) { - InternalSerializeAdapter::Is> adapter; + InternalSerializeAdapter::value> adapter; return adapter.deSerialize(object, buffer, size, streamEndianness); } private: - template - class InternalSerializeAdapter { + /** + * Internal template to deduce the right function calls at compile time + */ + template class InternalSerializeAdapter; + + /** + * Template to be used if T is not a child of SerializeIF + * + * @tparam T T must be trivially_copyable + */ + template + class InternalSerializeAdapter { + static_assert (std::is_trivially_copyable::value, + "If a type needs to be serialized it must be a child of SerializeIF or trivially copy-able"); public: static ReturnValue_t serialize(const T *object, uint8_t **buffer, size_t *size, size_t max_size, @@ -50,8 +95,9 @@ private: if (size == nullptr) { size = &ignoredSize; } - //TODO check integer overflow of *size - if (sizeof(T) + *size <= max_size) { + //Check remaining size is large enough and check integer overflow of *size + size_t newSize = sizeof(T) + *size; + if ((newSize <= max_size) and (newSize > *size)) { T tmp; switch (streamEndianness) { case SerializeIF::Endianness::BIG: @@ -65,7 +111,7 @@ private: tmp = *object; break; } - std::memcpy(*buffer, &tmp, sizeof(T)); + memcpy(*buffer, &tmp, sizeof(T)); *size += sizeof(T); (*buffer) += sizeof(T); return HasReturnvaluesIF::RETURN_OK; @@ -79,7 +125,7 @@ private: T tmp; if (*size >= sizeof(T)) { *size -= sizeof(T); - std::memcpy(&tmp, *buffer, sizeof(T)); + memcpy(&tmp, *buffer, sizeof(T)); switch (streamEndianness) { case SerializeIF::Endianness::BIG: *object = EndianConverter::convertBigEndian(tmp); @@ -103,14 +149,18 @@ private: uint32_t getSerializedSize(const T *object) { return sizeof(T); } - }; + /** + * Template for objects that inherit from SerializeIF + * + * @tparam T A child of SerializeIF + */ template - class InternalSerializeAdapter { + class InternalSerializeAdapter { public: - ReturnValue_t serialize(const T *object, uint8_t **buffer, - size_t *size, size_t max_size, + ReturnValue_t serialize(const T *object, uint8_t **buffer, size_t *size, + size_t max_size, SerializeIF::Endianness streamEndianness) const { size_t ignoredSize = 0; if (size == nullptr) { @@ -118,7 +168,7 @@ private: } return object->serialize(buffer, size, max_size, streamEndianness); } - uint32_t getSerializedSize(const T *object) const { + size_t getSerializedSize(const T *object) const { return object->getSerializedSize(); } @@ -129,4 +179,4 @@ private: }; }; -#endif /* SERIALIZEADAPTER_H_ */ +#endif /* _FSFW_SERIALIZE_SERIALIZEADAPTER_H_ */