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 "modsum32bytearraychecksumalgorithm.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 ModSum32ConfigGroupId[] = "ModularSum32"; 0020 0021 ModSum32ByteArrayChecksumAlgorithm::ModSum32ByteArrayChecksumAlgorithm() 0022 : AbstractByteArrayChecksumAlgorithm( 0023 i18nc("name of the checksum algorithm", "Modular sum 32-bit"), 0024 QStringLiteral("ModularSum32") 0025 ) 0026 {} 0027 0028 ModSum32ByteArrayChecksumAlgorithm::~ModSum32ByteArrayChecksumAlgorithm() = default; 0029 0030 AbstractByteArrayChecksumParameterSet* ModSum32ByteArrayChecksumAlgorithm::parameterSet() { return &mParameterSet; } 0031 0032 void ModSum32ByteArrayChecksumAlgorithm::loadConfig(const KConfigGroup& configGroup) 0033 { 0034 const KConfigGroup algorithmConfigGroup = configGroup.group(ModSum32ConfigGroupId); 0035 0036 mParameterSet.loadConfig(algorithmConfigGroup); 0037 } 0038 0039 void ModSum32ByteArrayChecksumAlgorithm::saveConfig(KConfigGroup& configGroup) const 0040 { 0041 KConfigGroup algorithmConfigGroup = configGroup.group(ModSum32ConfigGroupId); 0042 0043 mParameterSet.saveConfig(algorithmConfigGroup); 0044 } 0045 0046 bool ModSum32ByteArrayChecksumAlgorithm::calculateChecksum(QString* result, 0047 const Okteta::AbstractByteArrayModel* model, const Okteta::AddressRange& range) const 0048 { 0049 const bool useLittleEndian = (mParameterSet.endianness() == QSysInfo::LittleEndian); 0050 quint32 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, 8, 16, QChar::fromLatin1('0')); 0061 return true; 0062 } 0063 0064 quint32 ModSum32ByteArrayChecksumAlgorithm::calculateModSumWithBigEndian(const Okteta::AbstractByteArrayModel* model, const Okteta::AddressRange& range) const 0065 { 0066 quint32 modSum = 0x000000; 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 quint32 value = (quint32)(quint8)(model->byte(i)) << 24; 0072 ++i; 0073 if (i <= range.end()) { 0074 value |= (quint32)(quint8)(model->byte(i)) << 16; 0075 ++i; 0076 if (i <= range.end()) { 0077 value |= (quint32)(quint8)(model->byte(i)) << 8; 0078 ++i; 0079 if (i <= range.end()) { 0080 value |= (quint32)(quint8)(model->byte(i)); 0081 } 0082 } 0083 } 0084 0085 modSum += value; 0086 #if 0 0087 const uchar value = (crcBits & 0xFF) + model->byte(i); 0088 crcBits >>= 8; 0089 crcBits ^= lookupTable[value]; 0090 #endif 0091 if (i >= nextBlockEnd) { 0092 nextBlockEnd += CalculatedByteCountSignalLimit; 0093 Q_EMIT calculatedBytes(range.localIndex(i) + 1); 0094 } 0095 } 0096 0097 return modSum; 0098 } 0099 0100 quint32 ModSum32ByteArrayChecksumAlgorithm::calculateModSumWithLittleEndian(const Okteta::AbstractByteArrayModel* model, const Okteta::AddressRange& range) const 0101 { 0102 quint32 modSum = 0x000000; 0103 Okteta::Address nextBlockEnd = range.start() + CalculatedByteCountSignalLimit; 0104 0105 // TODO: move padding checks into extra code before and after loop 0106 for (Okteta::Address i = range.start(); i <= range.end(); ++i) { 0107 quint32 value = (quint32)(quint8)(model->byte(i)); 0108 ++i; 0109 if (i <= range.end()) { 0110 value |= (quint32)(quint8)(model->byte(i)) << 8; 0111 ++i; 0112 if (i <= range.end()) { 0113 value |= (quint32)(quint8)(model->byte(i)) << 16; 0114 ++i; 0115 if (i <= range.end()) { 0116 value |= (quint32)(quint8)(model->byte(i)) << 24; 0117 } 0118 } 0119 } 0120 0121 modSum += value; 0122 0123 if (i >= nextBlockEnd) { 0124 nextBlockEnd += CalculatedByteCountSignalLimit; 0125 Q_EMIT calculatedBytes(range.localIndex(i) + 1); 0126 } 0127 } 0128 0129 return modSum; 0130 } 0131 0132 #include "moc_modsum32bytearraychecksumalgorithm.cpp"