Merge remote-tracking branch 'upstream/mohr_serialize' into mueller_merge_mohr_serialize
This commit is contained in:
@ -5,13 +5,9 @@
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
|
||||
/**
|
||||
* @brief Can be used to swap endianness of data
|
||||
* into big endian
|
||||
*/
|
||||
class EndianSwapper {
|
||||
class EndianConverter {
|
||||
private:
|
||||
EndianSwapper() {};
|
||||
EndianConverter() {};
|
||||
public:
|
||||
/**
|
||||
* Swap the endianness of a variable with arbitrary type
|
||||
@ -20,13 +16,13 @@ public:
|
||||
* @return Variable with swapped endianness
|
||||
*/
|
||||
template<typename T>
|
||||
static T swap(T in) {
|
||||
static T convertBigEndian(T in) {
|
||||
#ifndef BYTE_ORDER_SYSTEM
|
||||
#error BYTE_ORDER_SYSTEM not defined
|
||||
#elif BYTE_ORDER_SYSTEM == LITTLE_ENDIAN
|
||||
T tmp;
|
||||
uint8_t *pointerOut = (uint8_t *) &tmp;
|
||||
uint8_t *pointerIn = (uint8_t *) ∈
|
||||
uint8_t *pointerOut = (uint8_t*) &tmp;
|
||||
uint8_t *pointerIn = (uint8_t*) ∈
|
||||
for (uint8_t count = 0; count < sizeof(T); count++) {
|
||||
pointerOut[sizeof(T) - count - 1] = pointerIn[count];
|
||||
}
|
||||
@ -38,13 +34,8 @@ public:
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Swap the endianness of a buffer.
|
||||
* @param out
|
||||
* @param in
|
||||
* @param size
|
||||
*/
|
||||
static void swap(uint8_t* out, const uint8_t* in, size_t size) {
|
||||
static void convertBigEndian(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
|
||||
@ -58,30 +49,36 @@ public:
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Swap endianness of buffer entries
|
||||
* Template argument specifies buffer type. The number of entries
|
||||
* (not the buffer size!) must be supplied
|
||||
* @param out
|
||||
* @param in
|
||||
* @param size Number of buffer entries (not size of buffer in bytes!)
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
static void swap(T * out, const T * in, uint32_t entries) {
|
||||
static T convertLittleEndian(T in) {
|
||||
#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 < entries; count++) {
|
||||
for(uint8_t i = 0; i < sizeof(T);i++) {
|
||||
out_buffer[sizeof(T)* (count + 1) - i - 1] =
|
||||
in_buffer[count * sizeof(T) + i];
|
||||
#error BYTE_ORDER_SYSTEM not defined
|
||||
#elif BYTE_ORDER_SYSTEM == BIG_ENDIAN
|
||||
T tmp;
|
||||
uint8_t *pointerOut = (uint8_t *) &tmp;
|
||||
uint8_t *pointerIn = (uint8_t *) ∈
|
||||
for (uint8_t count = 0; count < sizeof(T); count++) {
|
||||
pointerOut[sizeof(T) - count - 1] = pointerIn[count];
|
||||
}
|
||||
}
|
||||
return;
|
||||
#elif BYTE_ORDER_SYSTEM == BIG_ENDIAN
|
||||
memcpy(out, in, size*sizeof(T));
|
||||
return tmp;
|
||||
#elif BYTE_ORDER_SYSTEM == LITTLE_ENDIAN
|
||||
return in;
|
||||
#else
|
||||
#error Unknown Byte Order
|
||||
#endif
|
||||
}
|
||||
static void convertLittleEndian(uint8_t *out, const uint8_t *in,
|
||||
uint32_t size) {
|
||||
#ifndef BYTE_ORDER_SYSTEM
|
||||
#error BYTE_ORDER_SYSTEM not defined
|
||||
#elif BYTE_ORDER_SYSTEM == BIG_ENDIAN
|
||||
for (uint8_t count = 0; count < size; count++) {
|
||||
out[size - count - 1] = in[count];
|
||||
}
|
||||
return;
|
||||
#elif BYTE_ORDER_SYSTEM == LITTLE_ENDIAN
|
||||
memcpy(out, in, size);
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
|
@ -22,26 +22,24 @@ public:
|
||||
}
|
||||
|
||||
virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size,
|
||||
const size_t max_size, bool bigEndian) const override {
|
||||
return serialize(adaptee, buffer, size, max_size, bigEndian);
|
||||
size_t maxSize, Endianness streamEndianness) const {
|
||||
return serialize(adaptee, buffer, size, maxSize, streamEndianness);
|
||||
}
|
||||
|
||||
static ReturnValue_t serialize(const ArrayList<T, count_t>* list,
|
||||
uint8_t** buffer, size_t* size, const size_t max_size,
|
||||
bool bigEndian) {
|
||||
// Serialize length field first
|
||||
ReturnValue_t result = SerializeAdapter<count_t>::serialize(&list->size,
|
||||
buffer, size, max_size, bigEndian);
|
||||
static ReturnValue_t serialize(const ArrayList<T, count_t>* list, uint8_t** buffer, size_t* size,
|
||||
size_t maxSize, Endianness streamEndianness) {
|
||||
ReturnValue_t result = SerializeAdapter::serialize(&list->size,
|
||||
buffer, size, maxSize, streamEndianness);
|
||||
count_t i = 0;
|
||||
while ((result == HasReturnvaluesIF::RETURN_OK) && (i < list->size)) {
|
||||
result = SerializeAdapter<T>::serialize(&list->entries[i], buffer, size,
|
||||
max_size, bigEndian);
|
||||
result = SerializeAdapter::serialize(&list->entries[i], buffer, size,
|
||||
maxSize, streamEndianness);
|
||||
++i;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
virtual size_t getSerializedSize() const override {
|
||||
virtual size_t getSerializedSize() const {
|
||||
return getSerializedSize(adaptee);
|
||||
}
|
||||
|
||||
@ -50,34 +48,31 @@ public:
|
||||
count_t i = 0;
|
||||
|
||||
for (i = 0; i < list->size; ++i) {
|
||||
printSize += SerializeAdapter<T>::getSerializedSize(&list->entries[i]);
|
||||
printSize += SerializeAdapter::getSerializedSize(&list->entries[i]);
|
||||
}
|
||||
|
||||
return printSize;
|
||||
}
|
||||
|
||||
virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
|
||||
bool bigEndian) override {
|
||||
return deSerialize(adaptee, buffer, size, bigEndian);
|
||||
Endianness streamEndianness) {
|
||||
return deSerialize(adaptee, buffer, size, streamEndianness);
|
||||
}
|
||||
|
||||
static ReturnValue_t deSerialize(ArrayList<T, count_t>* list,
|
||||
const uint8_t** buffer, size_t* size, bool bigEndian) {
|
||||
static ReturnValue_t deSerialize(ArrayList<T, count_t>* list, const uint8_t** buffer, size_t* size,
|
||||
Endianness streamEndianness) {
|
||||
count_t tempSize = 0;
|
||||
ReturnValue_t result = SerializeAdapter<count_t>::deSerialize(&tempSize,
|
||||
buffer, size, bigEndian);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
ReturnValue_t result = SerializeAdapter::deSerialize(&tempSize,
|
||||
buffer, size, streamEndianness);
|
||||
if (tempSize > list->maxSize()) {
|
||||
return SerializeIF::TOO_MANY_ELEMENTS;
|
||||
}
|
||||
list->size = tempSize;
|
||||
count_t i = 0;
|
||||
while ((result == HasReturnvaluesIF::RETURN_OK) && (i < list->size)) {
|
||||
result = SerializeAdapter<T>::deSerialize(
|
||||
result = SerializeAdapter::deSerialize(
|
||||
&list->front()[i], buffer, size,
|
||||
bigEndian);
|
||||
streamEndianness);
|
||||
++i;
|
||||
}
|
||||
return result;
|
||||
|
@ -20,20 +20,20 @@ template<typename count_t>
|
||||
SerialBufferAdapter<count_t>::~SerialBufferAdapter() {
|
||||
}
|
||||
|
||||
template<typename count_t>
|
||||
ReturnValue_t SerialBufferAdapter<count_t>::serialize(uint8_t** buffer_,
|
||||
size_t* size_, const size_t max_size, bool bigEndian) const {
|
||||
template<typename T>
|
||||
ReturnValue_t SerialBufferAdapter<T>::serialize(uint8_t** buffer, size_t* size,
|
||||
size_t maxSize, Endianness streamEndianness) const {
|
||||
uint32_t serializedLength = bufferLength;
|
||||
if (serializeLength) {
|
||||
serializedLength += AutoSerializeAdapter::getSerializedSize(
|
||||
serializedLength += SerializeAdapter::getSerializedSize(
|
||||
&bufferLength);
|
||||
}
|
||||
if (*size_ + serializedLength > max_size) {
|
||||
if (*size + serializedLength > maxSize) {
|
||||
return BUFFER_TOO_SHORT;
|
||||
} else {
|
||||
if (serializeLength) {
|
||||
AutoSerializeAdapter::serialize(&bufferLength, buffer_, size_,
|
||||
max_size, bigEndian);
|
||||
SerializeAdapter::serialize(&bufferLength, buffer, size,
|
||||
maxSize, streamEndianness);
|
||||
}
|
||||
if (constBuffer != nullptr) {
|
||||
memcpy(*buffer_, this->constBuffer, bufferLength);
|
||||
@ -52,22 +52,22 @@ ReturnValue_t SerialBufferAdapter<count_t>::serialize(uint8_t** buffer_,
|
||||
}
|
||||
}
|
||||
|
||||
template<typename count_t>
|
||||
size_t SerialBufferAdapter<count_t>::getSerializedSize() const {
|
||||
template<typename T>
|
||||
size_t SerialBufferAdapter<T>::getSerializedSize() const {
|
||||
if (serializeLength) {
|
||||
return bufferLength + AutoSerializeAdapter::getSerializedSize(&bufferLength);
|
||||
return bufferLength + SerializeAdapter::getSerializedSize(&bufferLength);
|
||||
} else {
|
||||
return bufferLength;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename count_t>
|
||||
ReturnValue_t SerialBufferAdapter<count_t>::deSerialize(const uint8_t** buffer,
|
||||
size_t* size, bool bigEndian) {
|
||||
template<typename T>
|
||||
ReturnValue_t SerialBufferAdapter<T>::deSerialize(const uint8_t** buffer,
|
||||
size_t* size, Endianness streamEndianness) {
|
||||
//TODO Ignores Endian flag!
|
||||
if (buffer != nullptr) {
|
||||
if(serializeLength) {
|
||||
count_t serializedSize = AutoSerializeAdapter::getSerializedSize(
|
||||
if (buffer != NULL) {
|
||||
if(serializeLength){
|
||||
T serializedSize = SerializeAdapter::getSerializedSize(
|
||||
&bufferLength);
|
||||
if(bufferLength + serializedSize <= *size) {
|
||||
*buffer += serializedSize;
|
||||
|
@ -22,52 +22,52 @@ template<typename count_t>
|
||||
class SerialBufferAdapter: 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
|
||||
*/
|
||||
SerialBufferAdapter(const uint8_t* buffer, count_t bufferLength,
|
||||
bool serializeLength = false);
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
SerialBufferAdapter(const uint8_t* buffer, count_t bufferLength,
|
||||
bool serializeLength = false);
|
||||
|
||||
/**
|
||||
* Constructor for non-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 Length field will be serialized with size count_t
|
||||
*/
|
||||
SerialBufferAdapter(uint8_t* buffer, count_t bufferLength,
|
||||
bool serializeLength = false);
|
||||
/**
|
||||
* Constructor for non-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 Length field will be serialized with size count_t
|
||||
*/
|
||||
SerialBufferAdapter(uint8_t* buffer, count_t bufferLength,
|
||||
bool serializeLength = false);
|
||||
|
||||
virtual ~SerialBufferAdapter();
|
||||
virtual ~SerialBufferAdapter();
|
||||
|
||||
virtual ReturnValue_t serialize(uint8_t** buffer_, size_t* size,
|
||||
const size_t max_size, bool bigEndian) const override;
|
||||
virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size,
|
||||
size_t maxSize, Endianness streamEndianness) const override;
|
||||
|
||||
virtual size_t getSerializedSize() const;
|
||||
virtual size_t getSerializedSize() const override;
|
||||
|
||||
/**
|
||||
* @brief This function deserializes a buffer into the member buffer.
|
||||
* @details
|
||||
* If a length field is present, it is ignored, as the size should have
|
||||
* been set in the constructor. If the size is not known beforehand,
|
||||
* consider using SerialFixedArrayListAdapter instead.
|
||||
* @param buffer [out] Resulting buffer
|
||||
* @param size remaining size to deserialize, should be larger than buffer
|
||||
* + size field size
|
||||
* @param bigEndian
|
||||
* @return
|
||||
*/
|
||||
virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
|
||||
bool bigEndian) override;
|
||||
/**
|
||||
* @brief This function deserializes a buffer into the member buffer.
|
||||
* @details
|
||||
* If a length field is present, it is ignored, as the size should have
|
||||
* been set in the constructor. If the size is not known beforehand,
|
||||
* consider using SerialFixedArrayListAdapter instead.
|
||||
* @param buffer [out] Resulting buffer
|
||||
* @param size remaining size to deserialize, should be larger than buffer
|
||||
* + size field size
|
||||
* @param bigEndian
|
||||
* @return
|
||||
*/
|
||||
virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
|
||||
Endianness streamEndianness) override;
|
||||
|
||||
uint8_t * getBuffer();
|
||||
const uint8_t * getConstBuffer();
|
||||
void setBuffer(uint8_t* buffer, count_t bufferLength);
|
||||
uint8_t * getBuffer();
|
||||
const uint8_t * getConstBuffer();
|
||||
void setBuffer(uint8_t* buffer, count_t bufferLength);
|
||||
private:
|
||||
bool serializeLength = false;
|
||||
const uint8_t *constBuffer = nullptr;
|
||||
|
@ -48,20 +48,18 @@ public:
|
||||
buffer, size, max_size, bigEndian);
|
||||
}
|
||||
|
||||
ReturnValue_t serialize(uint8_t** buffer, size_t* size,
|
||||
size_t maxSize, Endianness streamEndianness) const {
|
||||
return SerialArrayListAdapter<T, count_t>::serialize(this, buffer, size, maxSize, streamEndianness);
|
||||
}
|
||||
|
||||
size_t getSerializedSize() const {
|
||||
return SerialArrayListAdapter<BUFFER_TYPE, count_t>::
|
||||
getSerializedSize(this);
|
||||
return SerialArrayListAdapter<T, count_t>::getSerializedSize(this);
|
||||
}
|
||||
|
||||
virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
|
||||
bool bigEndian) override {
|
||||
return SerialArrayListAdapter<BUFFER_TYPE, count_t>::deSerialize(this,
|
||||
buffer, size, bigEndian);
|
||||
}
|
||||
|
||||
void swapArrayListEndianness() {
|
||||
SerialArrayListAdapter<BUFFER_TYPE, count_t>::
|
||||
swapArrayListEndianness(this);
|
||||
ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
|
||||
Endianness streamEndianness) {
|
||||
return SerialArrayListAdapter<T, count_t>::deSerialize(this, buffer, size, streamEndianness);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -67,44 +67,32 @@ public:
|
||||
SinglyLinkedList<T>(), printCount(printCount) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialize object implementing this adapter into the supplied buffer
|
||||
* and calculate the serialized size
|
||||
* @param buffer [out] Object is serialized into this buffer.
|
||||
* Note that the buffer pointer *buffer is incremented automatically
|
||||
* inside the respective serialize functions
|
||||
* @param size [out] Calculated serialized size. Don't forget to set to 0.
|
||||
* @param max_size
|
||||
* @param bigEndian Specify endianness
|
||||
* @return
|
||||
*/
|
||||
virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size,
|
||||
const size_t max_size, bool bigEndian) const override{
|
||||
size_t maxSize, Endianness streamEndianness) const override {
|
||||
if (printCount) {
|
||||
count_t mySize = SinglyLinkedList<T>::getSize();
|
||||
ReturnValue_t result = SerializeAdapter<count_t>::serialize(&mySize,
|
||||
buffer, size, max_size, bigEndian);
|
||||
ReturnValue_t result = SerializeAdapter::serialize(&mySize,
|
||||
buffer, size, maxSize, streamEndianness);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return serialize(SinglyLinkedList<T>::start, buffer, size, max_size,
|
||||
bigEndian);
|
||||
return serialize(SinglyLinkedList<T>::start, buffer, size, maxSize,
|
||||
streamEndianness);
|
||||
}
|
||||
|
||||
static ReturnValue_t serialize(const LinkedElement<T>* element,
|
||||
uint8_t** buffer, size_t* size, const size_t max_size,
|
||||
bool bigEndian) {
|
||||
uint8_t** buffer, size_t* size, size_t maxSize,
|
||||
Endianness streamEndianness) {
|
||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
||||
while ((result == HasReturnvaluesIF::RETURN_OK) && (element != NULL)) {
|
||||
result = element->value->serialize(buffer, size, max_size,
|
||||
bigEndian);
|
||||
result = element->value->serialize(buffer, size, maxSize,
|
||||
streamEndianness);
|
||||
element = element->getNext();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
virtual size_t getSerializedSize() const override {
|
||||
if (printCount) {
|
||||
return SerialLinkedListAdapter<T>::getSerializedSize()
|
||||
@ -114,8 +102,8 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t getSerializedSize(const LinkedElement<T> *element) {
|
||||
uint32_t size = 0;
|
||||
static size_t getSerializedSize(const LinkedElement<T> *element) {
|
||||
size_t size = 0;
|
||||
while (element != NULL) {
|
||||
size += element->value->getSerializedSize();
|
||||
element = element->getNext();
|
||||
@ -124,24 +112,16 @@ public:
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Deserialize supplied buffer with supplied size into object
|
||||
* implementing this adapter.
|
||||
* @param buffer
|
||||
* @param size Decremented in respective deSerialize functions automatically
|
||||
* @param bigEndian Specify endianness
|
||||
* @return
|
||||
*/
|
||||
virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
|
||||
bool bigEndian) override {
|
||||
return deSerialize(SinglyLinkedList<T>::start, buffer, size, bigEndian);
|
||||
Endianness streamEndianness) override {
|
||||
return deSerialize(SinglyLinkedList<T>::start, buffer, size, streamEndianness);
|
||||
}
|
||||
|
||||
static ReturnValue_t deSerialize(LinkedElement<T>* element,
|
||||
const uint8_t** buffer, size_t* size, bool bigEndian) {
|
||||
const uint8_t** buffer, size_t* size, Endianness streamEndianness) {
|
||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
||||
while ((result == HasReturnvaluesIF::RETURN_OK) && (element != NULL)) {
|
||||
result = element->value->deSerialize(buffer, size, bigEndian);
|
||||
result = element->value->deSerialize(buffer, size, streamEndianness);
|
||||
element = element->getNext();
|
||||
}
|
||||
return result;
|
||||
|
@ -62,61 +62,113 @@
|
||||
* @ingroup serialize
|
||||
*/
|
||||
|
||||
// No type specification necessary here.
|
||||
class AutoSerializeAdapter {
|
||||
public:
|
||||
/**
|
||||
* Serialize object into buffer.
|
||||
* @tparam T Type of object.
|
||||
* @param object Object to serialize
|
||||
* @param buffer
|
||||
* Serialize into this buffer, pointer to pointer has to be passed,
|
||||
* *buffer will be incremented automatically.
|
||||
* @param size [out]
|
||||
* Update passed size value, will be incremented by serialized size
|
||||
* @param max_size
|
||||
* Maximum size for range checking
|
||||
* @param bigEndian
|
||||
* Set to true if host-to-network conversion or vice-versa is needed
|
||||
* @return
|
||||
*/
|
||||
template<typename T>
|
||||
static ReturnValue_t serialize(const T* object, uint8_t** buffer,
|
||||
size_t* size, const size_t max_size, bool bigEndian) {
|
||||
SerializeAdapter_<T, IsDerivedFrom<T, SerializeIF>::Is> adapter;
|
||||
return adapter.serialize(object, buffer, size, max_size, bigEndian);
|
||||
}
|
||||
template<typename T>
|
||||
static size_t getSerializedSize(const T* object) {
|
||||
SerializeAdapter_<T, IsDerivedFrom<T, SerializeIF>::Is> adapter;
|
||||
return adapter.getSerializedSize(object);
|
||||
}
|
||||
template<typename T>
|
||||
static ReturnValue_t deSerialize(T* object, const uint8_t** buffer,
|
||||
size_t* size, bool bigEndian) {
|
||||
SerializeAdapter_<T, IsDerivedFrom<T, SerializeIF>::Is> adapter;
|
||||
return adapter.deSerialize(object, buffer, size, bigEndian);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class SerializeAdapter {
|
||||
public:
|
||||
static ReturnValue_t serialize(const T* object, uint8_t** buffer,
|
||||
size_t* size, const size_t max_size, bool bigEndian) {
|
||||
SerializeAdapter_<T, IsDerivedFrom<T, SerializeIF>::Is> adapter;
|
||||
return adapter.serialize(object, buffer, size, max_size, bigEndian);
|
||||
template<typename T>
|
||||
static ReturnValue_t serialize(const T *object, uint8_t **buffer,
|
||||
size_t *size, size_t maxSize, SerializeIF::Endianness streamEndianness) {
|
||||
InternalSerializeAdapter<T, IsDerivedFrom<T, SerializeIF>::Is> adapter;
|
||||
return adapter.serialize(object, buffer, size, maxSize,
|
||||
streamEndianness);
|
||||
}
|
||||
static uint32_t getSerializedSize(const T* object) {
|
||||
SerializeAdapter_<T, IsDerivedFrom<T, SerializeIF>::Is> adapter;
|
||||
template<typename T>
|
||||
static uint32_t getSerializedSize(const T *object) {
|
||||
InternalSerializeAdapter<T, IsDerivedFrom<T, SerializeIF>::Is> adapter;
|
||||
return adapter.getSerializedSize(object);
|
||||
}
|
||||
|
||||
static ReturnValue_t deSerialize(T* object, const uint8_t** buffer,
|
||||
size_t* size, bool bigEndian) {
|
||||
SerializeAdapter_<T, IsDerivedFrom<T, SerializeIF>::Is> adapter;
|
||||
return adapter.deSerialize(object, buffer, size, bigEndian);
|
||||
template<typename T>
|
||||
static ReturnValue_t deSerialize(T *object, const uint8_t **buffer,
|
||||
size_t *size, SerializeIF::Endianness streamEndianness) {
|
||||
InternalSerializeAdapter<T, IsDerivedFrom<T, SerializeIF>::Is> adapter;
|
||||
return adapter.deSerialize(object, buffer, size, streamEndianness);
|
||||
}
|
||||
private:
|
||||
template<typename T, int>
|
||||
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 ignoredSize = 0;
|
||||
if (size == NULL) {
|
||||
size = &ignoredSize;
|
||||
}
|
||||
//TODO check integer overflow of *size
|
||||
if (sizeof(T) + *size <= max_size) {
|
||||
T tmp;
|
||||
switch (streamEndianness) {
|
||||
case SerializeIF::Endianness::BIG:
|
||||
tmp = EndianConverter::convertBigEndian<T>(*object);
|
||||
break;
|
||||
case SerializeIF::Endianness::LITTLE:
|
||||
tmp = EndianConverter::convertLittleEndian<T>(*object);
|
||||
break;
|
||||
default:
|
||||
case SerializeIF::Endianness::MACHINE:
|
||||
tmp = *object;
|
||||
break;
|
||||
}
|
||||
memcpy(*buffer, &tmp, sizeof(T));
|
||||
*size += sizeof(T);
|
||||
(*buffer) += sizeof(T);
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
} else {
|
||||
return SerializeIF::BUFFER_TOO_SHORT;
|
||||
}
|
||||
}
|
||||
|
||||
ReturnValue_t deSerialize(T *object, const uint8_t **buffer,
|
||||
size_t *size, SerializeIF::Endianness streamEndianness) {
|
||||
T tmp;
|
||||
if (*size >= sizeof(T)) {
|
||||
*size -= sizeof(T);
|
||||
memcpy(&tmp, *buffer, sizeof(T));
|
||||
switch (streamEndianness) {
|
||||
case SerializeIF::Endianness::BIG:
|
||||
*object = EndianConverter::convertBigEndian<T>(tmp);
|
||||
break;
|
||||
case SerializeIF::Endianness::LITTLE:
|
||||
*object = EndianConverter::convertLittleEndian<T>(tmp);
|
||||
break;
|
||||
default:
|
||||
case SerializeIF::Endianness::MACHINE:
|
||||
*object = tmp;
|
||||
break;
|
||||
}
|
||||
|
||||
*buffer += sizeof(T);
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
} else {
|
||||
return SerializeIF::STREAM_TOO_SHORT;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t getSerializedSize(const T *object) {
|
||||
return sizeof(T);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class InternalSerializeAdapter<T, 1> {
|
||||
public:
|
||||
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) {
|
||||
size = &ignoredSize;
|
||||
}
|
||||
return object->serialize(buffer, size, max_size, streamEndianness);
|
||||
}
|
||||
uint32_t getSerializedSize(const T *object) const {
|
||||
return object->getSerializedSize();
|
||||
}
|
||||
|
||||
ReturnValue_t deSerialize(T *object, const uint8_t **buffer,
|
||||
size_t *size, SerializeIF::Endianness streamEndianness) {
|
||||
return object->deSerialize(buffer, size, streamEndianness);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
#endif /* SERIALIZEADAPTER_H_ */
|
||||
|
@ -17,49 +17,44 @@
|
||||
* @ingroup serialize
|
||||
*/
|
||||
template<typename T>
|
||||
class SerializeElement : public SerializeIF, public LinkedElement<SerializeIF> {
|
||||
class SerializeElement: public SerializeIF, public LinkedElement<SerializeIF> {
|
||||
public:
|
||||
/**
|
||||
* Arguments are forwarded to the element datatype constructor
|
||||
* @param args
|
||||
*/
|
||||
template<typename... Args>
|
||||
SerializeElement(Args... args):
|
||||
LinkedElement<SerializeIF>(this),
|
||||
entry(std::forward<Args>(args)...) {}
|
||||
|
||||
SerializeElement() : LinkedElement<SerializeIF>(this) {}
|
||||
template<typename ... Args>
|
||||
SerializeElement(Args ... args) :
|
||||
LinkedElement<SerializeIF>(this), entry(std::forward<Args>(args)...) {
|
||||
|
||||
}
|
||||
SerializeElement() :
|
||||
LinkedElement<SerializeIF>(this) {
|
||||
}
|
||||
T entry;
|
||||
|
||||
virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size,
|
||||
const size_t max_size, bool bigEndian) const override {
|
||||
return SerializeAdapter<T>::serialize(&entry, buffer, size,
|
||||
max_size, bigEndian);
|
||||
ReturnValue_t serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
||||
Endianness streamEndianness) const override {
|
||||
return SerializeAdapter::serialize(&entry, buffer, size, maxSize,
|
||||
streamEndianness);
|
||||
}
|
||||
|
||||
size_t getSerializedSize() const {
|
||||
return SerializeAdapter<T>::getSerializedSize(&entry);
|
||||
size_t getSerializedSize() const override {
|
||||
return SerializeAdapter::getSerializedSize(&entry);
|
||||
}
|
||||
|
||||
virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
|
||||
bool bigEndian) override {
|
||||
return SerializeAdapter<T>::deSerialize(&entry, buffer, size, bigEndian);
|
||||
virtual ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size,
|
||||
Endianness streamEndianness) override {
|
||||
return SerializeAdapter::deSerialize(&entry, buffer, size,
|
||||
streamEndianness);
|
||||
}
|
||||
|
||||
operator T() {
|
||||
return entry;
|
||||
}
|
||||
|
||||
SerializeElement<T> &operator=(T newValue) {
|
||||
SerializeElement<T>& operator=(T newValue) {
|
||||
entry = newValue;
|
||||
return *this;
|
||||
}
|
||||
T *operator->() {
|
||||
T* operator->() {
|
||||
return &entry;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif /* SERIALIZEELEMENT_H_ */
|
||||
|
@ -33,6 +33,10 @@
|
||||
*/
|
||||
class SerializeIF {
|
||||
public:
|
||||
enum class Endianness : uint8_t {
|
||||
BIG, LITTLE, MACHINE
|
||||
};
|
||||
|
||||
static const uint8_t INTERFACE_ID = CLASS_ID::SERIALIZE_IF;
|
||||
static const ReturnValue_t BUFFER_TOO_SHORT = MAKE_RETURN_CODE(1);
|
||||
static const ReturnValue_t STREAM_TOO_SHORT = MAKE_RETURN_CODE(2);
|
||||
@ -41,13 +45,13 @@ public:
|
||||
virtual ~SerializeIF() {
|
||||
}
|
||||
|
||||
virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size,
|
||||
const size_t max_size, bool bigEndian) const = 0;
|
||||
virtual ReturnValue_t serialize(uint8_t **buffer, size_t *size,
|
||||
size_t maxSize, Endianness streamEndianness) const = 0;
|
||||
|
||||
virtual size_t getSerializedSize() const = 0;
|
||||
|
||||
virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
|
||||
bool bigEndian) = 0;
|
||||
virtual ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size,
|
||||
Endianness streamEndianness) = 0;
|
||||
|
||||
};
|
||||
|
||||
|
Reference in New Issue
Block a user