mirror of
https://github.com/nasa/fprime.git
synced 2025-12-10 16:29:04 -06:00
97 lines
2.6 KiB
C++
97 lines
2.6 KiB
C++
// ======================================================================
|
|
// \title CFDP/Checksum/Checksum.cpp
|
|
// \author bocchino
|
|
// \brief cpp file for CFDP checksum class
|
|
//
|
|
// \copyright
|
|
// Copyright 2009-2016, by the California Institute of Technology.
|
|
// ALL RIGHTS RESERVED. United States Government Sponsorship
|
|
// acknowledged.
|
|
//
|
|
// ======================================================================
|
|
|
|
#include "CFDP/Checksum/Checksum.hpp"
|
|
#include "Fw/Types/Assert.hpp"
|
|
|
|
static U32 min(const U32 a, const U32 b) {
|
|
return (a < b) ? a : b;
|
|
}
|
|
|
|
namespace CFDP {
|
|
|
|
Checksum ::Checksum() : m_value(0) {}
|
|
|
|
Checksum ::Checksum(const U32 value) : m_value(value) {}
|
|
|
|
Checksum ::Checksum(const Checksum& original) {
|
|
this->m_value = original.getValue();
|
|
}
|
|
|
|
Checksum ::~Checksum() {}
|
|
|
|
Checksum& Checksum ::operator=(const Checksum& checksum) {
|
|
this->m_value = checksum.m_value;
|
|
return *this;
|
|
}
|
|
|
|
bool Checksum ::operator==(const Checksum& checksum) const {
|
|
return this->m_value == checksum.m_value;
|
|
}
|
|
|
|
bool Checksum ::operator!=(const Checksum& checksum) const {
|
|
return not(*this == checksum);
|
|
}
|
|
|
|
U32 Checksum ::getValue() const {
|
|
return this->m_value;
|
|
}
|
|
|
|
void Checksum ::update(const U8* const data, const U32 offset, const U32 length) {
|
|
U32 index = 0;
|
|
|
|
// Add the first word unaligned if necessary
|
|
const U32 offsetMod4 = offset % 4;
|
|
if (offsetMod4 != 0) {
|
|
const U8 wordLength = static_cast<U8>(min(length, 4 - offsetMod4));
|
|
this->addWordUnaligned(&data[index], static_cast<U8>(offset + index), wordLength);
|
|
index += wordLength;
|
|
}
|
|
|
|
// Add the middle words aligned
|
|
for (; index + 4 <= length; index += 4) {
|
|
addWordAligned(&data[index]);
|
|
}
|
|
|
|
// Add the last word unaligned if necessary
|
|
if (index < length) {
|
|
const U8 wordLength = static_cast<U8>(length - index);
|
|
this->addWordUnaligned(&data[index], static_cast<U8>(offset + index), wordLength);
|
|
}
|
|
}
|
|
|
|
void Checksum ::addWordAligned(const U8* const word) {
|
|
for (U8 i = 0; i < 4; ++i) {
|
|
addByteAtOffset(word[i], i);
|
|
}
|
|
}
|
|
|
|
void Checksum ::addWordUnaligned(const U8* word, const U8 position, const U8 length) {
|
|
FW_ASSERT(length < 4);
|
|
U8 offset = position % 4;
|
|
for (U8 i = 0; i < length; ++i) {
|
|
addByteAtOffset(word[i], offset);
|
|
++offset;
|
|
if (offset == 4) {
|
|
offset = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
void Checksum ::addByteAtOffset(const U8 byte, const U8 offset) {
|
|
FW_ASSERT(offset < 4);
|
|
const U32 addend = static_cast<U32>(byte) << (8 * (3 - offset));
|
|
this->m_value += addend;
|
|
}
|
|
|
|
} // namespace CFDP
|