Update SerializeAdapter #513

Merged
gaisser merged 3 commits from KSat/fsfw:mueller/serializeif-update into development 2021-11-29 14:37:40 +01:00
2 changed files with 429 additions and 268 deletions

View File

@ -7,7 +7,7 @@
#include <cstddef> #include <cstddef>
#include <type_traits> #include <type_traits>
/** /**
* @brief These adapters provides an interface to use the SerializeIF functions * @brief These adapters provides an interface to use the SerializeIF functions
* with arbitrary template objects to facilitate and simplify the * with arbitrary template objects to facilitate and simplify the
* serialization of classes with different multiple different data types * serialization of classes with different multiple different data types
@ -20,174 +20,250 @@
*/ */
class SerializeAdapter { class SerializeAdapter {
public: public:
/*** /***
* This function can be used to serialize a trivial copy-able type or a * @brief Serialize a trivial copy-able type or a child of SerializeIF.
* child of SerializeIF. * @details
* The right template to be called is determined in the function itself. * 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 * For objects of non trivial copy-able type this function is almost never
* called by the user directly. Instead helpers for specific types like * called by the user directly. Instead helpers for specific types like
* SerialArrayListAdapter or SerialLinkedListAdapter is the right choice here. * SerialArrayListAdapter or SerialLinkedListAdapter are the right choice here.
* *
* @param[in] object Object to serialize, the used type is deduced from this pointer * @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] buffer: Pointer to the buffer to serialize into. Buffer position will be
* @param[in/out] size Size of current written buffer. Will be incremented by the function. * incremented by the function.
* @param[in] maxSize Max size of Buffer * @param[in/out] size: Pointer to size of current written buffer.
* @param[in] streamEndianness Endianness of serialized element as in according to SerializeIF::Endianness * SIze will be incremented by the function.
* @return * @param[in] maxSize: Max size of Buffer
* - @c BUFFER_TOO_SHORT The given buffer in is too short * @param[in] streamEndianness: Endianness of serialized element as in according to
* - @c RETURN_FAILED Generic Error * SerializeIF::Endianness
* - @c RETURN_OK Successful serialization * @return
*/ * - @c BUFFER_TOO_SHORT The given buffer in is too short
template<typename T> * - @c RETURN_FAILED Generic Error
static ReturnValue_t serialize(const T *object, uint8_t **buffer, * - @c RETURN_OK Successful serialization
size_t *size, size_t maxSize, */
SerializeIF::Endianness streamEndianness) { template<typename T>
InternalSerializeAdapter<T, std::is_base_of<SerializeIF, T>::value> adapter; static ReturnValue_t serialize(const T *object, uint8_t **buffer,
return adapter.serialize(object, buffer, size, maxSize, size_t *size, size_t maxSize,
streamEndianness); SerializeIF::Endianness streamEndianness) {
} InternalSerializeAdapter<T, std::is_base_of<SerializeIF, T>::value> adapter;
/** return adapter.serialize(object, buffer, size, maxSize,
* Function to return the serialized size of the object in the pointer. streamEndianness);
* May be a trivially copy-able object or a Child of SerializeIF }
*
* @param object Pointer to Object /***
* @return Serialized size of object * 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.
template<typename T> * For objects of non trivial copy-able type this function is almost never
static size_t getSerializedSize(const T *object){ * called by the user directly. Instead helpers for specific types like
InternalSerializeAdapter<T, std::is_base_of<SerializeIF, T>::value> adapter; * SerialArrayListAdapter or SerialLinkedListAdapter are the right choice here.
return adapter.getSerializedSize(object); *
} * @param[in] object: Object to serialize, the used type is deduced from this pointer
/** * @param[in/out] buffer: Buffer to serialize into.
* @brief * @param[out] serSize: Serialized size
* Deserializes a object from a given buffer of given size. * @param[in] maxSize: Max size of buffer
* Object Must be trivially copy-able or a child of SerializeIF. * @param[in] streamEndianness: Endianness of serialized element as in according to
* * SerializeIF::Endianness
* @details * @return
* Buffer will be moved to the current read location. Size will be decreased by the function. * - @c BUFFER_TOO_SHORT The given buffer in is too short
* * - @c RETURN_FAILED Generic Error
* @param[in/out] buffer Buffer to deSerialize from. Will be moved by the function. * - @c RETURN_OK Successful serialization
* @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 template<typename T>
* @return static ReturnValue_t serialize(const T *object, uint8_t* const buffer, size_t* serSize,
* - @c STREAM_TOO_SHORT The input stream is too short to deSerialize the object size_t maxSize, SerializeIF::Endianness streamEndianness) {
* - @c TOO_MANY_ELEMENTS The buffer has more inputs than expected if(object == nullptr or buffer == nullptr) {
* - @c RETURN_FAILED Generic Error return HasReturnvaluesIF::RETURN_FAILED;
* - @c RETURN_OK Successful deserialization }
*/ InternalSerializeAdapter<T, std::is_base_of<SerializeIF, T>::value> adapter;
template<typename T> uint8_t** tempPtr = const_cast<uint8_t**>(&buffer);
static ReturnValue_t deSerialize(T *object, const uint8_t **buffer, size_t tmpSize = 0;
size_t *size, SerializeIF::Endianness streamEndianness) { ReturnValue_t result = adapter.serialize(object, tempPtr, &tmpSize, maxSize,
InternalSerializeAdapter<T, std::is_base_of<SerializeIF, T>::value> adapter; streamEndianness);
return adapter.deSerialize(object, buffer, size, streamEndianness); if(serSize != nullptr) {
} *serSize = tmpSize;
}
return result;
}
/**
* @brief Function to return the serialized size of the object in the pointer.
* @details
* May be a trivially copy-able object or a child of SerializeIF.
*
* @param object Pointer to Object
* @return Serialized size of object
*/
template<typename T>
static size_t getSerializedSize(const T *object){
InternalSerializeAdapter<T, std::is_base_of<SerializeIF, T>::value> adapter;
return adapter.getSerializedSize(object);
}
/**
* @brief Deserializes a object from a given buffer of given size.
*
* @details
* Object Must be trivially copy-able or a child of SerializeIF.
* Buffer will be moved to the current read location. Size will be decreased by the function.
*
* @param[in] object: Pointer to object to deserialize
* @param[in/out] buffer: Pointer to the buffer to deSerialize from. Buffer position will be
* incremented by the function
* @param[in/out] size: Pointer to 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<typename T>
static ReturnValue_t deSerialize(T *object, const uint8_t **buffer,
size_t *size, SerializeIF::Endianness streamEndianness) {
InternalSerializeAdapter<T, std::is_base_of<SerializeIF, T>::value> adapter;
return adapter.deSerialize(object, buffer, size, streamEndianness);
}
/**
* @brief Deserializes a object from a given buffer of given size.
*
gaisser marked this conversation as resolved Outdated

The comment here is wrong. The size is no longer decreased.

The comment here is wrong. The size is no longer decreased.

done. buffer is not moved as well here

done. buffer is not moved as well here
* @details
* Object Must be trivially copy-able or a child of SerializeIF.
*
gaisser marked this conversation as resolved Outdated

In this function the buffer is no "out" just in.

In this function the buffer is no "out" just in.

done

done
* @param[in] object: Pointer to object to deserialize
* @param[in] buffer: Buffer to deSerialize from
* @param[out] deserSize: Deserialized length
* @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
*/
gaisser marked this conversation as resolved Outdated

As the Pointer can not be changed here the second const seems useless to me.

This might get rid of the const_cast

As the Pointer can not be changed here the second const seems useless to me. This might get rid of the const_cast

done

done
template<typename T>
static ReturnValue_t deSerialize(T *object, const uint8_t* buffer,
size_t* deserSize, SerializeIF::Endianness streamEndianness) {
if(object == nullptr or buffer == nullptr) {
return HasReturnvaluesIF::RETURN_FAILED;
}
InternalSerializeAdapter<T, std::is_base_of<SerializeIF, T>::value> adapter;
const uint8_t** tempPtr = &buffer;
size_t maxVal = -1;
ReturnValue_t result = adapter.deSerialize(object, tempPtr, &maxVal, streamEndianness);
if(deserSize != nullptr) {
*deserSize = -1 - maxVal;
}
return result;
}
private: private:
/** /**
* Internal template to deduce the right function calls at compile time * Internal template to deduce the right function calls at compile time
*/ */
template<typename T, bool> class InternalSerializeAdapter; template<typename T, bool> class InternalSerializeAdapter;
/** /**
* Template to be used if T is not a child of SerializeIF * Template to be used if T is not a child of SerializeIF
* *
* @tparam T T must be trivially_copyable * @tparam T T must be trivially_copyable
*/ */
template<typename T> template<typename T>
class InternalSerializeAdapter<T, false> { class InternalSerializeAdapter<T, false> {
static_assert (std::is_trivially_copyable<T>::value, static_assert (std::is_trivially_copyable<T>::value,
"If a type needs to be serialized it must be a child of " "If a type needs to be serialized it must be a child of "
"SerializeIF or trivially copy-able"); "SerializeIF or trivially copy-able");
public: public:
static ReturnValue_t serialize(const T *object, uint8_t **buffer, static ReturnValue_t serialize(const T *object, uint8_t **buffer,
size_t *size, size_t max_size, size_t *size, size_t max_size,
SerializeIF::Endianness streamEndianness) { SerializeIF::Endianness streamEndianness) {
size_t ignoredSize = 0; size_t ignoredSize = 0;
if (size == nullptr) { if (size == nullptr) {
size = &ignoredSize; size = &ignoredSize;
} }
// Check remaining size is large enough and check integer // Check remaining size is large enough and check integer
// overflow of *size // overflow of *size
size_t newSize = sizeof(T) + *size; size_t newSize = sizeof(T) + *size;
if ((newSize <= max_size) and (newSize > *size)) { if ((newSize <= max_size) and (newSize > *size)) {
T tmp; T tmp;
switch (streamEndianness) { switch (streamEndianness) {
case SerializeIF::Endianness::BIG: case SerializeIF::Endianness::BIG:
tmp = EndianConverter::convertBigEndian<T>(*object); tmp = EndianConverter::convertBigEndian<T>(*object);
break; break;
case SerializeIF::Endianness::LITTLE: case SerializeIF::Endianness::LITTLE:
tmp = EndianConverter::convertLittleEndian<T>(*object); tmp = EndianConverter::convertLittleEndian<T>(*object);
break; break;
default: default:
case SerializeIF::Endianness::MACHINE: case SerializeIF::Endianness::MACHINE:
tmp = *object; tmp = *object;
break; break;
} }
std::memcpy(*buffer, &tmp, sizeof(T)); std::memcpy(*buffer, &tmp, sizeof(T));
*size += sizeof(T); *size += sizeof(T);
(*buffer) += sizeof(T); (*buffer) += sizeof(T);
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} else { } else {
return SerializeIF::BUFFER_TOO_SHORT; return SerializeIF::BUFFER_TOO_SHORT;
} }
} }
ReturnValue_t deSerialize(T *object, const uint8_t **buffer, ReturnValue_t deSerialize(T *object, const uint8_t **buffer,
size_t *size, SerializeIF::Endianness streamEndianness) { size_t *size, SerializeIF::Endianness streamEndianness) {
T tmp; T tmp;
if (*size >= sizeof(T)) { if (*size >= sizeof(T)) {
*size -= sizeof(T); *size -= sizeof(T);
std::memcpy(&tmp, *buffer, sizeof(T)); std::memcpy(&tmp, *buffer, sizeof(T));
switch (streamEndianness) { switch (streamEndianness) {
case SerializeIF::Endianness::BIG: case SerializeIF::Endianness::BIG:
*object = EndianConverter::convertBigEndian<T>(tmp); *object = EndianConverter::convertBigEndian<T>(tmp);
break; break;
case SerializeIF::Endianness::LITTLE: case SerializeIF::Endianness::LITTLE:
*object = EndianConverter::convertLittleEndian<T>(tmp); *object = EndianConverter::convertLittleEndian<T>(tmp);
break; break;
default: default:
case SerializeIF::Endianness::MACHINE: case SerializeIF::Endianness::MACHINE:
*object = tmp; *object = tmp;
break; break;
} }
*buffer += sizeof(T); *buffer += sizeof(T);
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} else { } else {
return SerializeIF::STREAM_TOO_SHORT; return SerializeIF::STREAM_TOO_SHORT;
} }
} }
uint32_t getSerializedSize(const T *object) { uint32_t getSerializedSize(const T *object) {
return sizeof(T); return sizeof(T);
} }
}; };
/** /**
* Template for objects that inherit from SerializeIF * Template for objects that inherit from SerializeIF
* *
* @tparam T A child of SerializeIF * @tparam T A child of SerializeIF
*/ */
template<typename T> template<typename T>
class InternalSerializeAdapter<T, true> { class InternalSerializeAdapter<T, true> {
public: public:
ReturnValue_t serialize(const T *object, uint8_t **buffer, size_t *size, ReturnValue_t serialize(const T *object, uint8_t **buffer, size_t *size,
size_t max_size, size_t max_size,
SerializeIF::Endianness streamEndianness) const { SerializeIF::Endianness streamEndianness) const {
size_t ignoredSize = 0; size_t ignoredSize = 0;
if (size == nullptr) { if (size == nullptr) {
size = &ignoredSize; size = &ignoredSize;
} }
return object->serialize(buffer, size, max_size, streamEndianness); return object->serialize(buffer, size, max_size, streamEndianness);
} }
size_t getSerializedSize(const T *object) const { size_t getSerializedSize(const T *object) const {
return object->getSerializedSize(); return object->getSerializedSize();
} }
ReturnValue_t deSerialize(T *object, const uint8_t **buffer, ReturnValue_t deSerialize(T *object, const uint8_t **buffer,
size_t *size, SerializeIF::Endianness streamEndianness) { size_t *size, SerializeIF::Endianness streamEndianness) {
return object->deSerialize(buffer, size, streamEndianness); return object->deSerialize(buffer, size, streamEndianness);
} }
}; };
}; };
#endif /* _FSFW_SERIALIZE_SERIALIZEADAPTER_H_ */ #endif /* _FSFW_SERIALIZE_SERIALIZEADAPTER_H_ */

View File

@ -3,128 +3,213 @@
#include <catch2/catch_test_macros.hpp> #include <catch2/catch_test_macros.hpp>
#include <catch2/catch_approx.hpp> #include <catch2/catch_approx.hpp>
#include <fsfw/serialize/SerialBufferAdapter.h>
#include <array> #include <array>
static bool test_value_bool = true; static bool testBool = true;
static uint8_t tv_uint8 {5}; static uint8_t tvUint8 {5};
static uint16_t tv_uint16 {283}; static uint16_t tvUint16 {283};
static uint32_t tv_uint32 {929221}; static uint32_t tvUint32 {929221};
static uint64_t tv_uint64 {2929329429}; static uint64_t tvUint64 {2929329429};
static int8_t tv_int8 {-16}; static int8_t tvInt8 {-16};
static int16_t tv_int16 {-829}; static int16_t tvInt16 {-829};
static int32_t tv_int32 {-2312}; static int32_t tvInt32 {-2312};
static float tv_float {8.2149214}; static float tvFloat {8.2149214};
static float tv_sfloat = {-922.2321321}; static float tvSfloat = {-922.2321321};
static double tv_double {9.2132142141e8}; static double tvDouble {9.2132142141e8};
static double tv_sdouble {-2.2421e19}; static double tvSdouble {-2.2421e19};
static std::array<uint8_t, 512> test_array; static std::array<uint8_t, 512> TEST_ARRAY;
TEST_CASE( "Serialization size tests", "[TestSerialization]") { TEST_CASE( "Serialization size tests", "[SerSizeTest]") {
//REQUIRE(unitTestClass.test_autoserialization() == 0); //REQUIRE(unitTestClass.test_autoserialization() == 0);
REQUIRE(SerializeAdapter::getSerializedSize(&test_value_bool) == REQUIRE(SerializeAdapter::getSerializedSize(&testBool) ==
sizeof(test_value_bool)); sizeof(testBool));
REQUIRE(SerializeAdapter::getSerializedSize(&tv_uint8) == REQUIRE(SerializeAdapter::getSerializedSize(&tvUint8) ==
sizeof(tv_uint8)); sizeof(tvUint8));
REQUIRE(SerializeAdapter::getSerializedSize(&tv_uint16) == REQUIRE(SerializeAdapter::getSerializedSize(&tvUint16) ==
sizeof(tv_uint16)); sizeof(tvUint16));
REQUIRE(SerializeAdapter::getSerializedSize(&tv_uint32 ) == REQUIRE(SerializeAdapter::getSerializedSize(&tvUint32 ) ==
sizeof(tv_uint32)); sizeof(tvUint32));
REQUIRE(SerializeAdapter::getSerializedSize(&tv_uint64) == REQUIRE(SerializeAdapter::getSerializedSize(&tvUint64) ==
sizeof(tv_uint64)); sizeof(tvUint64));
REQUIRE(SerializeAdapter::getSerializedSize(&tv_int8) == REQUIRE(SerializeAdapter::getSerializedSize(&tvInt8) ==
sizeof(tv_int8)); sizeof(tvInt8));
REQUIRE(SerializeAdapter::getSerializedSize(&tv_int16) == REQUIRE(SerializeAdapter::getSerializedSize(&tvInt16) ==
sizeof(tv_int16)); sizeof(tvInt16));
REQUIRE(SerializeAdapter::getSerializedSize(&tv_int32) == REQUIRE(SerializeAdapter::getSerializedSize(&tvInt32) ==
sizeof(tv_int32)); sizeof(tvInt32));
REQUIRE(SerializeAdapter::getSerializedSize(&tv_float) == REQUIRE(SerializeAdapter::getSerializedSize(&tvFloat) ==
sizeof(tv_float)); sizeof(tvFloat));
REQUIRE(SerializeAdapter::getSerializedSize(&tv_sfloat) == REQUIRE(SerializeAdapter::getSerializedSize(&tvSfloat) ==
sizeof(tv_sfloat )); sizeof(tvSfloat ));
REQUIRE(SerializeAdapter::getSerializedSize(&tv_double) == REQUIRE(SerializeAdapter::getSerializedSize(&tvDouble) ==
sizeof(tv_double)); sizeof(tvDouble));
REQUIRE(SerializeAdapter::getSerializedSize(&tv_sdouble) == REQUIRE(SerializeAdapter::getSerializedSize(&tvSdouble) ==
sizeof(tv_sdouble)); sizeof(tvSdouble));
} }
TEST_CASE("Auto Serialize Adapter", "[SerAdapter]") {
size_t serializedSize = 0;
uint8_t * pArray = TEST_ARRAY.data();
TEST_CASE("Auto Serialize Adapter testing", "[single-file]") { SECTION("SerDe") {
size_t serialized_size = 0; size_t deserSize = 0;
uint8_t * p_array = test_array.data(); SerializeAdapter::serialize(&testBool, TEST_ARRAY.data(), &deserSize, TEST_ARRAY.size(),
SerializeIF::Endianness::MACHINE);
REQUIRE(deserSize == 1);
REQUIRE(TEST_ARRAY[0] == true);
bool readBack = false;
SerializeAdapter::deSerialize(&readBack, TEST_ARRAY.data(), &deserSize,
SerializeIF::Endianness::MACHINE);
REQUIRE(deserSize == 1);
REQUIRE(readBack == true);
SerializeAdapter::serialize(&tvUint8, TEST_ARRAY.data(), &deserSize, TEST_ARRAY.size(),
SerializeIF::Endianness::MACHINE);
REQUIRE(deserSize == 1);
REQUIRE(TEST_ARRAY[0] == 5);
uint8_t readBackUint8 = 0;
uint8_t* const testPtr = TEST_ARRAY.data();
uint8_t* const shouldStayConst = testPtr;
SerializeAdapter::deSerialize(&readBackUint8, testPtr, &deserSize,
SerializeIF::Endianness::MACHINE);
REQUIRE(testPtr == shouldStayConst);
REQUIRE(deserSize == 1);
REQUIRE(readBackUint8 == 5);
SerializeAdapter::serialize(&tvUint16, TEST_ARRAY.data(), &deserSize, TEST_ARRAY.size(),
SerializeIF::Endianness::MACHINE);
REQUIRE(deserSize == 2);
deserSize = 0;
uint16_t readBackUint16 = 0;
SerializeAdapter::deSerialize(&readBackUint16, TEST_ARRAY.data(), &deserSize,
SerializeIF::Endianness::MACHINE);
REQUIRE(deserSize == 2);
REQUIRE(readBackUint16 == 283);
SECTION("Serializing...") { SerializeAdapter::serialize(&tvUint32, TEST_ARRAY.data(), &deserSize, TEST_ARRAY.size(),
SerializeAdapter::serialize(&test_value_bool, &p_array, SerializeIF::Endianness::MACHINE);
&serialized_size, test_array.size(), SerializeIF::Endianness::MACHINE); REQUIRE(deserSize == 4);
SerializeAdapter::serialize(&tv_uint8, &p_array, uint32_t readBackUint32 = 0;
&serialized_size, test_array.size(), SerializeIF::Endianness::MACHINE); deserSize = 0;
SerializeAdapter::serialize(&tv_uint16, &p_array, SerializeAdapter::deSerialize(&readBackUint32, TEST_ARRAY.data(), &deserSize,
&serialized_size, test_array.size(), SerializeIF::Endianness::MACHINE); SerializeIF::Endianness::MACHINE);
SerializeAdapter::serialize(&tv_uint32, &p_array, REQUIRE(deserSize == 4);
&serialized_size, test_array.size(), SerializeIF::Endianness::MACHINE); REQUIRE(readBackUint32 == 929221);
SerializeAdapter::serialize(&tv_int8, &p_array,
&serialized_size, test_array.size(), SerializeIF::Endianness::MACHINE); SerializeAdapter::serialize(&tvInt16, TEST_ARRAY.data(), &deserSize, TEST_ARRAY.size(),
SerializeAdapter::serialize(&tv_int16, &p_array, SerializeIF::Endianness::MACHINE);
&serialized_size, test_array.size(), SerializeIF::Endianness::MACHINE); REQUIRE(deserSize == 2);
SerializeAdapter::serialize(&tv_int32, &p_array, int16_t readBackInt16 = 0;
&serialized_size, test_array.size(), SerializeIF::Endianness::MACHINE); SerializeAdapter::deSerialize(&readBackInt16, TEST_ARRAY.data(), &deserSize,
SerializeAdapter::serialize(&tv_uint64, &p_array, SerializeIF::Endianness::MACHINE);
&serialized_size, test_array.size(), SerializeIF::Endianness::MACHINE); REQUIRE(readBackInt16 == -829);
SerializeAdapter::serialize(&tv_float, &p_array, REQUIRE(deserSize == 2);
&serialized_size, test_array.size(), SerializeIF::Endianness::MACHINE);
SerializeAdapter::serialize(&tv_double, &p_array, SerializeAdapter::serialize(&tvFloat, TEST_ARRAY.data(), &deserSize, TEST_ARRAY.size(),
&serialized_size, test_array.size(), SerializeIF::Endianness::MACHINE); SerializeIF::Endianness::MACHINE);
SerializeAdapter::serialize(&tv_sfloat, &p_array, float readBackFloat = 0.0;
&serialized_size, test_array.size(), SerializeIF::Endianness::MACHINE); SerializeAdapter::deSerialize(&readBackFloat, TEST_ARRAY.data(), &deserSize,
SerializeAdapter::serialize(&tv_sdouble, &p_array, SerializeIF::Endianness::MACHINE);
&serialized_size, test_array.size(), SerializeIF::Endianness::MACHINE); REQUIRE(readBackFloat == Catch::Approx(8.214921));
REQUIRE (serialized_size == 47);
SerializeAdapter::serialize(&tvSdouble, TEST_ARRAY.data(), &deserSize, TEST_ARRAY.size(),
SerializeIF::Endianness::MACHINE);
double readBackSignedDouble = 0.0;
SerializeAdapter::deSerialize(&readBackSignedDouble, TEST_ARRAY.data(), &deserSize,
SerializeIF::Endianness::MACHINE);
REQUIRE(readBackSignedDouble == Catch::Approx(-2.2421e19));
uint8_t testBuf[4] = {1, 2, 3, 4};
SerialBufferAdapter<uint8_t> bufferAdapter(testBuf, sizeof(testBuf));
SerializeAdapter::serialize(&bufferAdapter, TEST_ARRAY.data(), &deserSize,
TEST_ARRAY.size(), SerializeIF::Endianness::MACHINE);
REQUIRE(deserSize == 4);
for(uint8_t idx = 0; idx < 4; idx++) {
REQUIRE(TEST_ARRAY[idx] == idx + 1);
}
deserSize = 0;
testBuf[0] = 0;
testBuf[1] = 12;
SerializeAdapter::deSerialize(&bufferAdapter, TEST_ARRAY.data(), &deserSize,
SerializeIF::Endianness::MACHINE);
REQUIRE(deserSize == 4);
for(uint8_t idx = 0; idx < 4; idx++) {
REQUIRE(testBuf[idx] == idx + 1);
}
}
SECTION("Serialize incrementing") {
SerializeAdapter::serialize(&testBool, &pArray, &serializedSize,
TEST_ARRAY.size(), SerializeIF::Endianness::MACHINE);
SerializeAdapter::serialize(&tvUint8, &pArray, &serializedSize,
TEST_ARRAY.size(), SerializeIF::Endianness::MACHINE);
SerializeAdapter::serialize(&tvUint16, &pArray, &serializedSize,
TEST_ARRAY.size(), SerializeIF::Endianness::MACHINE);
SerializeAdapter::serialize(&tvUint32, &pArray, &serializedSize,
TEST_ARRAY.size(), SerializeIF::Endianness::MACHINE);
SerializeAdapter::serialize(&tvInt8, &pArray, &serializedSize,
TEST_ARRAY.size(), SerializeIF::Endianness::MACHINE);
SerializeAdapter::serialize(&tvInt16, &pArray, &serializedSize,
TEST_ARRAY.size(), SerializeIF::Endianness::MACHINE);
SerializeAdapter::serialize(&tvInt32, &pArray, &serializedSize,
TEST_ARRAY.size(), SerializeIF::Endianness::MACHINE);
SerializeAdapter::serialize(&tvUint64, &pArray, &serializedSize,
TEST_ARRAY.size(), SerializeIF::Endianness::MACHINE);
SerializeAdapter::serialize(&tvFloat, &pArray, &serializedSize,
TEST_ARRAY.size(), SerializeIF::Endianness::MACHINE);
SerializeAdapter::serialize(&tvDouble, &pArray, &serializedSize, TEST_ARRAY.size(),
SerializeIF::Endianness::MACHINE);
SerializeAdapter::serialize(&tvSfloat, &pArray, &serializedSize, TEST_ARRAY.size(),
SerializeIF::Endianness::MACHINE);
SerializeAdapter::serialize(&tvSdouble, &pArray, &serializedSize, TEST_ARRAY.size(),
SerializeIF::Endianness::MACHINE);
REQUIRE (serializedSize == 47);
} }
SECTION("Deserializing") { SECTION("Deserialize decrementing") {
p_array = test_array.data(); pArray = TEST_ARRAY.data();
size_t remaining_size = serialized_size; size_t remaining_size = serializedSize;
SerializeAdapter::deSerialize(&test_value_bool, SerializeAdapter::deSerialize(&testBool, const_cast<const uint8_t**>(&pArray),
const_cast<const uint8_t**>(&p_array), &remaining_size, SerializeIF::Endianness::MACHINE); &remaining_size, SerializeIF::Endianness::MACHINE);
SerializeAdapter::deSerialize(&tv_uint8, SerializeAdapter::deSerialize(&tvUint8, const_cast<const uint8_t**>(&pArray),
const_cast<const uint8_t**>(&p_array), &remaining_size, SerializeIF::Endianness::MACHINE); &remaining_size, SerializeIF::Endianness::MACHINE);
SerializeAdapter::deSerialize(&tv_uint16, SerializeAdapter::deSerialize(&tvUint16, const_cast<const uint8_t**>(&pArray),
const_cast<const uint8_t**>(&p_array), &remaining_size, SerializeIF::Endianness::MACHINE); &remaining_size, SerializeIF::Endianness::MACHINE);
SerializeAdapter::deSerialize(&tv_uint32, SerializeAdapter::deSerialize(&tvUint32, const_cast<const uint8_t**>(&pArray),
const_cast<const uint8_t**>(&p_array), &remaining_size, SerializeIF::Endianness::MACHINE); &remaining_size, SerializeIF::Endianness::MACHINE);
SerializeAdapter::deSerialize(&tv_int8, SerializeAdapter::deSerialize(&tvInt8, const_cast<const uint8_t**>(&pArray),
const_cast<const uint8_t**>(&p_array), &remaining_size, SerializeIF::Endianness::MACHINE); &remaining_size, SerializeIF::Endianness::MACHINE);
SerializeAdapter::deSerialize(&tv_int16, SerializeAdapter::deSerialize(&tvInt16, const_cast<const uint8_t**>(&pArray),
const_cast<const uint8_t**>(&p_array), &remaining_size, SerializeIF::Endianness::MACHINE); &remaining_size, SerializeIF::Endianness::MACHINE);
SerializeAdapter::deSerialize(&tv_int32, SerializeAdapter::deSerialize(&tvInt32, const_cast<const uint8_t**>(&pArray),
const_cast<const uint8_t**>(&p_array), &remaining_size, SerializeIF::Endianness::MACHINE); &remaining_size, SerializeIF::Endianness::MACHINE);
SerializeAdapter::deSerialize(&tv_uint64, SerializeAdapter::deSerialize(&tvUint64,
const_cast<const uint8_t**>(&p_array), &remaining_size, SerializeIF::Endianness::MACHINE); const_cast<const uint8_t**>(&pArray), &remaining_size, SerializeIF::Endianness::MACHINE);
SerializeAdapter::deSerialize(&tv_float, SerializeAdapter::deSerialize(&tvFloat,
const_cast<const uint8_t**>(&p_array), &remaining_size, SerializeIF::Endianness::MACHINE); const_cast<const uint8_t**>(&pArray), &remaining_size, SerializeIF::Endianness::MACHINE);
SerializeAdapter::deSerialize(&tv_double, SerializeAdapter::deSerialize(&tvDouble,
const_cast<const uint8_t**>(&p_array), &remaining_size, SerializeIF::Endianness::MACHINE); const_cast<const uint8_t**>(&pArray), &remaining_size, SerializeIF::Endianness::MACHINE);
SerializeAdapter::deSerialize(&tv_sfloat, SerializeAdapter::deSerialize(&tvSfloat,
const_cast<const uint8_t**>(&p_array), &remaining_size, SerializeIF::Endianness::MACHINE); const_cast<const uint8_t**>(&pArray), &remaining_size, SerializeIF::Endianness::MACHINE);
SerializeAdapter::deSerialize(&tv_sdouble, SerializeAdapter::deSerialize(&tvSdouble,
const_cast<const uint8_t**>(&p_array), &remaining_size, SerializeIF::Endianness::MACHINE); const_cast<const uint8_t**>(&pArray), &remaining_size, SerializeIF::Endianness::MACHINE);
REQUIRE(test_value_bool == true); REQUIRE(testBool == true);
REQUIRE(tv_uint8 == 5); REQUIRE(tvUint8 == 5);
REQUIRE(tv_uint16 == 283); REQUIRE(tvUint16 == 283);
REQUIRE(tv_uint32 == 929221); REQUIRE(tvUint32 == 929221);
REQUIRE(tv_uint64 == 2929329429); REQUIRE(tvUint64 == 2929329429);
REQUIRE(tv_int8 == -16); REQUIRE(tvInt8 == -16);
REQUIRE(tv_int16 == -829); REQUIRE(tvInt16 == -829);
REQUIRE(tv_int32 == -2312); REQUIRE(tvInt32 == -2312);
REQUIRE(tv_float == Catch::Approx(8.214921)); REQUIRE(tvFloat == Catch::Approx(8.214921));
REQUIRE(tv_double == Catch::Approx(9.2132142141e8)); REQUIRE(tvDouble == Catch::Approx(9.2132142141e8));
REQUIRE(tv_sfloat == Catch::Approx(-922.2321321)); REQUIRE(tvSfloat == Catch::Approx(-922.2321321));
REQUIRE(tv_sdouble == Catch::Approx(-2.2421e19)); REQUIRE(tvSdouble == Catch::Approx(-2.2421e19));
} }
} }