// ====================================================================== // \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(min(length, 4 - offsetMod4)); this->addWordUnaligned( &data[index], static_cast(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(length - index); this->addWordUnaligned( &data[index], static_cast(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(byte) << (8*(3-offset)); this->m_value += addend; } }