mirror of
https://github.com/nasa/fprime.git
synced 2025-12-10 16:29:04 -06:00
758 lines
26 KiB
C++
758 lines
26 KiB
C++
#include <Fw/Types/Serializable.hpp>
|
|
#include <string.h> // memcpy
|
|
#include <Fw/Types/Assert.hpp>
|
|
#include <Fw/Types/StringType.hpp>
|
|
#include <stdio.h>
|
|
|
|
#ifdef BUILD_UT
|
|
#include <iomanip>
|
|
#include <Fw/Types/EightyCharString.hpp>
|
|
#endif
|
|
|
|
// Some macros/functions to optimize for architectures
|
|
|
|
namespace Fw {
|
|
|
|
Serializable::Serializable() {
|
|
}
|
|
|
|
Serializable::~Serializable() {
|
|
}
|
|
|
|
#if FW_SERIALIZABLE_TO_STRING || BUILD_UT
|
|
|
|
void Serializable::toString(StringBase& text) const {
|
|
text = "NOSPEC"; // set to not specified.
|
|
}
|
|
|
|
#endif
|
|
|
|
#ifdef BUILD_UT
|
|
std::ostream& operator<<(std::ostream& os, const Serializable& val) {
|
|
Fw::EightyCharString out;
|
|
val.toString(out);
|
|
|
|
os << out;
|
|
|
|
return os;
|
|
}
|
|
#endif
|
|
|
|
SerializeBufferBase::SerializeBufferBase() :
|
|
m_serLoc(0), m_deserLoc(0) {
|
|
}
|
|
|
|
SerializeBufferBase::~SerializeBufferBase() {
|
|
}
|
|
|
|
void SerializeBufferBase::copyFrom(const SerializeBufferBase& src) {
|
|
this->m_serLoc = src.m_serLoc;
|
|
this->m_deserLoc = src.m_deserLoc;
|
|
FW_ASSERT(src.getBuffAddr());
|
|
FW_ASSERT(this->getBuffAddr());
|
|
// destination has to be same or bigger
|
|
FW_ASSERT(src.getBuffLength() <= this->getBuffCapacity(),src.getBuffLength(),this->getBuffLength());
|
|
(void) memcpy(this->getBuffAddr(),src.getBuffAddr(),this->m_serLoc+1);
|
|
}
|
|
|
|
SerializeBufferBase::SerializeBufferBase(const SerializeBufferBase &src) {
|
|
this->copyFrom(src);
|
|
}
|
|
|
|
const SerializeBufferBase& SerializeBufferBase::operator=(const SerializeBufferBase &src) {
|
|
this->copyFrom(src);
|
|
return src;
|
|
}
|
|
|
|
// serialization routines
|
|
|
|
SerializeStatus SerializeBufferBase::serialize(U8 val) {
|
|
if (this->m_serLoc + (NATIVE_UINT_TYPE) sizeof(val) - 1 >= this->getBuffCapacity()) {
|
|
return FW_SERIALIZE_NO_ROOM_LEFT;
|
|
}
|
|
FW_ASSERT(this->getBuffAddr());
|
|
this->getBuffAddr()[this->m_serLoc] = val;
|
|
this->m_serLoc += sizeof(val);
|
|
this->m_deserLoc = 0;
|
|
|
|
return FW_SERIALIZE_OK;
|
|
}
|
|
|
|
SerializeStatus SerializeBufferBase::serialize(I8 val) {
|
|
if (this->m_serLoc + (NATIVE_UINT_TYPE) sizeof(val) - 1 >= this->getBuffCapacity()) {
|
|
return FW_SERIALIZE_NO_ROOM_LEFT;
|
|
}
|
|
FW_ASSERT(this->getBuffAddr());
|
|
this->getBuffAddr()[this->m_serLoc + 0] = (U8) val;
|
|
this->m_serLoc += sizeof(val);
|
|
this->m_deserLoc = 0;
|
|
return FW_SERIALIZE_OK;
|
|
}
|
|
|
|
#if FW_HAS_16_BIT==1
|
|
SerializeStatus SerializeBufferBase::serialize(U16 val) {
|
|
if (this->m_serLoc + (NATIVE_UINT_TYPE) sizeof(val) - 1 >= this->getBuffCapacity()) {
|
|
return FW_SERIALIZE_NO_ROOM_LEFT;
|
|
}
|
|
FW_ASSERT(this->getBuffAddr());
|
|
// MSB first
|
|
this->getBuffAddr()[this->m_serLoc + 0] = (U8) ((val & 0xFF00) >> 8);
|
|
this->getBuffAddr()[this->m_serLoc + 1] = (U8) ((val & 0x00FF) >> 0);
|
|
this->m_serLoc += sizeof(val);
|
|
this->m_deserLoc = 0;
|
|
return FW_SERIALIZE_OK;
|
|
}
|
|
|
|
SerializeStatus SerializeBufferBase::serialize(I16 val) {
|
|
if (this->m_serLoc + (NATIVE_UINT_TYPE) sizeof(val) - 1 >= this->getBuffCapacity()) {
|
|
return FW_SERIALIZE_NO_ROOM_LEFT;
|
|
}
|
|
FW_ASSERT(this->getBuffAddr());
|
|
// MSB first
|
|
this->getBuffAddr()[this->m_serLoc + 0] = (U8) ((val & 0xFF00) >> 8);
|
|
this->getBuffAddr()[this->m_serLoc + 1] = (U8) ((val & 0x00FF) >> 0);
|
|
this->m_serLoc += sizeof(val);
|
|
this->m_deserLoc = 0;
|
|
return FW_SERIALIZE_OK;
|
|
}
|
|
#endif
|
|
#if FW_HAS_32_BIT==1
|
|
SerializeStatus SerializeBufferBase::serialize(U32 val) {
|
|
if (this->m_serLoc + (NATIVE_UINT_TYPE) sizeof(val) - 1 >= this->getBuffCapacity()) {
|
|
return FW_SERIALIZE_NO_ROOM_LEFT;
|
|
}
|
|
FW_ASSERT(this->getBuffAddr());
|
|
// MSB first
|
|
this->getBuffAddr()[this->m_serLoc + 0] =
|
|
(U8) ((val & 0xFF000000) >> 24);
|
|
this->getBuffAddr()[this->m_serLoc + 1] =
|
|
(U8) ((val & 0x00FF0000) >> 16);
|
|
this->getBuffAddr()[this->m_serLoc + 2] =
|
|
(U8) ((val & 0x0000FF00) >> 8);
|
|
this->getBuffAddr()[this->m_serLoc + 3] =
|
|
(U8) ((val & 0x000000FF) >> 0);
|
|
this->m_serLoc += sizeof(val);
|
|
this->m_deserLoc = 0;
|
|
return FW_SERIALIZE_OK;
|
|
}
|
|
|
|
SerializeStatus SerializeBufferBase::serialize(I32 val) {
|
|
if (this->m_serLoc + (NATIVE_UINT_TYPE) sizeof(val) - 1 >= this->getBuffCapacity()) {
|
|
return FW_SERIALIZE_NO_ROOM_LEFT;
|
|
}
|
|
FW_ASSERT(this->getBuffAddr());
|
|
// MSB first
|
|
this->getBuffAddr()[this->m_serLoc + 0] =
|
|
(U8) ((val & 0xFF000000) >> 24);
|
|
this->getBuffAddr()[this->m_serLoc + 1] =
|
|
(U8) ((val & 0x00FF0000) >> 16);
|
|
this->getBuffAddr()[this->m_serLoc + 2] =
|
|
(U8) ((val & 0x0000FF00) >> 8);
|
|
this->getBuffAddr()[this->m_serLoc + 3] =
|
|
(U8) ((val & 0x000000FF) >> 0);
|
|
this->m_serLoc += sizeof(val);
|
|
this->m_deserLoc = 0;
|
|
return FW_SERIALIZE_OK;
|
|
}
|
|
#endif
|
|
|
|
#if FW_HAS_64_BIT==1
|
|
SerializeStatus SerializeBufferBase::serialize(U64 val) {
|
|
if (this->m_serLoc + (NATIVE_UINT_TYPE) sizeof(val) - 1 >= this->getBuffCapacity()) {
|
|
return FW_SERIALIZE_NO_ROOM_LEFT;
|
|
}
|
|
FW_ASSERT(this->getBuffAddr());
|
|
// MSB first
|
|
const U64 mask = 0xFF;
|
|
this->getBuffAddr()[this->m_serLoc + 0] = (U8) ((val & (mask << 56))
|
|
>> 56);
|
|
this->getBuffAddr()[this->m_serLoc + 1] = (U8) ((val & (mask << 48))
|
|
>> 48);
|
|
this->getBuffAddr()[this->m_serLoc + 2] = (U8) ((val & (mask << 40))
|
|
>> 40);
|
|
this->getBuffAddr()[this->m_serLoc + 3] = (U8) ((val & (mask << 32))
|
|
>> 32);
|
|
this->getBuffAddr()[this->m_serLoc + 4] = (U8) ((val & (mask << 24))
|
|
>> 24);
|
|
this->getBuffAddr()[this->m_serLoc + 5] = (U8) ((val & (mask << 16))
|
|
>> 16);
|
|
this->getBuffAddr()[this->m_serLoc + 6] = (U8) ((val & (mask << 8))
|
|
>> 8);
|
|
this->getBuffAddr()[this->m_serLoc + 7] = (U8) ((val & (mask << 0))
|
|
>> 0);
|
|
this->m_serLoc += sizeof(val);
|
|
this->m_deserLoc = 0;
|
|
return FW_SERIALIZE_OK;
|
|
}
|
|
|
|
SerializeStatus SerializeBufferBase::serialize(I64 val) {
|
|
if (this->m_serLoc + (NATIVE_UINT_TYPE) sizeof(val) - 1 >= this->getBuffCapacity()) {
|
|
return FW_SERIALIZE_NO_ROOM_LEFT;
|
|
}
|
|
FW_ASSERT(this->getBuffAddr());
|
|
// MSB first
|
|
const U64 mask = 0xFF;
|
|
this->getBuffAddr()[this->m_serLoc + 0] = (U8) ((val & (mask << 56))
|
|
>> 56);
|
|
this->getBuffAddr()[this->m_serLoc + 1] = (U8) ((val & (mask << 48))
|
|
>> 48);
|
|
this->getBuffAddr()[this->m_serLoc + 2] = (U8) ((val & (mask << 40))
|
|
>> 40);
|
|
this->getBuffAddr()[this->m_serLoc + 3] = (U8) ((val & (mask << 32))
|
|
>> 32);
|
|
this->getBuffAddr()[this->m_serLoc + 4] = (U8) ((val & (mask << 24))
|
|
>> 24);
|
|
this->getBuffAddr()[this->m_serLoc + 5] = (U8) ((val & (mask << 16))
|
|
>> 16);
|
|
this->getBuffAddr()[this->m_serLoc + 6] =
|
|
(U8) ((val & (mask << 8)) >> 8);
|
|
this->getBuffAddr()[this->m_serLoc + 7] =
|
|
(U8) ((val & (mask << 0)) >> 0);
|
|
this->m_serLoc += sizeof(val);
|
|
this->m_deserLoc = 0;
|
|
return FW_SERIALIZE_OK;
|
|
}
|
|
#endif
|
|
|
|
#if FW_HAS_F64
|
|
|
|
SerializeStatus SerializeBufferBase::serialize(F64 val) {
|
|
// floating point values need to be byte-swapped as well, so copy to U64 and use that routine
|
|
U64 u64Val;
|
|
(void) memcpy(&u64Val, &val, sizeof(val));
|
|
return this->serialize(u64Val);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
SerializeStatus SerializeBufferBase::serialize(F32 val) {
|
|
|
|
// floating point values need to be byte-swapped as well, so copy to U32 and use that routine
|
|
U32 u32Val;
|
|
(void) memcpy(&u32Val, &val, sizeof(val));
|
|
return this->serialize(u32Val);
|
|
|
|
}
|
|
|
|
SerializeStatus SerializeBufferBase::serialize(bool val) {
|
|
if (this->m_serLoc + (NATIVE_UINT_TYPE) sizeof(U8) - 1 >= this->getBuffCapacity()) {
|
|
return FW_SERIALIZE_NO_ROOM_LEFT;
|
|
}
|
|
|
|
FW_ASSERT(this->getBuffAddr());
|
|
if (val) {
|
|
this->getBuffAddr()[this->m_serLoc + 0] = FW_SERIALIZE_TRUE_VALUE;
|
|
} else {
|
|
this->getBuffAddr()[this->m_serLoc + 0] = FW_SERIALIZE_FALSE_VALUE;
|
|
}
|
|
|
|
this->m_serLoc += sizeof(U8);
|
|
this->m_deserLoc = 0;
|
|
return FW_SERIALIZE_OK;
|
|
}
|
|
|
|
SerializeStatus SerializeBufferBase::serialize(const void* val) {
|
|
if (this->m_serLoc + (NATIVE_UINT_TYPE) sizeof(void*) - 1
|
|
>= this->getBuffCapacity()) {
|
|
return FW_SERIALIZE_NO_ROOM_LEFT;
|
|
}
|
|
|
|
return this->serialize((POINTER_CAST) val);
|
|
|
|
}
|
|
|
|
SerializeStatus SerializeBufferBase::serialize(const U8* buff, NATIVE_UINT_TYPE length, bool noLength) {
|
|
// First serialize length
|
|
SerializeStatus stat;
|
|
if (not noLength) {
|
|
stat = this->serialize(static_cast<FwBuffSizeType>(length));
|
|
if (stat != FW_SERIALIZE_OK) {
|
|
return stat;
|
|
}
|
|
}
|
|
|
|
// make sure we have enough space
|
|
if (this->m_serLoc + length > this->getBuffCapacity()) {
|
|
return FW_SERIALIZE_NO_ROOM_LEFT;
|
|
}
|
|
|
|
// copy buffer to our buffer
|
|
(void) memcpy(&this->getBuffAddr()[this->m_serLoc], buff, length);
|
|
this->m_serLoc += length;
|
|
this->m_deserLoc = 0;
|
|
|
|
return FW_SERIALIZE_OK;
|
|
}
|
|
|
|
SerializeStatus SerializeBufferBase::serialize(const Serializable &val) {
|
|
return val.serialize(*this);
|
|
}
|
|
|
|
SerializeStatus SerializeBufferBase::serialize(
|
|
const SerializeBufferBase& val) {
|
|
NATIVE_UINT_TYPE size = val.getBuffLength();
|
|
if (this->m_serLoc + size + (NATIVE_UINT_TYPE) sizeof(FwBuffSizeType)
|
|
> this->getBuffCapacity()) {
|
|
return FW_SERIALIZE_NO_ROOM_LEFT;
|
|
}
|
|
|
|
// First, serialize size
|
|
SerializeStatus stat = this->serialize((FwBuffSizeType)size);
|
|
if (stat != FW_SERIALIZE_OK) {
|
|
return stat;
|
|
}
|
|
|
|
FW_ASSERT(this->getBuffAddr());
|
|
FW_ASSERT(val.getBuffAddr());
|
|
// serialize buffer
|
|
(void) memcpy(&this->getBuffAddr()[this->m_serLoc], val.getBuffAddr(), size);
|
|
this->m_serLoc += size;
|
|
this->m_deserLoc = 0;
|
|
|
|
return FW_SERIALIZE_OK;
|
|
}
|
|
|
|
// deserialization routines
|
|
|
|
SerializeStatus SerializeBufferBase::deserialize(U8 &val) {
|
|
// check for room
|
|
if (this->getBuffLength() == this->m_deserLoc) {
|
|
return FW_DESERIALIZE_BUFFER_EMPTY;
|
|
} else if (this->getBuffLength() - this->m_deserLoc < (NATIVE_UINT_TYPE)sizeof(val)) {
|
|
return FW_DESERIALIZE_SIZE_MISMATCH;
|
|
}
|
|
// read from current location
|
|
FW_ASSERT(this->getBuffAddr());
|
|
val = this->getBuffAddr()[this->m_deserLoc + 0];
|
|
this->m_deserLoc += sizeof(val);
|
|
return FW_SERIALIZE_OK;
|
|
}
|
|
|
|
SerializeStatus SerializeBufferBase::deserialize(I8 &val) {
|
|
// check for room
|
|
if (this->getBuffLength() == this->m_deserLoc) {
|
|
return FW_DESERIALIZE_BUFFER_EMPTY;
|
|
} else if (this->getBuffLength() - this->m_deserLoc < (NATIVE_UINT_TYPE)sizeof(val)) {
|
|
return FW_DESERIALIZE_SIZE_MISMATCH;
|
|
}
|
|
// read from current location
|
|
FW_ASSERT(this->getBuffAddr());
|
|
val = (I8) this->getBuffAddr()[this->m_deserLoc + 0];
|
|
this->m_deserLoc += sizeof(val);
|
|
return FW_SERIALIZE_OK;
|
|
}
|
|
|
|
#if FW_HAS_16_BIT==1
|
|
SerializeStatus SerializeBufferBase::deserialize(U16 &val) {
|
|
// check for room
|
|
if (this->getBuffLength() == this->m_deserLoc) {
|
|
return FW_DESERIALIZE_BUFFER_EMPTY;
|
|
} else if (this->getBuffLength() - this->m_deserLoc < (NATIVE_UINT_TYPE)sizeof(val)) {
|
|
return FW_DESERIALIZE_SIZE_MISMATCH;
|
|
}
|
|
// read from current location
|
|
FW_ASSERT(this->getBuffAddr());
|
|
// MSB first
|
|
val = ((U16) this->getBuffAddr()[this->m_deserLoc + 1] << 0)
|
|
| ((U16) this->getBuffAddr()[this->m_deserLoc + 0] << 8);
|
|
this->m_deserLoc += sizeof(val);
|
|
return FW_SERIALIZE_OK;
|
|
}
|
|
|
|
SerializeStatus SerializeBufferBase::deserialize(I16 &val) {
|
|
// check for room
|
|
if (this->getBuffLength() == this->m_deserLoc) {
|
|
return FW_DESERIALIZE_BUFFER_EMPTY;
|
|
} else if (this->getBuffLength() - this->m_deserLoc < (NATIVE_UINT_TYPE)sizeof(val)) {
|
|
return FW_DESERIALIZE_SIZE_MISMATCH;
|
|
}
|
|
// read from current location
|
|
FW_ASSERT(this->getBuffAddr());
|
|
// MSB first
|
|
val = ((I16) this->getBuffAddr()[this->m_deserLoc + 1] << 0)
|
|
| ((I16) this->getBuffAddr()[this->m_deserLoc + 0] << 8);
|
|
this->m_deserLoc += sizeof(val);
|
|
return FW_SERIALIZE_OK;
|
|
}
|
|
#endif
|
|
#if FW_HAS_32_BIT==1
|
|
SerializeStatus SerializeBufferBase::deserialize(U32 &val) {
|
|
// check for room
|
|
if (this->getBuffLength() == this->m_deserLoc) {
|
|
return FW_DESERIALIZE_BUFFER_EMPTY;
|
|
} else if (this->getBuffLength() - this->m_deserLoc < (NATIVE_UINT_TYPE)sizeof(val)) {
|
|
return FW_DESERIALIZE_SIZE_MISMATCH;
|
|
}
|
|
// read from current location
|
|
FW_ASSERT(this->getBuffAddr());
|
|
// MSB first
|
|
val = ((U32) this->getBuffAddr()[this->m_deserLoc + 3] << 0)
|
|
| ((U32) this->getBuffAddr()[this->m_deserLoc + 2] << 8)
|
|
| ((U32) this->getBuffAddr()[this->m_deserLoc + 1] << 16)
|
|
| ((U32) this->getBuffAddr()[this->m_deserLoc + 0] << 24);
|
|
this->m_deserLoc += sizeof(val);
|
|
return FW_SERIALIZE_OK;
|
|
}
|
|
|
|
SerializeStatus SerializeBufferBase::deserialize(I32 &val) {
|
|
// check for room
|
|
if (this->getBuffLength() == this->m_deserLoc) {
|
|
return FW_DESERIALIZE_BUFFER_EMPTY;
|
|
} else if (this->getBuffLength() - this->m_deserLoc < (NATIVE_UINT_TYPE)sizeof(val)) {
|
|
return FW_DESERIALIZE_SIZE_MISMATCH;
|
|
}
|
|
// read from current location
|
|
FW_ASSERT(this->getBuffAddr());
|
|
// MSB first
|
|
val = ((U32) this->getBuffAddr()[this->m_deserLoc + 3] << 0)
|
|
| ((U32) this->getBuffAddr()[this->m_deserLoc + 2] << 8)
|
|
| ((U32) this->getBuffAddr()[this->m_deserLoc + 1] << 16)
|
|
| ((U32) this->getBuffAddr()[this->m_deserLoc + 0] << 24);
|
|
this->m_deserLoc += sizeof(val);
|
|
return FW_SERIALIZE_OK;
|
|
}
|
|
#endif
|
|
|
|
#if FW_HAS_64_BIT==1
|
|
|
|
SerializeStatus SerializeBufferBase::deserialize(U64 &val) {
|
|
// check for room
|
|
if (this->getBuffLength() == this->m_deserLoc) {
|
|
return FW_DESERIALIZE_BUFFER_EMPTY;
|
|
} else if (this->getBuffLength() - this->m_deserLoc < (NATIVE_UINT_TYPE)sizeof(val)) {
|
|
return FW_DESERIALIZE_SIZE_MISMATCH;
|
|
}
|
|
// read from current location
|
|
FW_ASSERT(this->getBuffAddr());
|
|
// MSB first
|
|
val = ((U64) this->getBuffAddr()[this->m_deserLoc + 7] << 0)
|
|
| ((U64) this->getBuffAddr()[this->m_deserLoc + 6] << 8)
|
|
| ((U64) this->getBuffAddr()[this->m_deserLoc + 5] << 16)
|
|
| ((U64) this->getBuffAddr()[this->m_deserLoc + 4] << 24)
|
|
| ((U64) this->getBuffAddr()[this->m_deserLoc + 3] << 32)
|
|
| ((U64) this->getBuffAddr()[this->m_deserLoc + 2] << 40)
|
|
| ((U64) this->getBuffAddr()[this->m_deserLoc + 1] << 48)
|
|
| ((U64) this->getBuffAddr()[this->m_deserLoc + 0] << 56);
|
|
|
|
this->m_deserLoc += sizeof(val);
|
|
return FW_SERIALIZE_OK;
|
|
}
|
|
|
|
SerializeStatus SerializeBufferBase::deserialize(I64 &val) {
|
|
// check for room
|
|
if (this->getBuffLength() == this->m_deserLoc) {
|
|
return FW_DESERIALIZE_BUFFER_EMPTY;
|
|
} else if (this->getBuffLength() - this->m_deserLoc < (NATIVE_UINT_TYPE)sizeof(val)) {
|
|
return FW_DESERIALIZE_SIZE_MISMATCH;
|
|
}
|
|
// read from current location
|
|
FW_ASSERT(this->getBuffAddr());
|
|
// MSB first
|
|
val = ((I64) this->getBuffAddr()[this->m_deserLoc + 7] << 0)
|
|
| ((I64) this->getBuffAddr()[this->m_deserLoc + 6] << 8)
|
|
| ((I64) this->getBuffAddr()[this->m_deserLoc + 5] << 16)
|
|
| ((I64) this->getBuffAddr()[this->m_deserLoc + 4] << 24)
|
|
| ((I64) this->getBuffAddr()[this->m_deserLoc + 3] << 32)
|
|
| ((I64) this->getBuffAddr()[this->m_deserLoc + 2] << 40)
|
|
| ((I64) this->getBuffAddr()[this->m_deserLoc + 1] << 48)
|
|
| ((I64) this->getBuffAddr()[this->m_deserLoc + 0] << 56);
|
|
this->m_deserLoc += sizeof(val);
|
|
return FW_SERIALIZE_OK;
|
|
}
|
|
#endif
|
|
|
|
#if FW_HAS_F64
|
|
|
|
SerializeStatus SerializeBufferBase::deserialize(F64 &val) {
|
|
|
|
// deserialize as 64-bit int to handle endianness
|
|
U64 tempVal;
|
|
SerializeStatus stat = this->deserialize(tempVal);
|
|
if (stat != FW_SERIALIZE_OK) {
|
|
return stat;
|
|
}
|
|
// copy to argument
|
|
(void) memcpy(&val, &tempVal, (NATIVE_UINT_TYPE)sizeof(val));
|
|
|
|
return FW_SERIALIZE_OK;
|
|
}
|
|
|
|
#endif
|
|
|
|
SerializeStatus SerializeBufferBase::deserialize(bool &val) {
|
|
// check for room
|
|
if (this->getBuffLength() == this->m_deserLoc) {
|
|
return FW_DESERIALIZE_BUFFER_EMPTY;
|
|
} else if (this->getBuffLength() - this->m_deserLoc < (NATIVE_UINT_TYPE)sizeof(U8)) {
|
|
return FW_DESERIALIZE_SIZE_MISMATCH;
|
|
}
|
|
// read from current location
|
|
FW_ASSERT(this->getBuffAddr());
|
|
if (FW_SERIALIZE_TRUE_VALUE == this->getBuffAddr()[this->m_deserLoc + 0]) {
|
|
val = true;
|
|
} else if (FW_SERIALIZE_FALSE_VALUE == this->getBuffAddr()[this->m_deserLoc + 0]) {
|
|
val = false;
|
|
} else {
|
|
return FW_DESERIALIZE_FORMAT_ERROR;
|
|
}
|
|
|
|
this->m_deserLoc += sizeof(U8);
|
|
return FW_SERIALIZE_OK;
|
|
}
|
|
|
|
SerializeStatus SerializeBufferBase::deserialize(void*& val) {
|
|
return this->deserialize((POINTER_CAST&) val);
|
|
}
|
|
|
|
SerializeStatus SerializeBufferBase::deserialize(F32 &val) {
|
|
// deserialize as 64-bit int to handle endianness
|
|
U32 tempVal;
|
|
SerializeStatus stat = this->deserialize(tempVal);
|
|
if (stat != FW_SERIALIZE_OK) {
|
|
return stat;
|
|
}
|
|
(void) memcpy(&val, &tempVal, sizeof(val));
|
|
|
|
return FW_SERIALIZE_OK;
|
|
}
|
|
|
|
SerializeStatus SerializeBufferBase::deserialize(U8* buff, NATIVE_UINT_TYPE& length, bool noLength) {
|
|
|
|
FW_ASSERT(this->getBuffAddr());
|
|
|
|
if (not noLength) {
|
|
FwBuffSizeType storedLength;
|
|
|
|
SerializeStatus stat = this->deserialize(storedLength);
|
|
|
|
if (stat != FW_SERIALIZE_OK) {
|
|
return stat;
|
|
}
|
|
|
|
// make sure it fits
|
|
if ((storedLength > this->getBuffLeft()) or (storedLength > length)) {
|
|
return FW_DESERIALIZE_SIZE_MISMATCH;
|
|
}
|
|
|
|
(void) memcpy(buff, &this->getBuffAddr()[this->m_deserLoc], storedLength);
|
|
|
|
length = static_cast<NATIVE_UINT_TYPE>(storedLength);
|
|
|
|
} else {
|
|
// make sure enough is left
|
|
if (length > this->getBuffLeft()) {
|
|
return FW_DESERIALIZE_SIZE_MISMATCH;
|
|
}
|
|
|
|
(void) memcpy(buff, &this->getBuffAddr()[this->m_deserLoc], length);
|
|
}
|
|
|
|
this->m_deserLoc += length;
|
|
return FW_SERIALIZE_OK;
|
|
}
|
|
|
|
SerializeStatus SerializeBufferBase::deserialize(Serializable &val) {
|
|
return val.deserialize(*this);
|
|
}
|
|
|
|
SerializeStatus SerializeBufferBase::deserialize(SerializeBufferBase& val) {
|
|
|
|
FW_ASSERT(val.getBuffAddr());
|
|
SerializeStatus stat = FW_SERIALIZE_OK;
|
|
|
|
FwBuffSizeType storedLength;
|
|
|
|
stat = this->deserialize(storedLength);
|
|
|
|
if (stat != FW_SERIALIZE_OK) {
|
|
return stat;
|
|
}
|
|
|
|
// make sure destination has enough room
|
|
|
|
if ((storedLength > val.getBuffCapacity()) or (storedLength > this->getBuffLeft()) ) {
|
|
return FW_DESERIALIZE_SIZE_MISMATCH;
|
|
}
|
|
|
|
FW_ASSERT(this->getBuffAddr());
|
|
(void) memcpy(val.getBuffAddr(), &this->getBuffAddr()[this->m_deserLoc],
|
|
storedLength);
|
|
|
|
stat = val.setBuffLen(storedLength);
|
|
|
|
if (stat != FW_SERIALIZE_OK) {
|
|
return stat;
|
|
}
|
|
|
|
this->m_deserLoc += storedLength;
|
|
|
|
return FW_SERIALIZE_OK;
|
|
}
|
|
|
|
void SerializeBufferBase::resetSer(void) {
|
|
this->m_deserLoc = 0;
|
|
this->m_serLoc = 0;
|
|
}
|
|
|
|
void SerializeBufferBase::resetDeser(void) {
|
|
this->m_deserLoc = 0;
|
|
}
|
|
|
|
SerializeStatus SerializeBufferBase::deserializeSkip(NATIVE_UINT_TYPE numBytesToSkip)
|
|
{
|
|
// check for room
|
|
if (this->getBuffLength() == this->m_deserLoc) {
|
|
return FW_DESERIALIZE_BUFFER_EMPTY;
|
|
} else if (this->getBuffLength() - this->m_deserLoc < numBytesToSkip) {
|
|
return FW_DESERIALIZE_SIZE_MISMATCH;
|
|
}
|
|
// update location in buffer to skip the value
|
|
this->m_deserLoc += numBytesToSkip;
|
|
return FW_SERIALIZE_OK;
|
|
}
|
|
|
|
NATIVE_UINT_TYPE SerializeBufferBase::getBuffLength(void) const {
|
|
return this->m_serLoc;
|
|
}
|
|
|
|
SerializeStatus SerializeBufferBase::setBuff(const U8* src, NATIVE_UINT_TYPE length) {
|
|
if (this->getBuffCapacity() < length) {
|
|
return FW_SERIALIZE_NO_ROOM_LEFT;
|
|
} else {
|
|
FW_ASSERT(src);
|
|
FW_ASSERT(this->getBuffAddr());
|
|
memcpy(this->getBuffAddr(), src, length);
|
|
this->m_serLoc = length;
|
|
this->m_deserLoc = 0;
|
|
return FW_SERIALIZE_OK;
|
|
}
|
|
}
|
|
|
|
SerializeStatus SerializeBufferBase::setBuffLen(NATIVE_UINT_TYPE length) {
|
|
if (this->getBuffCapacity() < length) {
|
|
return FW_SERIALIZE_NO_ROOM_LEFT;
|
|
} else {
|
|
this->m_serLoc = length;
|
|
this->m_deserLoc = 0;
|
|
return FW_SERIALIZE_OK;
|
|
}
|
|
}
|
|
|
|
NATIVE_UINT_TYPE SerializeBufferBase::getBuffLeft(void) const {
|
|
return this->m_serLoc - this->m_deserLoc;
|
|
}
|
|
|
|
SerializeStatus SerializeBufferBase::copyRaw(SerializeBufferBase& dest, NATIVE_UINT_TYPE size) {
|
|
// make sure there is sufficient size in destination
|
|
if (dest.getBuffCapacity() < size) {
|
|
return FW_SERIALIZE_NO_ROOM_LEFT;
|
|
}
|
|
// otherwise, set destination buffer to data from deserialization pointer plus size
|
|
SerializeStatus stat = dest.setBuff(&this->getBuffAddr()[this->m_deserLoc],size);
|
|
if (FW_SERIALIZE_OK) {
|
|
this->m_deserLoc += size;
|
|
}
|
|
return stat;
|
|
|
|
}
|
|
|
|
SerializeStatus SerializeBufferBase::copyRawOffset(SerializeBufferBase& dest, NATIVE_UINT_TYPE size) {
|
|
// make sure there is sufficient size in destination
|
|
if (dest.getBuffCapacity() < size + dest.getBuffLength()) {
|
|
return FW_SERIALIZE_NO_ROOM_LEFT;
|
|
}
|
|
// make sure there is sufficient buffer in source
|
|
if (this->getBuffLeft() < size) {
|
|
return FW_DESERIALIZE_SIZE_MISMATCH;
|
|
}
|
|
|
|
// otherwise, serialize bytes to destination without writing length
|
|
SerializeStatus stat = dest.serialize(&this->getBuffAddr()[this->m_deserLoc], size, true);
|
|
if (stat == FW_SERIALIZE_OK) {
|
|
this->m_deserLoc += size;
|
|
}
|
|
return stat;
|
|
|
|
}
|
|
|
|
// return address of buffer not yet deserialized. This is used
|
|
// to copy the remainder of a buffer.
|
|
const U8* SerializeBufferBase::getBuffAddrLeft(void) const {
|
|
return &this->getBuffAddr()[this->m_deserLoc];
|
|
}
|
|
|
|
//!< gets address of end of serialization. Used to manually place data at the end
|
|
U8* SerializeBufferBase::getBuffAddrSer(void) {
|
|
return &this->getBuffAddr()[this->m_serLoc];
|
|
}
|
|
|
|
#ifdef BUILD_UT
|
|
bool SerializeBufferBase::operator==(const SerializeBufferBase& other) const {
|
|
if (this->getBuffLength() != other.getBuffLength()) {
|
|
return false;
|
|
}
|
|
|
|
const U8* us = this->getBuffAddr();
|
|
const U8* them = other.getBuffAddr();
|
|
|
|
FW_ASSERT(us);
|
|
FW_ASSERT(them);
|
|
|
|
for (NATIVE_UINT_TYPE byte = 0; byte < this->getBuffLength(); byte++) {
|
|
if (us[byte] != them[byte]) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
std::ostream& operator<<(std::ostream& os, const SerializeBufferBase& buff) {
|
|
|
|
const U8* us = buff.getBuffAddr();
|
|
|
|
FW_ASSERT(us);
|
|
|
|
for (NATIVE_UINT_TYPE byte = 0; byte < buff.getBuffLength(); byte++) {
|
|
os << "[" << std::setw(2) << std::hex << std::setfill('0') << (NATIVE_UINT_TYPE)us[byte] << "]" << std::dec;
|
|
}
|
|
|
|
return os;
|
|
}
|
|
#endif
|
|
|
|
ExternalSerializeBuffer::ExternalSerializeBuffer(U8* buffPtr, NATIVE_UINT_TYPE size) {
|
|
this->setExtBuffer(buffPtr,size);
|
|
}
|
|
|
|
ExternalSerializeBuffer::ExternalSerializeBuffer() {
|
|
this->clear();
|
|
}
|
|
|
|
void ExternalSerializeBuffer::setExtBuffer(U8* buffPtr, NATIVE_UINT_TYPE size) {
|
|
FW_ASSERT(buffPtr);
|
|
this->m_buff = buffPtr;
|
|
this->m_buffSize = size;
|
|
}
|
|
|
|
void ExternalSerializeBuffer::clear(void) {
|
|
this->m_buff = 0;
|
|
this->m_buffSize = 0;
|
|
}
|
|
|
|
NATIVE_UINT_TYPE ExternalSerializeBuffer::getBuffCapacity(void) const {
|
|
return this->m_buffSize;
|
|
}
|
|
|
|
U8* ExternalSerializeBuffer::getBuffAddr(void) {
|
|
return this->m_buff;
|
|
}
|
|
|
|
const U8* ExternalSerializeBuffer::getBuffAddr(void) const {
|
|
return this->m_buff;
|
|
}
|
|
|
|
}
|
|
|