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
This commit is contained in:
Robin Müller 2020-01-16 18:46:29 +01:00
parent 1437f33027
commit 9bdbc2c380
3 changed files with 149 additions and 5 deletions

View File

@ -14,6 +14,14 @@ public:
ArrayList<T, count_t>(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<T, count_t>(data, MAX_SIZE) {
// memcpy(data, data_, count);
// }
FixedArrayList(const FixedArrayList& other) :
ArrayList<T, count_t>(data, MAX_SIZE) {
memcpy(this->data, other.data, sizeof(this->data));

View File

@ -48,17 +48,14 @@ public:
}
template<typename T>
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<const uint8_t *>(in);
uint8_t * out_buffer = reinterpret_cast<uint8_t *>(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;

View File

@ -0,0 +1,139 @@
#ifndef SERIALBUFFERADAPTER2_H_
#define SERIALBUFFERADAPTER2_H_
#include <framework/serialize/SerializeIF.h>
#include <framework/serialize/SerializeAdapter.h>
#include <framework/serviceinterface/ServiceInterfaceStream.h>
#include <cstring>
/**
* 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<SerialBufferAdapter<bufferLengthType(will be uint8_t mostly)>> serialBufferElement.
* Right now, the SerialBufferAdapter must always be initialized with the buffer and size !
*
* \ingroup serialize
*/
template<typename BUFFER_TYPE = uint8_t, typename count_t = uint8_t>
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<BUFFER_TYPE>::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<BUFFER_TYPE>(pTmp,*buffer, bufferLength);
} else {
pTmp = const_cast<uint8_t *>(*buffer);
}
*size -= bufferLength;
memcpy(const_cast<void *>(reinterpret_cast<const void*>(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<uint8_t *>(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_ */