File indexing completed on 2024-07-07 05:34:58

0001 /*
0002     This file is part of the Okteta Kasten Framework, made within the KDE community.
0003 
0004     SPDX-FileCopyrightText: 2010 Alex Richardson <alex.richardson@gmx.de>
0005 
0006     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0007 */
0008 
0009 #include "abstractbitfielddatainformation.hpp"
0010 
0011 #include <KLocalizedString>
0012 
0013 #include "../../topleveldatainformation.hpp"
0014 
0015 #include "../../../script/classes/bitfieldscriptclass.hpp"
0016 #include "../../../script/scripthandlerinfo.hpp"
0017 
0018 AbstractBitfieldDataInformation::AbstractBitfieldDataInformation(const QString& name, BitCount32 width,
0019                                                                  DataInformation* parent)
0020     : PrimitiveDataInformation(name, parent)
0021     , mWidth(qMin(width, 64U))
0022 {
0023     Q_ASSERT(width <= 64);
0024 }
0025 
0026 AbstractBitfieldDataInformation::AbstractBitfieldDataInformation(const AbstractBitfieldDataInformation& d) = default;
0027 
0028 AbstractBitfieldDataInformation::~AbstractBitfieldDataInformation() = default;
0029 
0030 QString AbstractBitfieldDataInformation::sizeString() const
0031 {
0032     return i18np("%1 bit", "%1 bits", width());
0033 }
0034 
0035 AllPrimitiveTypes AbstractBitfieldDataInformation::value() const
0036 {
0037     return mValue;
0038 }
0039 
0040 void AbstractBitfieldDataInformation::setValue(AllPrimitiveTypes newVal)
0041 {
0042     Q_ASSERT((newVal.value<quint64>() & mask()) == newVal.value<quint64>());
0043     mValue = newVal.value<quint64>() & mask();
0044 }
0045 
0046 PrimitiveDataType AbstractBitfieldDataInformation::type() const
0047 {
0048     return PrimitiveDataType::Bitfield;
0049 }
0050 
0051 qint64 AbstractBitfieldDataInformation::readData(const Okteta::AbstractByteArrayModel* input,
0052                                                  Okteta::Address address, BitCount64 bitsRemaining, quint8* bitOffset)
0053 {
0054     Q_ASSERT(mHasBeenUpdated); // update must have been called prior to reading
0055     if (bitsRemaining < BitCount64(width())) {
0056         mWasAbleToRead = false;
0057         mValue = 0;
0058         return -1;
0059     }
0060     AllPrimitiveTypes oldVal(mValue);
0061     AllPrimitiveTypes newVal(mValue);
0062 
0063     mWasAbleToRead = newVal.readBits(size(), input, effectiveByteOrder(), address, bitsRemaining,
0064                                      bitOffset);
0065 
0066     if (oldVal != newVal || mWasAbleToReadBefore != mWasAbleToRead) {
0067         topLevelDataInformation()->setChildDataChanged();
0068         mValue = newVal;
0069     }
0070     return width();
0071 }
0072 
0073 bool AbstractBitfieldDataInformation::setData(const QVariant& valueVariant,
0074                                               Okteta::AbstractByteArrayModel* out, Okteta::Address address, BitCount64 bitsRemaining,
0075                                               quint8 bitOffset)
0076 {
0077     AllPrimitiveTypes oldVal(mValue);
0078     bool ok;
0079     AllPrimitiveTypes valToWrite = valueVariant.toULongLong(&ok);
0080     Q_ASSERT(ok);
0081     if (!ok) {
0082         return false;
0083     }
0084     AllPrimitiveTypes newVal(oldVal);
0085     // this handles remaining < size() for us
0086     bool wasAbleToWrite = newVal.writeBits(width(), valToWrite, out, effectiveByteOrder(), address,
0087                                            bitsRemaining, &bitOffset);
0088     return wasAbleToWrite;
0089 }
0090 
0091 AllPrimitiveTypes AbstractBitfieldDataInformation::fromVariant(const QVariant& variant, bool* ok) const
0092 {
0093     return AllPrimitiveTypes(variant.toULongLong(ok));
0094 }
0095 
0096 QScriptClass* AbstractBitfieldDataInformation::scriptClass(ScriptHandlerInfo* handlerInfo) const
0097 {
0098     return handlerInfo->mBitfieldClass.get();
0099 }
0100 
0101 BitCount32 AbstractBitfieldDataInformation::size() const
0102 {
0103     return mWidth;
0104 }
0105 
0106 bool AbstractBitfieldDataInformation::isBitfield() const
0107 {
0108     return true;
0109 }
0110 
0111 Qt::ItemFlags AbstractBitfieldDataInformation::flags(int column, bool fileLoaded) const
0112 {
0113     if (column == (int) DataInformation::ColumnValue && fileLoaded) {
0114         return Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable;
0115     }
0116 
0117     return Qt::ItemIsSelectable | Qt::ItemIsEnabled;
0118 }