File indexing completed on 2024-06-23 05:48:48
0001 /* 0002 This file is part of the Okteta Kasten module, made within the KDE community. 0003 0004 SPDX-FileCopyrightText: 2009, 2022 Friedrich W. H. Kossebau <kossebau@kde.org> 0005 0006 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0007 */ 0008 0009 #include "modsum16bytearraychecksumalgorithm.hpp" 0010 0011 // Okteta core 0012 #include <Okteta/AbstractByteArrayModel> 0013 // KF 0014 #include <KConfigGroup> 0015 #include <KLocalizedString> 0016 // Qt 0017 #include <QtEndian> 0018 0019 static constexpr char ModSum16ConfigGroupId[] = "ModularSum16"; 0020 0021 ModSum16ByteArrayChecksumAlgorithm::ModSum16ByteArrayChecksumAlgorithm() 0022 : AbstractByteArrayChecksumAlgorithm( 0023 i18nc("name of the checksum algorithm", "Modular sum 16-bit"), 0024 QStringLiteral("ModularSum16") 0025 ) 0026 {} 0027 0028 ModSum16ByteArrayChecksumAlgorithm::~ModSum16ByteArrayChecksumAlgorithm() = default; 0029 0030 AbstractByteArrayChecksumParameterSet* ModSum16ByteArrayChecksumAlgorithm::parameterSet() { return &mParameterSet; } 0031 0032 void ModSum16ByteArrayChecksumAlgorithm::loadConfig(const KConfigGroup& configGroup) 0033 { 0034 const KConfigGroup algorithmConfigGroup = configGroup.group(ModSum16ConfigGroupId); 0035 0036 mParameterSet.loadConfig(algorithmConfigGroup); 0037 } 0038 0039 void ModSum16ByteArrayChecksumAlgorithm::saveConfig(KConfigGroup& configGroup) const 0040 { 0041 KConfigGroup algorithmConfigGroup = configGroup.group(ModSum16ConfigGroupId); 0042 0043 mParameterSet.saveConfig(algorithmConfigGroup); 0044 } 0045 0046 bool ModSum16ByteArrayChecksumAlgorithm::calculateChecksum(QString* result, 0047 const Okteta::AbstractByteArrayModel* model, const Okteta::AddressRange& range) const 0048 { 0049 const bool useLittleEndian = (mParameterSet.endianness() == QSysInfo::LittleEndian); 0050 quint16 modSum = useLittleEndian ? 0051 calculateModSumWithLittleEndian(model, range) : 0052 calculateModSumWithBigEndian(model, range); 0053 0054 modSum = ~modSum + 1; 0055 0056 if (useLittleEndian) { 0057 modSum = qbswap(modSum); 0058 } 0059 0060 *result = QStringLiteral("%1").arg(modSum, 4, 16, QChar::fromLatin1('0')); 0061 return true; 0062 } 0063 0064 quint16 ModSum16ByteArrayChecksumAlgorithm::calculateModSumWithBigEndian(const Okteta::AbstractByteArrayModel* model, const Okteta::AddressRange& range) const 0065 { 0066 quint16 modSum = 0x0000; 0067 Okteta::Address nextBlockEnd = range.start() + CalculatedByteCountSignalLimit; 0068 0069 // TODO: move padding checks into extra code before and after loop 0070 for (Okteta::Address i = range.start(); i <= range.end(); ++i) { 0071 quint16 value = (quint16)((quint8)(model->byte(i))) << 8; 0072 ++i; 0073 if (i <= range.end()) { 0074 value |= (quint16)((quint8)(model->byte(i))); 0075 } 0076 0077 modSum += value; 0078 #if 0 0079 const uchar value = (crcBits & 0xFF) + model->byte(i); 0080 crcBits >>= 8; 0081 crcBits ^= lookupTable[value]; 0082 #endif 0083 if (i >= nextBlockEnd) { 0084 nextBlockEnd += CalculatedByteCountSignalLimit; 0085 Q_EMIT calculatedBytes(range.localIndex(i) + 1); 0086 } 0087 } 0088 0089 return modSum; 0090 } 0091 0092 quint16 ModSum16ByteArrayChecksumAlgorithm::calculateModSumWithLittleEndian(const Okteta::AbstractByteArrayModel* model, const Okteta::AddressRange& range) const 0093 { 0094 quint16 modSum = 0x0000; 0095 Okteta::Address nextBlockEnd = range.start() + CalculatedByteCountSignalLimit; 0096 0097 // TODO: move padding checks into extra code before and after loop 0098 for (Okteta::Address i = range.start(); i <= range.end(); ++i) { 0099 quint16 value = (quint16)((quint8)(model->byte(i))); 0100 ++i; 0101 if (i <= range.end()) { 0102 value |= (quint16)((quint8)(model->byte(i))) << 8; 0103 } 0104 0105 modSum += value; 0106 0107 if (i >= nextBlockEnd) { 0108 nextBlockEnd += CalculatedByteCountSignalLimit; 0109 Q_EMIT calculatedBytes(range.localIndex(i) + 1); 0110 } 0111 } 0112 0113 return modSum; 0114 } 0115 0116 #include "moc_modsum16bytearraychecksumalgorithm.cpp"