fprime/CFDP/Checksum/Checksum.cpp
2025-09-10 15:02:07 -07:00

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