File indexing completed on 2024-06-02 06:03:07

0001 /*
0002     This file is part of the Okteta Kasten module, made within the KDE community.
0003 
0004     SPDX-FileCopyrightText: 2010 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 #ifndef KASTEN_BYTEARRAYIHEXSTREAMENCODER_HPP
0010 #define KASTEN_BYTEARRAYIHEXSTREAMENCODER_HPP
0011 
0012 // lib
0013 #include "abstractbytearraystreamencoder.hpp"
0014 // Okteta core
0015 #include <Okteta/OktetaCore>
0016 // Qt
0017 #include <QString>
0018 // Std
0019 #include <array>
0020 
0021 class KConfigGroup;
0022 
0023 class QTextStream;
0024 
0025 namespace Kasten {
0026 
0027 class IHexStreamEncoderSettings
0028 {
0029 public:
0030     enum class AddressSizeId
0031     {
0032         Bits32 = 0,
0033         Bits16 = 1,
0034         Bits8 = 2,
0035         _Count,
0036     };
0037 
0038     static inline constexpr int AddressSizeCount = static_cast<int>(AddressSizeId::_Count);
0039     static const std::array<QString, AddressSizeCount> addressSizeConfigValueList;
0040 
0041 private:
0042     static inline constexpr char AddressSizeConfigKey[] = "AddressSize";
0043 
0044     static inline constexpr AddressSizeId DefaultAddressSize = AddressSizeId::Bits32;
0045 
0046 public:
0047     IHexStreamEncoderSettings();
0048     IHexStreamEncoderSettings(const IHexStreamEncoderSettings&) = default;
0049 
0050     ~IHexStreamEncoderSettings() = default;
0051 
0052     IHexStreamEncoderSettings& operator=(const IHexStreamEncoderSettings&) = default;
0053 
0054     bool operator==(const IHexStreamEncoderSettings& other) const;
0055 
0056 public:
0057     void loadConfig(const KConfigGroup& configGroup);
0058     void saveConfig(KConfigGroup& configGroup) const;
0059 
0060 public:
0061     AddressSizeId addressSizeId = AddressSizeId::Bits32;
0062 };
0063 
0064 class ByteArrayIHexStreamEncoder : public AbstractByteArrayStreamEncoder
0065 {
0066     Q_OBJECT
0067 
0068 private:
0069     static inline constexpr char ConfigGroupId[] = "ByteArrayIntelHexStreamEncoder";
0070 
0071     static inline constexpr unsigned char dataRecordCode = 0x0;
0072     static inline constexpr unsigned char endOfFileRecordCode = 0x1;
0073     static inline constexpr unsigned char extendedSegmentAddressRecordCode = 0x2;
0074     static inline constexpr unsigned char startSegmentAddressRecordCode = 0x3;
0075     static inline constexpr unsigned char extendedLinearAddressRecordCode = 0x4;
0076     static inline constexpr unsigned char startLinearAddressRecordCode = 0x5;
0077 
0078     static inline constexpr char startCode = ':';
0079 
0080     static inline constexpr int byteCountLineOffset = 0;
0081     static inline constexpr int byteCountLineSize = 1;
0082     static inline constexpr int addressLineOffset = byteCountLineOffset + byteCountLineSize;
0083     static inline constexpr int addressLineSize = 2;
0084     static inline constexpr int recordTypeLineOffset = addressLineOffset + addressLineSize;
0085     static inline constexpr int recordTypeLineSize = 1;
0086     static inline constexpr int dataLineOffset = recordTypeLineOffset + recordTypeLineSize;
0087     static const char hexDigits[16];
0088 
0089 private:
0090     static char hexValueOfNibble(int nibble);
0091     static void writeBigEndian(unsigned char* line, quint32 value, int byteSize);
0092 
0093     static void streamLine(QTextStream& textStream, const unsigned char* line);
0094     static void streamExtendedSegmentAddress(QTextStream& textStream, unsigned char* line,
0095                                              quint16 upperSegmentBaseAddress);
0096     static void streamExtendedLinearAddress(QTextStream& textStream, unsigned char* line,
0097                                             quint16 upperLinearBaseAddress);
0098     static void streamEndOfFile(QTextStream& textStream, unsigned char* line,
0099                                 quint16 startAddress = 0);
0100 
0101 public:
0102     ByteArrayIHexStreamEncoder();
0103     ~ByteArrayIHexStreamEncoder() override;
0104 
0105 public:
0106     IHexStreamEncoderSettings settings() const;
0107     void setSettings(const IHexStreamEncoderSettings& settings);
0108 
0109 protected: // AbstractByteArrayStreamEncoder API
0110     bool encodeDataToStream(QIODevice* device,
0111                             const ByteArrayView* byteArrayView,
0112                             const Okteta::AbstractByteArrayModel* byteArrayModel,
0113                             const Okteta::AddressRange& range) override;
0114 
0115 private:
0116     IHexStreamEncoderSettings mSettings;
0117 };
0118 
0119 inline IHexStreamEncoderSettings ByteArrayIHexStreamEncoder::settings() const { return mSettings; }
0120 
0121 inline char ByteArrayIHexStreamEncoder::hexValueOfNibble(int nibble)
0122 { return hexDigits[nibble & 0xF]; }
0123 
0124 inline void ByteArrayIHexStreamEncoder::writeBigEndian(unsigned char* line, quint32 value, int byteSize)
0125 {
0126     while (byteSize > 0) {
0127         --byteSize;
0128         line[byteSize] = value;
0129         value >>= 8;
0130     }
0131 }
0132 
0133 }
0134 
0135 #endif