From 9bdbc2c380780ae7f523c4367560a13f1c64ca66 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 16 Jan 2020 18:46:29 +0100 Subject: [PATCH] Endian swapper changes, Serial buffer adapter New Serial Buffer Adapter with complete template class for buffer type. Endian Swapper input now standard uint8_t * pointers instead of template type. Fixed Array List new ctor, but commented out for now --- container/FixedArrayList.h | 8 ++ serialize/EndianSwapper.h | 7 +- serialize/SerialBufferAdapter2.h | 139 +++++++++++++++++++++++++++++++ 3 files changed, 149 insertions(+), 5 deletions(-) create mode 100644 serialize/SerialBufferAdapter2.h diff --git a/container/FixedArrayList.h b/container/FixedArrayList.h index eeffcc87..ef2a82f5 100644 --- a/container/FixedArrayList.h +++ b/container/FixedArrayList.h @@ -14,6 +14,14 @@ public: ArrayList(data, MAX_SIZE) { } + //We could create a constructor to initialize the fixed array list with data and the known size field + //so it can be used for serialization too (with SerialFixedArrrayListAdapter) + //is this feasible? +// FixedArrayList(T * data_, count_t count): +// ArrayList(data, MAX_SIZE) { +// memcpy(data, data_, count); +// } + FixedArrayList(const FixedArrayList& other) : ArrayList(data, MAX_SIZE) { memcpy(this->data, other.data, sizeof(this->data)); diff --git a/serialize/EndianSwapper.h b/serialize/EndianSwapper.h index db170c0b..6c391316 100644 --- a/serialize/EndianSwapper.h +++ b/serialize/EndianSwapper.h @@ -48,17 +48,14 @@ public: } template - static void swap(T * out, const T * in, uint32_t size) { + static void swap(uint8_t * out, const uint8_t * in, uint32_t size) { #ifndef BYTE_ORDER_SYSTEM #error BYTE_ORDER_SYSTEM not defined #elif BYTE_ORDER_SYSTEM == LITTLE_ENDIAN - const uint8_t * in_buffer = reinterpret_cast(in); - uint8_t * out_buffer = reinterpret_cast(out); for (uint8_t count = 0; count < size; count++) { for(uint8_t i = 0; i < sizeof(T);i++) { - out_buffer[sizeof(T)* (count + 1) - i - 1] = in_buffer[count * sizeof(T) + i]; + out[sizeof(T)* (count + 1) - i - 1] = in[count * sizeof(T) + i]; } - } return; diff --git a/serialize/SerialBufferAdapter2.h b/serialize/SerialBufferAdapter2.h new file mode 100644 index 00000000..a9613d94 --- /dev/null +++ b/serialize/SerialBufferAdapter2.h @@ -0,0 +1,139 @@ +#ifndef SERIALBUFFERADAPTER2_H_ +#define SERIALBUFFERADAPTER2_H_ + +#include +#include +#include + +#include + +/** + * This adapter provides an interface for SerializeIF to serialize or deserialize + * buffers with no length header but a known size. + * + * Additionally, the buffer length can be serialized too and will be put in front of the serialized buffer. + * + * Can be used with SerialLinkedListAdapter by declaring a SerializeElement with + * SerialElement> serialBufferElement. + * Right now, the SerialBufferAdapter must always be initialized with the buffer and size ! + * + * \ingroup serialize + */ +template +class SerialBufferAdapter2: public SerializeIF { +public: + /** + * Constructor for constant uint8_t buffer. Length field can be serialized optionally. + * Type of length can be supplied as template type. + * @param buffer + * @param bufferLength + * @param serializeLength + */ + SerialBufferAdapter2(BUFFER_TYPE * buffer_, count_t bufferLength_, bool serializeLength_ = false): + buffer(buffer_),bufferLength(bufferLength_), serializeLength(serializeLength_) { + determineLengthMultiplier(sizeof(count_t)); + if(std::is_const::value) { + isConst = true; + } + } + + ReturnValue_t serialize(uint8_t ** buffer, uint32_t* size, + const uint32_t max_size, bool bigEndian) const { + uint32_t serializedLength = bufferLength; + if (serializeLength) { + serializedLength += AutoSerializeAdapter::getSerializedSize( + &bufferLength); + } + if (*size + serializedLength > max_size) { + return BUFFER_TOO_SHORT; + } else { + if (serializeLength) { + AutoSerializeAdapter::serialize(&bufferLength, buffer, size, + max_size, bigEndian); + } + memcpy(*buffer, this->buffer, bufferLength); + *size += bufferLength; + (*buffer) += bufferLength; + return HasReturnvaluesIF::RETURN_OK; + } + } + + uint32_t getSerializedSize() const { + if (serializeLength) { + return bufferLength + AutoSerializeAdapter::getSerializedSize(&bufferLength); + } else { + return bufferLength; + } + } + + ReturnValue_t deSerialize(const uint8_t** buffer, + int32_t* size, bool bigEndian) { + //TODO Ignores Endian flag! + //UPDATE: Endian swapper introduced. Must be tested.. + if (buffer != NULL) { + if(serializeLength){ + count_t serializedSize = AutoSerializeAdapter::getSerializedSize( + &bufferLength); + if((*size - bufferLength - serializedSize) >= 0){ + *buffer += serializedSize; + *size -= serializedSize; + }else{ + return STREAM_TOO_SHORT; + } + } + //No Else If, go on with buffer + if (*size - bufferLength >= 0) { + uint8_t tmp [bufferLength]; + uint8_t * pTmp = tmp; + if (bigEndian) { + EndianSwapper::swap(pTmp,*buffer, bufferLength); + } else { + pTmp = const_cast(*buffer); + } + *size -= bufferLength; + memcpy(const_cast(reinterpret_cast(this->buffer)), pTmp, bufferLength); + (*buffer) += bufferLength; + return HasReturnvaluesIF::RETURN_OK; + } else { + return STREAM_TOO_SHORT; + } + } else { + return HasReturnvaluesIF::RETURN_FAILED; + } + } + + + uint8_t * getBuffer() { + return reinterpret_cast(buffer); + } + + void setBuffer(BUFFER_TYPE * buffer_, count_t bufferLength_, bool serializeLength_ = false) { + buffer = buffer_; + bufferLength = bufferLength_; + serializeLength = serializeLength_; + determineLengthMultiplier(sizeof(count_t)); + } +private: + BUFFER_TYPE * buffer; + count_t bufferLength; + bool serializeLength; + + bool isConst = false; + + void determineLengthMultiplier(uint8_t typeSize) { + switch(typeSize) { + case(2): + bufferLength *= 2; break; + case(4): + bufferLength *= 4; break; + case(8): + bufferLength *= 8; break; + default: + warning << "Invalid type size, assuming regular uint8_t." << std::endl; + } + } +}; + + + +#endif /* SERIALBUFFERADAPTER2_H_ */