fprime/Fw/Types/Serializable.cpp
2019-02-27 10:56:36 -08:00

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;
}
}