File indexing completed on 2025-01-19 05:20:18

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 "bytearraypatterngenerator.hpp"
0010 
0011 // KF
0012 #include <KConfigGroup>
0013 #include <KSharedConfig>
0014 #include <KLocalizedString>
0015 // Qt
0016 #include <QMimeData>
0017 #include <QByteArray>
0018 // Std
0019 #include <algorithm>
0020 #include <array>
0021 #include <iterator>
0022 
0023 // TODO: deduplicate with kasten/controllers/libconfigentries/
0024 static constexpr int codingCount =
0025     static_cast<int>(Kasten::ByteArrayPatternGeneratorSettings::_CodingCount);
0026 static const std::array<QString, codingCount> codingConfigValueList = {
0027     QStringLiteral("Hexadecimal"),
0028     QStringLiteral("Decimal"),
0029     QStringLiteral("Octal"),
0030     QStringLiteral("Binary"),
0031     QStringLiteral("Char"),
0032     QStringLiteral("UTF-8"),
0033 };
0034 
0035 
0036 template <>
0037 inline Kasten::ByteArrayPatternGeneratorSettings::Coding
0038 KConfigGroup::readEntry(const char *key,
0039                         const Kasten::ByteArrayPatternGeneratorSettings::Coding &defaultValue) const
0040 {
0041     const QString entry = readEntry(key, QString());
0042 
0043     auto it = std::find(codingConfigValueList.cbegin(), codingConfigValueList.cend(), entry);
0044     if (it == codingConfigValueList.cend()) {
0045         return defaultValue;
0046     }
0047 
0048     const int listIndex = std::distance(codingConfigValueList.cbegin(), it);
0049     return static_cast<Kasten::ByteArrayPatternGeneratorSettings::Coding>(listIndex);
0050 }
0051 
0052 template <>
0053 inline void KConfigGroup::writeEntry(const char *key,
0054                                      const Kasten::ByteArrayPatternGeneratorSettings::Coding &value,
0055                                      KConfigBase::WriteConfigFlags flags)
0056 {
0057     QString configValue;
0058     if (value == Kasten::ByteArrayPatternGeneratorSettings::InvalidCoding) {
0059         configValue = QStringLiteral("Invalid");
0060     } else {
0061         const int listIndex = static_cast<int>(value);
0062         configValue = codingConfigValueList[listIndex];
0063     }
0064     writeEntry(key, configValue, flags);
0065 }
0066 
0067 namespace Kasten {
0068 
0069 const QByteArray ByteArrayPatternGeneratorSettings::DefaultPattern = QByteArray(1, 0);
0070 
0071 
0072 ByteArrayPatternGeneratorSettings::ByteArrayPatternGeneratorSettings() = default;
0073 
0074 bool ByteArrayPatternGeneratorSettings::operator==(const ByteArrayPatternGeneratorSettings& other) const
0075 {
0076     return (pattern == other.pattern) && (patternCoding == other.patternCoding) && (count == other.count);
0077 }
0078 
0079 void ByteArrayPatternGeneratorSettings::loadConfig(const KConfigGroup& configGroup)
0080 {
0081     pattern = configGroup.readEntry(PatternConfigKey, DefaultPattern);
0082     count = configGroup.readEntry(CountConfigKey, DefaultCount);
0083     patternCoding = configGroup.readEntry(PatternCodingConfigKey, DefaultPatternCoding);
0084 }
0085 
0086 void ByteArrayPatternGeneratorSettings::saveConfig(KConfigGroup& configGroup) const
0087 {
0088     configGroup.writeEntry(PatternConfigKey, pattern);
0089     configGroup.writeEntry(PatternCodingConfigKey, patternCoding);
0090     configGroup.writeEntry(CountConfigKey, count);
0091 }
0092 
0093 // TODO: support insert to selection, cmp. fill in painting program
0094 // there are two kinds of generated datam fixed size (e.g. sequence) and endless size?
0095 // perhaps by option fill selection? or a separate menu entry fill, which only works on selections?
0096 
0097 ByteArrayPatternGenerator::ByteArrayPatternGenerator()
0098     : AbstractModelDataGenerator(
0099         i18nc("name of the generated data", "Pattern..."),
0100         QStringLiteral("application/octet-stream"),
0101         DynamicGeneration)
0102 {
0103     const KConfigGroup configGroup(KSharedConfig::openConfig(), ConfigGroupId);
0104 
0105     mSettings.loadConfig(configGroup);
0106 }
0107 
0108 ByteArrayPatternGenerator::~ByteArrayPatternGenerator() = default;
0109 
0110 void ByteArrayPatternGenerator::setSettings(const ByteArrayPatternGeneratorSettings& settings)
0111 {
0112     if (mSettings == settings) {
0113         return;
0114     }
0115 
0116     mSettings = settings;
0117 
0118     KConfigGroup configGroup(KSharedConfig::openConfig(), ConfigGroupId);
0119     mSettings.saveConfig(configGroup);
0120 //     Q_EMIT settingsChanged();
0121 }
0122 
0123 // TODO: optimize and check if pattern is just one byte, so memset can be used
0124 // TODO: see if copying larger chunks with memcpy is faster, so
0125 QMimeData* ByteArrayPatternGenerator::generateData()
0126 {
0127     const int patternSize = mSettings.pattern.size();
0128 
0129     const int insertDataSize = mSettings.count * patternSize;
0130 
0131     QByteArray insertData(insertDataSize, '\0');
0132 
0133     char* rawInsertData = insertData.data();
0134     const char* rawPatternData = mSettings.pattern.constData();
0135 
0136     for (int i = 0; i < insertDataSize; i += patternSize) {
0137         memcpy(&rawInsertData[i], rawPatternData, patternSize);
0138     }
0139 
0140     auto* mimeData = new QMimeData;
0141     mimeData->setData(mimeType(), insertData);
0142 
0143 // TODO: a method to get the description of the change, e.g.
0144 #if 0
0145     Okteta::ChangesDescribable* changesDescribable =
0146         qobject_cast<Okteta::ChangesDescribable*>(mByteArrayModel);
0147 
0148     if (changesDescribable) {
0149         changesDescribable->openGroupedChange(i18n("Pattern inserted."));
0150     }
0151     mByteArrayView->insert(insertData);
0152 //     mByteArrayModel->replace( filteredSection, filterResult );
0153     if (changesDescribable) {
0154         changesDescribable->closeGroupedChange();
0155     }
0156 #endif
0157 
0158     return mimeData;
0159 }
0160 
0161 }
0162 
0163 #include "moc_bytearraypatterngenerator.cpp"