From 8c722feafb18f15e5e1db3ddde65ae66a3b09dad Mon Sep 17 00:00:00 2001 From: Steffen Gaisser Date: Tue, 11 Aug 2020 16:21:59 +0200 Subject: [PATCH 1/8] Fixes #47 and #36 --- container/ArrayList.h | 8 ++- container/FixedMap.h | 23 ++++----- container/FixedOrderedMultimap.h | 13 +---- subsystem/Subsystem.cpp | 4 +- tmtcservices/CommandingServiceBase.cpp | 70 +++++++++++++------------- 5 files changed, 54 insertions(+), 64 deletions(-) diff --git a/container/ArrayList.h b/container/ArrayList.h index 9c4c4ceb..0a2f460b 100644 --- a/container/ArrayList.h +++ b/container/ArrayList.h @@ -72,11 +72,15 @@ public: return tmp; } - T operator*() { + T& operator*(){ return *value; } - T *operator->() { + const T& operator*() const{ + return *value; + } + + T *operator->(){ return value; } diff --git a/container/FixedMap.h b/container/FixedMap.h index ac170bd2..0823b670 100644 --- a/container/FixedMap.h +++ b/container/FixedMap.h @@ -1,5 +1,5 @@ -#ifndef FIXEDMAP_H_ -#define FIXEDMAP_H_ +#ifndef FRAMEWORK_CONTAINER_FIXEDMAP_H_ +#define FRAMEWORK_CONTAINER_FIXEDMAP_H_ #include #include @@ -7,6 +7,10 @@ /** * \ingroup container + * + * + * \warning Iterators return a non-const key_t in the pair. + * \warning A User is not allowed to change the key, otherwise the map is corrupted. */ template class FixedMap: public SerializeIF { @@ -47,15 +51,6 @@ public: Iterator(std::pair *pair) : ArrayList, uint32_t>::Iterator(pair) { } - - T operator*() { - return ArrayList, uint32_t>::Iterator::value->second; - } - - T *operator->() { - return &ArrayList, uint32_t>::Iterator::value->second; - } - }; Iterator begin() const { @@ -70,7 +65,7 @@ public: return _size; } - ReturnValue_t insert(key_t key, T value, Iterator *storedValue = NULL) { + ReturnValue_t insert(key_t key, T value, Iterator *storedValue = nullptr) { if (exists(key) == HasReturnvaluesIF::RETURN_OK) { return KEY_ALREADY_EXISTS; } @@ -79,7 +74,7 @@ public: } theMap[_size].first = key; theMap[_size].second = value; - if (storedValue != NULL) { + if (storedValue != nullptr) { *storedValue = Iterator(&theMap[_size]); } ++_size; @@ -87,7 +82,7 @@ public: } ReturnValue_t insert(std::pair pair) { - return insert(pair.fist, pair.second); + return insert(pair.first, pair.second); } ReturnValue_t exists(key_t key) const { diff --git a/container/FixedOrderedMultimap.h b/container/FixedOrderedMultimap.h index 21629664..4f81c97c 100644 --- a/container/FixedOrderedMultimap.h +++ b/container/FixedOrderedMultimap.h @@ -68,15 +68,6 @@ public: Iterator(std::pair *pair) : ArrayList, uint32_t>::Iterator(pair) { } - - T operator*() { - return ArrayList, uint32_t>::Iterator::value->second; - } - - T *operator->() { - return &ArrayList, uint32_t>::Iterator::value->second; - } - }; Iterator begin() const { @@ -91,7 +82,7 @@ public: return _size; } - ReturnValue_t insert(key_t key, T value, Iterator *storedValue = NULL) { + ReturnValue_t insert(key_t key, T value, Iterator *storedValue = nullptr) { if (_size == theMap.maxSize()) { return MAP_FULL; } @@ -101,7 +92,7 @@ public: theMap[position].first = key; theMap[position].second = value; ++_size; - if (storedValue != NULL) { + if (storedValue != nullptr) { *storedValue = Iterator(&theMap[position]); } return HasReturnvaluesIF::RETURN_OK; diff --git a/subsystem/Subsystem.cpp b/subsystem/Subsystem.cpp index fcf2e189..094e79b4 100644 --- a/subsystem/Subsystem.cpp +++ b/subsystem/Subsystem.cpp @@ -549,7 +549,7 @@ Mode_t Subsystem::getFallbackSequence(Mode_t sequence) { for (FixedMap::Iterator iter = modeSequences.begin(); iter != modeSequences.end(); ++iter) { if (iter.value->first == sequence) { - return iter->fallbackSequence; + return iter->second.fallbackSequence; } } return -1; @@ -558,7 +558,7 @@ Mode_t Subsystem::getFallbackSequence(Mode_t sequence) { bool Subsystem::isFallbackSequence(Mode_t SequenceId) { for (FixedMap::Iterator iter = modeSequences.begin(); iter != modeSequences.end(); iter++) { - if (iter->fallbackSequence == SequenceId) { + if (iter->second.fallbackSequence == SequenceId) { return true; } } diff --git a/tmtcservices/CommandingServiceBase.cpp b/tmtcservices/CommandingServiceBase.cpp index 331bc7c8..b08e315d 100644 --- a/tmtcservices/CommandingServiceBase.cpp +++ b/tmtcservices/CommandingServiceBase.cpp @@ -104,8 +104,8 @@ void CommandingServiceBase::handleCommandMessage(CommandMessage* reply) { // Implemented by child class, specifies what to do with reply. - ReturnValue_t result = handleReply(reply, iter->command, &iter->state, - &nextCommand, iter->objectId, &isStep); + ReturnValue_t result = handleReply(reply, iter->second.command, &iter->second.state, + &nextCommand, iter->second.objectId, &isStep); /* If the child implementation does not implement special handling for * rejected replies (RETURN_FAILED is returned), a failure verification @@ -114,7 +114,7 @@ void CommandingServiceBase::handleCommandMessage(CommandMessage* reply) { if(reply->getCommand() == CommandMessage::REPLY_REJECTED and result == RETURN_FAILED) { result = reply->getReplyRejectedReason(); - failureParameter1 = iter->command; + failureParameter1 = iter->second.command; } switch (result) { @@ -131,14 +131,14 @@ void CommandingServiceBase::handleCommandMessage(CommandMessage* reply) { default: if (isStep) { verificationReporter.sendFailureReport( - TC_VERIFY::PROGRESS_FAILURE, iter->tcInfo.ackFlags, - iter->tcInfo.tcPacketId, iter->tcInfo.tcSequenceControl, - result, ++iter->step, failureParameter1, + TC_VERIFY::PROGRESS_FAILURE, iter->second.tcInfo.ackFlags, + iter->second.tcInfo.tcPacketId, iter->second.tcInfo.tcSequenceControl, + result, ++iter->second.step, failureParameter1, failureParameter2); } else { verificationReporter.sendFailureReport( - TC_VERIFY::COMPLETION_FAILURE, iter->tcInfo.ackFlags, - iter->tcInfo.tcPacketId, iter->tcInfo.tcSequenceControl, + TC_VERIFY::COMPLETION_FAILURE, iter->second.tcInfo.ackFlags, + iter->second.tcInfo.tcPacketId, iter->second.tcInfo.tcSequenceControl, result, 0, failureParameter1, failureParameter2); } failureParameter1 = 0; @@ -152,7 +152,7 @@ void CommandingServiceBase::handleCommandMessage(CommandMessage* reply) { void CommandingServiceBase::handleReplyHandlerResult(ReturnValue_t result, CommandMapIter iter, CommandMessage* nextCommand, CommandMessage* reply, bool& isStep) { - iter->command = nextCommand->getCommand(); + iter->second.command = nextCommand->getCommand(); // In case a new command is to be sent immediately, this is performed here. // If no new command is sent, only analyse reply result by initializing @@ -167,14 +167,14 @@ void CommandingServiceBase::handleReplyHandlerResult(ReturnValue_t result, if (isStep and result != NO_STEP_MESSAGE) { verificationReporter.sendSuccessReport( TC_VERIFY::PROGRESS_SUCCESS, - iter->tcInfo.ackFlags, iter->tcInfo.tcPacketId, - iter->tcInfo.tcSequenceControl, ++iter->step); + iter->second.tcInfo.ackFlags, iter->second.tcInfo.tcPacketId, + iter->second.tcInfo.tcSequenceControl, ++iter->second.step); } else { verificationReporter.sendSuccessReport( TC_VERIFY::COMPLETION_SUCCESS, - iter->tcInfo.ackFlags, iter->tcInfo.tcPacketId, - iter->tcInfo.tcSequenceControl, 0); + iter->second.tcInfo.ackFlags, iter->second.tcInfo.tcPacketId, + iter->second.tcInfo.tcSequenceControl, 0); checkAndExecuteFifo(iter); } } @@ -182,16 +182,16 @@ void CommandingServiceBase::handleReplyHandlerResult(ReturnValue_t result, if (isStep) { nextCommand->clearCommandMessage(); verificationReporter.sendFailureReport( - TC_VERIFY::PROGRESS_FAILURE, iter->tcInfo.ackFlags, - iter->tcInfo.tcPacketId, - iter->tcInfo.tcSequenceControl, sendResult, - ++iter->step, failureParameter1, failureParameter2); + TC_VERIFY::PROGRESS_FAILURE, iter->second.tcInfo.ackFlags, + iter->second.tcInfo.tcPacketId, + iter->second.tcInfo.tcSequenceControl, sendResult, + ++iter->second.step, failureParameter1, failureParameter2); } else { nextCommand->clearCommandMessage(); verificationReporter.sendFailureReport( TC_VERIFY::COMPLETION_FAILURE, - iter->tcInfo.ackFlags, iter->tcInfo.tcPacketId, - iter->tcInfo.tcSequenceControl, sendResult, 0, + iter->second.tcInfo.ackFlags, iter->second.tcInfo.tcPacketId, + iter->second.tcInfo.tcSequenceControl, sendResult, 0, failureParameter1, failureParameter2); } failureParameter1 = 0; @@ -230,7 +230,7 @@ void CommandingServiceBase::handleRequestQueue() { iter = commandMap.find(queue); if (iter != commandMap.end()) { - result = iter->fifo.insert(address); + result = iter->second.fifo.insert(address); if (result != RETURN_OK) { rejectPacket(TC_VERIFY::START_FAILURE, &packet, OBJECT_BUSY); } @@ -298,11 +298,11 @@ void CommandingServiceBase::startExecution(TcPacketStored *storedPacket, CommandMapIter iter) { ReturnValue_t result = RETURN_OK; CommandMessage command; - iter->subservice = storedPacket->getSubService(); - result = prepareCommand(&command, iter->subservice, + iter->second.subservice = storedPacket->getSubService(); + result = prepareCommand(&command, iter->second.subservice, storedPacket->getApplicationData(), - storedPacket->getApplicationDataSize(), &iter->state, - iter->objectId); + storedPacket->getApplicationDataSize(), &iter->second.state, + iter->second.objectId); ReturnValue_t sendResult = RETURN_OK; switch (result) { @@ -312,13 +312,13 @@ void CommandingServiceBase::startExecution(TcPacketStored *storedPacket, &command); } if (sendResult == RETURN_OK) { - Clock::getUptime(&iter->uptimeOfStart); - iter->step = 0; - iter->subservice = storedPacket->getSubService(); - iter->command = command.getCommand(); - iter->tcInfo.ackFlags = storedPacket->getAcknowledgeFlags(); - iter->tcInfo.tcPacketId = storedPacket->getPacketId(); - iter->tcInfo.tcSequenceControl = + Clock::getUptime(&iter->second.uptimeOfStart); + iter->second.step = 0; + iter->second.subservice = storedPacket->getSubService(); + iter->second.command = command.getCommand(); + iter->second.tcInfo.ackFlags = storedPacket->getAcknowledgeFlags(); + iter->second.tcInfo.tcPacketId = storedPacket->getPacketId(); + iter->second.tcInfo.tcSequenceControl = storedPacket->getPacketSequenceControl(); acceptPacket(TC_VERIFY::START_SUCCESS, storedPacket); } else { @@ -368,7 +368,7 @@ void CommandingServiceBase::acceptPacket(uint8_t reportId, void CommandingServiceBase::checkAndExecuteFifo(CommandMapIter iter) { store_address_t address; - if (iter->fifo.retrieve(&address) != RETURN_OK) { + if (iter->second.fifo.retrieve(&address) != RETURN_OK) { commandMap.erase(&iter); } else { TcPacketStored newPacket(address); @@ -394,10 +394,10 @@ void CommandingServiceBase::checkTimeout() { Clock::getUptime(&uptime); CommandMapIter iter; for (iter = commandMap.begin(); iter != commandMap.end(); ++iter) { - if ((iter->uptimeOfStart + (timeoutSeconds * 1000)) < uptime) { + if ((iter->second.uptimeOfStart + (timeoutSeconds * 1000)) < uptime) { verificationReporter.sendFailureReport( - TC_VERIFY::COMPLETION_FAILURE, iter->tcInfo.ackFlags, - iter->tcInfo.tcPacketId, iter->tcInfo.tcSequenceControl, + TC_VERIFY::COMPLETION_FAILURE, iter->second.tcInfo.ackFlags, + iter->second.tcInfo.tcPacketId, iter->second.tcInfo.tcSequenceControl, TIMEOUT); checkAndExecuteFifo(iter); } From e963aca02a343a8afa46e5ef0103307b1b87248d Mon Sep 17 00:00:00 2001 From: Steffen Gaisser Date: Tue, 11 Aug 2020 17:02:19 +0200 Subject: [PATCH 2/8] Fixed an issue with memmove in FixedOrderedMultimap --- container/FixedOrderedMultimap.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/container/FixedOrderedMultimap.h b/container/FixedOrderedMultimap.h index 4f81c97c..4ddc5dcb 100644 --- a/container/FixedOrderedMultimap.h +++ b/container/FixedOrderedMultimap.h @@ -48,7 +48,7 @@ private: if (_size <= position) { return; } - memmove(&theMap[position], &theMap[position + 1], + memmove(static_cast(&theMap[position]), static_cast(&theMap[position + 1]), (_size - position - 1) * sizeof(std::pair)); --_size; } @@ -87,7 +87,7 @@ public: return MAP_FULL; } uint32_t position = findNicePlace(key); - memmove(&theMap[position + 1], &theMap[position], + memmove(static_cast(&theMap[position + 1]),static_cast(&theMap[position]), (_size - position) * sizeof(std::pair)); theMap[position].first = key; theMap[position].second = value; From b484e4d5ad7325597fa42905fdb984ec145a475e Mon Sep 17 00:00:00 2001 From: Steffen Gaisser Date: Thu, 13 Aug 2020 10:27:16 +0200 Subject: [PATCH 3/8] Removed unused function --- container/FixedOrderedMultimap.h | 6 ------ 1 file changed, 6 deletions(-) diff --git a/container/FixedOrderedMultimap.h b/container/FixedOrderedMultimap.h index 4ddc5dcb..872425e6 100644 --- a/container/FixedOrderedMultimap.h +++ b/container/FixedOrderedMultimap.h @@ -136,12 +136,6 @@ public: return HasReturnvaluesIF::RETURN_OK; } - //This is potentially unsafe -// T *findValue(key_t key) const { -// return &theMap[findFirstIndex(key)].second; -// } - - Iterator find(key_t key) const { ReturnValue_t result = exists(key); if (result != HasReturnvaluesIF::RETURN_OK) { From 2a28114b49fc48d01e95bb350d8c52d299bcab5c Mon Sep 17 00:00:00 2001 From: Steffen Gaisser Date: Mon, 7 Sep 2020 15:43:48 +0200 Subject: [PATCH 4/8] Fixes for #190 and #189 --- container/DynamicFIFO.h | 16 ++++++++++++++-- container/FIFO.h | 12 ++++++++++++ container/FixedMap.h | 3 +++ tmtcservices/CommandingServiceBase.h | 17 +++++++++++++++-- 4 files changed, 44 insertions(+), 4 deletions(-) diff --git a/container/DynamicFIFO.h b/container/DynamicFIFO.h index abb53330..8f5c5e40 100644 --- a/container/DynamicFIFO.h +++ b/container/DynamicFIFO.h @@ -27,14 +27,26 @@ public: /** * @brief Custom copy constructor which prevents setting the - * underlying pointer wrong. + * underlying pointer wrong. This function allocates memory! + * @details This is a very heavy operation so try to avoid this! + * */ DynamicFIFO(const DynamicFIFO& other): FIFOBase(other), fifoVector(other.maxCapacity) { this->setContainer(fifoVector.data()); } - + /** + * @brief Custom assignment operator + * @details This is a very heavy operation so try to avoid this! + * @param other DyamicFIFO to copy from + */ + DynamicFIFO& operator=(const DynamicFIFO& other){ + FIFOBase::operator=(other); + this->fifoVector = other.fifoVector; + this->setContainer(fifoVector.data()); + return *this; + } private: std::vector fifoVector; }; diff --git a/container/FIFO.h b/container/FIFO.h index 19f763fc..70113852 100644 --- a/container/FIFO.h +++ b/container/FIFO.h @@ -25,9 +25,21 @@ public: * @param other */ FIFO(const FIFO& other): FIFOBase(other) { + this->fifoArray = other.fifoArray; this->setContainer(fifoArray.data()); } + /** + * @brief Custom assignment operator + * @param other + */ + FIFO& operator=(const FIFO& other){ + FIFOBase::operator=(other); + this->fifoArray = other.fifoArray; + this->setContainer(fifoArray.data()); + return *this; + } + private: std::array fifoArray; }; diff --git a/container/FixedMap.h b/container/FixedMap.h index dc19ce53..65459631 100644 --- a/container/FixedMap.h +++ b/container/FixedMap.h @@ -4,12 +4,15 @@ #include "ArrayList.h" #include "../returnvalues/HasReturnvaluesIF.h" #include +#include /** * \ingroup container */ template class FixedMap: public SerializeIF { + static_assert (std::is_trivially_copyable::value or std::is_base_of::value, + "Types used in FixedMap must either be trivial copy-able or a derived Class from SerializeIF to be serialize-able"); public: static const uint8_t INTERFACE_ID = CLASS_ID::FIXED_MAP; static const ReturnValue_t KEY_ALREADY_EXISTS = MAKE_RETURN_CODE(0x01); diff --git a/tmtcservices/CommandingServiceBase.h b/tmtcservices/CommandingServiceBase.h index 864a0614..23b08acf 100644 --- a/tmtcservices/CommandingServiceBase.h +++ b/tmtcservices/CommandingServiceBase.h @@ -211,8 +211,7 @@ protected: virtual void doPeriodicOperation(); - - struct CommandInfo { + struct CommandInfo: public SerializeIF{ struct tcInfo { uint8_t ackFlags; uint16_t tcPacketId; @@ -225,6 +224,20 @@ protected: Command_t command; object_id_t objectId; FIFO fifo; + + virtual ReturnValue_t serialize(uint8_t **buffer, size_t *size, + size_t maxSize, Endianness streamEndianness) const override{ + return HasReturnvaluesIF::RETURN_FAILED; + }; + + virtual size_t getSerializedSize() const override { + return 0; + }; + + virtual ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size, + Endianness streamEndianness) override{ + return HasReturnvaluesIF::RETURN_FAILED; + }; }; using CommandMapIter = FixedMap Date: Mon, 7 Sep 2020 15:49:28 +0200 Subject: [PATCH 5/8] Another fix in DynamicFIFO --- container/DynamicFIFO.h | 1 + 1 file changed, 1 insertion(+) diff --git a/container/DynamicFIFO.h b/container/DynamicFIFO.h index 8f5c5e40..86d43f7d 100644 --- a/container/DynamicFIFO.h +++ b/container/DynamicFIFO.h @@ -33,6 +33,7 @@ public: */ DynamicFIFO(const DynamicFIFO& other): FIFOBase(other), fifoVector(other.maxCapacity) { + this->fifoVector = other.fifoVector; this->setContainer(fifoVector.data()); } From b65789824cc103d8fbc46479e6eff0f09c6346d6 Mon Sep 17 00:00:00 2001 From: Steffen Gaisser Date: Mon, 7 Sep 2020 18:06:08 +0200 Subject: [PATCH 6/8] Removed old hacks and replaced by standard c++ Added overflow check in SerializeAdapter --- container/IsDerivedFrom.h | 41 ------------------------------------ serialize/SerializeAdapter.h | 32 ++++++++++++++++------------ 2 files changed, 18 insertions(+), 55 deletions(-) delete mode 100644 container/IsDerivedFrom.h diff --git a/container/IsDerivedFrom.h b/container/IsDerivedFrom.h deleted file mode 100644 index 520033db..00000000 --- a/container/IsDerivedFrom.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef ISDERIVEDFROM_H_ -#define ISDERIVEDFROM_H_ - -template -class IsDerivedFrom { - class No { - }; - class Yes { - No no[3]; - }; - - static Yes Test(B*); // declared, but not defined - static No Test(... ); // declared, but not defined - -public: - enum { - Is = sizeof(Test(static_cast(0))) == sizeof(Yes) - }; -}; - -template -struct is_same { - static bool const value = false; -}; - -template -struct is_same { - static bool const value = true; -}; - - -template -struct enable_if { - typedef T type; -}; - -template -struct enable_if { }; - - -#endif /* ISDERIVEDFROM_H_ */ diff --git a/serialize/SerializeAdapter.h b/serialize/SerializeAdapter.h index af5ec116..cd6b6b06 100644 --- a/serialize/SerializeAdapter.h +++ b/serialize/SerializeAdapter.h @@ -1,11 +1,11 @@ #ifndef SERIALIZEADAPTER_H_ #define SERIALIZEADAPTER_H_ -#include "../container/IsDerivedFrom.h" #include "../returnvalues/HasReturnvaluesIF.h" #include "EndianConverter.h" #include "SerializeIF.h" #include +#include /** * \ingroup serialize @@ -15,34 +15,39 @@ class SerializeAdapter { public: 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); } template static uint32_t getSerializedSize(const T *object) { - InternalSerializeAdapter::Is> adapter; + InternalSerializeAdapter::value> adapter; return adapter.getSerializedSize(object); } 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 { + template class InternalSerializeAdapter; + + template + class InternalSerializeAdapter { public: static ReturnValue_t serialize(const T *object, uint8_t **buffer, - size_t *size, size_t max_size, SerializeIF::Endianness streamEndianness) { + size_t *size, size_t max_size, + SerializeIF::Endianness streamEndianness) { size_t ignoredSize = 0; if (size == NULL) { 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: @@ -94,14 +99,13 @@ private: uint32_t getSerializedSize(const T *object) { return sizeof(T); } - }; 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 == NULL) { From 0258ce62f0ccb64be8f87e17321627171601f348 Mon Sep 17 00:00:00 2001 From: Steffen Gaisser Date: Mon, 7 Sep 2020 18:35:25 +0200 Subject: [PATCH 7/8] Added documentation --- serialize/SerializeAdapter.h | 71 ++++++++++++++++++++++++++++++++---- serialize/SerializeIF.h | 2 +- 2 files changed, 64 insertions(+), 9 deletions(-) diff --git a/serialize/SerializeAdapter.h b/serialize/SerializeAdapter.h index cd6b6b06..a05b1791 100644 --- a/serialize/SerializeAdapter.h +++ b/serialize/SerializeAdapter.h @@ -1,10 +1,10 @@ -#ifndef SERIALIZEADAPTER_H_ -#define 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 /** @@ -13,6 +13,22 @@ 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, @@ -21,11 +37,35 @@ public: 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) { + 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) { @@ -33,16 +73,26 @@ public: return adapter.deSerialize(object, buffer, size, streamEndianness); } private: + /** + * 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, SerializeIF::Endianness streamEndianness) { size_t ignoredSize = 0; - if (size == NULL) { + if (size == nullptr) { size = &ignoredSize; } //Check remaining size is large enough and check integer overflow of *size @@ -101,6 +151,11 @@ private: } }; + /** + * Template for objects that inherit from SerializeIF + * + * @tparam T A child of SerializeIF + */ template class InternalSerializeAdapter { public: @@ -108,12 +163,12 @@ private: size_t max_size, SerializeIF::Endianness streamEndianness) const { size_t ignoredSize = 0; - if (size == NULL) { + if (size == nullptr) { size = &ignoredSize; } 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(); } @@ -124,4 +179,4 @@ private: }; }; -#endif /* SERIALIZEADAPTER_H_ */ +#endif /* _FSFW_SERIALIZE_SERIALIZEADAPTER_H_ */ diff --git a/serialize/SerializeIF.h b/serialize/SerializeIF.h index 7f9ea9df..a701fe53 100644 --- a/serialize/SerializeIF.h +++ b/serialize/SerializeIF.h @@ -43,7 +43,7 @@ public: * @param[in] maxSize The size of the buffer that is allowed to be used for serialize. * @param[in] streamEndianness Endianness of the serialized data according to SerializeIF::Endianness * @return - * - @ยข BUFFER_TOO_SHORT The given buffer in is too short + * - @c BUFFER_TOO_SHORT The given buffer in is too short * - @c RETURN_FAILED Generic error * - @c RETURN_OK Successful serialization */ From e7444912d5eb69dc701b12f7de5f94d730d2992d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robin=20M=C3=BCller?= Date: Thu, 10 Sep 2020 15:29:19 +0200 Subject: [PATCH 8/8] corrected include guard --- container/FixedMap.h | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/container/FixedMap.h b/container/FixedMap.h index 56a6140a..d1cc31ff 100644 --- a/container/FixedMap.h +++ b/container/FixedMap.h @@ -1,5 +1,5 @@ -#ifndef FRAMEWORK_CONTAINER_FIXEDMAP_H_ -#define FRAMEWORK_CONTAINER_FIXEDMAP_H_ +#ifndef FSFW_CONTAINER_FIXEDMAP_H_ +#define FSFW_CONTAINER_FIXEDMAP_H_ #include "ArrayList.h" #include "../returnvalues/HasReturnvaluesIF.h" @@ -7,11 +7,9 @@ #include /** - * \ingroup container - * - * - * \warning Iterators return a non-const key_t in the pair. - * \warning A User is not allowed to change the key, otherwise the map is corrupted. + * @warning Iterators return a non-const key_t in the pair. + * @warning A User is not allowed to change the key, otherwise the map is corrupted. + * @ingroup container */ template class FixedMap: public SerializeIF { @@ -194,4 +192,4 @@ public: }; -#endif /* FIXEDMAP_H_ */ +#endif /* FSFW_CONTAINER_FIXEDMAP_H_ */