x-tools/Source/Assistants/CRC/Source/xToolsCRCAssistant.cpp
2024-03-20 16:59:03 +08:00

219 lines
8.1 KiB
C++

/***************************************************************************************************
* Copyright 2018-2024 x-tools-author(x-tools@outlook.com). All rights reserved.
*
* The file is encoded using "utf8 with bom", it is a part of xTools project.
*
* xTools is licensed according to the terms in the file LICENCE(GPL V3) in the root of the source
* code directory.
**************************************************************************************************/
#include "xToolsCRCAssistant.h"
#include "ui_xToolsCRCAssistant.h"
#include <QComboBox>
#include <QDesktopServices>
#include <QLoggingCategory>
#include <QMetaEnum>
#include "xToolsCrcInterface.h"
xToolsCRCAssistant::xToolsCRCAssistant(QWidget* parent)
: QWidget(parent)
, m_crcInterface(new xToolsCrcInterface)
, ui(new Ui::xToolsCRCAssistant)
{
ui->setupUi(this);
m_widthComboBox = ui->comboBoxWidth;
m_widthComboBox->addItem(QString::number(8));
m_widthComboBox->addItem(QString::number(16));
m_widthComboBox->addItem(QString::number(32));
m_widthComboBox->setEnabled(false);
m_parameterComboBox = ui->comboBoxName;
m_parameterComboBox->clear();
m_refinCheckBox = ui->checkBoxRefIn;
m_refoutCheckBox = ui->checkBoxRefOut;
m_polyLineEdit = ui->lineEditPoly;
m_initLineEdit = ui->lineEditInit;
m_xorLineEdit = ui->lineEditXOROUT;
m_refinCheckBox->setEnabled(false);
m_refoutCheckBox->setEnabled(false);
m_polyLineEdit->setReadOnly(true);
m_initLineEdit->setReadOnly(true);
m_xorLineEdit->setReadOnly(true);
m_hexRadioBt = ui->radioButtonHex;
m_asciiRadioBt = ui->radioButtonASCII;
m_hexCRCOutput = ui->lineEditOutputHex;
m_binCRCOutput = ui->lineEditOutputBin;
m_hexCRCOutput->setReadOnly(true);
m_binCRCOutput->setReadOnly(true);
m_inputTextEdit = ui->textEdit;
m_calculatedBt = ui->pushButtonCalculate;
m_labelPolyFormula = ui->labelPolyFormula;
m_labelInfo = ui->labelInfo;
m_labelInfo->installEventFilter(this);
m_labelInfo->setCursor(QCursor(Qt::PointingHandCursor));
initParameterModel();
connect(m_parameterComboBox,
QOverload<int>::of(&QComboBox::currentIndexChanged),
this,
&xToolsCRCAssistant::changedParameterModel);
connect(m_calculatedBt, &QPushButton::clicked, this, &xToolsCRCAssistant::calculate);
connect(m_inputTextEdit, &QTextEdit::textChanged, this, &xToolsCRCAssistant::textFormatControl);
}
xToolsCRCAssistant::~xToolsCRCAssistant()
{
delete m_crcInterface;
delete ui;
}
void xToolsCRCAssistant::initParameterModel()
{
m_parameterComboBox->clear();
QStringList list = m_crcInterface->supportedParameterModels();
m_parameterComboBox->addItems(list);
QMetaEnum models = QMetaEnum::fromType<xToolsCrcInterface::SAKEnumCrcAlgorithm>();
bool ok = false;
int ret = models.keyToValue(m_parameterComboBox->currentText().toLatin1().constData(), &ok);
xToolsCrcInterface::SAKEnumCrcAlgorithm model = xToolsCrcInterface::CRC_8;
if (ok) {
model = static_cast<xToolsCrcInterface::SAKEnumCrcAlgorithm>(ret);
}
int bitsWidth = m_crcInterface->bitsWidth(model);
m_widthComboBox->setCurrentIndex(m_widthComboBox->findText(QString::number(bitsWidth)));
m_labelPolyFormula->setText(m_crcInterface->friendlyPoly(model));
}
void xToolsCRCAssistant::calculate()
{
QByteArray inputArray;
if (m_hexRadioBt->isChecked()) {
QString str = m_inputTextEdit->toPlainText();
QStringList strList = str.split(' ');
char ch;
for (int i = 0; i < strList.length(); i++) {
if (strList.at(i).isEmpty()) {
continue;
}
ch = static_cast<char>(strList.at(i).toInt(Q_NULLPTR, 16));
inputArray.append(ch);
}
} else {
inputArray = m_inputTextEdit->toPlainText().toLatin1();
}
if (inputArray.isEmpty()) {
return;
}
int bitsWidth = m_widthComboBox->currentText().toInt();
QMetaEnum models = QMetaEnum::fromType<xToolsCrcInterface::SAKEnumCrcAlgorithm>();
bool ok = false;
int ret = models.keyToValue(m_parameterComboBox->currentText().toLatin1().constData(), &ok);
xToolsCrcInterface::SAKEnumCrcAlgorithm model = xToolsCrcInterface::CRC_8;
if (ok) {
model = static_cast<xToolsCrcInterface::SAKEnumCrcAlgorithm>(ret);
} else {
Q_ASSERT_X(false, __FUNCTION__, "Unknown crc parameters model!");
}
QString crcHexString = "error";
QString crcBinString = "error";
uint8_t* inputData = reinterpret_cast<uint8_t*>(inputArray.data());
uint64_t inputLength = static_cast<uint64_t>(inputArray.length());
if (bitsWidth == 8) {
uint8_t crc = m_crcInterface->crcCalculate<uint8_t>(inputData, inputLength, model);
crcHexString = QString("0x%1").arg(QString::number(crc, 16), 2, '0');
crcBinString = QString("%1").arg(QString::number(crc, 2), 8, '0');
} else if (bitsWidth == 16) {
uint16_t crc = m_crcInterface->crcCalculate<uint16_t>(inputData, inputLength, model);
crcHexString = QString("0x%1").arg(QString::number(crc, 16), 4, '0');
crcBinString = QString("%1").arg(QString::number(crc, 2), 16, '0');
} else if (bitsWidth == 32) {
uint32_t crc = m_crcInterface->crcCalculate<uint32_t>(inputData, inputLength, model);
crcHexString = QString("0x%1").arg(QString::number(crc, 16), 8, '0');
crcBinString = QString("%1").arg(QString::number(crc, 2), 32, '0');
} else {
qWarning() << "Not supported bits width!";
}
m_hexCRCOutput->setText(crcHexString);
m_binCRCOutput->setText(crcBinString);
}
void xToolsCRCAssistant::textFormatControl()
{
if (m_asciiRadioBt->isChecked()) {
return;
}
disconnect(m_inputTextEdit, &QTextEdit::textChanged, this, &xToolsCRCAssistant::textFormatControl);
QString strTemp;
QString plaintext = m_inputTextEdit->toPlainText();
static QRegularExpression reg("[^0-9a-fA-F]");
plaintext.remove(reg);
for (int i = 0; i < plaintext.length(); i++) {
if ((i != 0) && (i % 2 == 0)) {
strTemp.append(QChar(' '));
}
strTemp.append(plaintext.at(i));
}
m_inputTextEdit->setText(strTemp.toUpper());
m_inputTextEdit->moveCursor(QTextCursor::End);
connect(m_inputTextEdit, &QTextEdit::textChanged, this, &xToolsCRCAssistant::textFormatControl);
}
void xToolsCRCAssistant::changedParameterModel(int index)
{
Q_UNUSED(index)
QMetaEnum models = QMetaEnum::fromType<xToolsCrcInterface::SAKEnumCrcAlgorithm>();
bool ok = false;
xToolsCrcInterface::SAKEnumCrcAlgorithm model = xToolsCrcInterface::CRC_8;
int ret = models.keyToValue(m_parameterComboBox->currentText().toLatin1().constData(), &ok);
if (ok) {
model = static_cast<xToolsCrcInterface::SAKEnumCrcAlgorithm>(ret);
} else {
qWarning() << "Unknown parameter model!";
Q_ASSERT_X(false, __FUNCTION__, "Unknown parameter model!");
return;
}
int bitsWidth = m_crcInterface->bitsWidth(model);
m_widthComboBox->setCurrentIndex(m_widthComboBox->findText(QString::number(bitsWidth)));
QString strTmp = QString::number(static_cast<int>(m_crcInterface->poly(model)), 16);
m_polyLineEdit->setText(QString("0x%1").arg(strTmp, bitsWidth / 4, '0'));
strTmp = QString::number(static_cast<int>(m_crcInterface->initialValue(model)), 16);
m_initLineEdit->setText(QString("0x%1").arg(strTmp, bitsWidth / 4, '0'));
strTmp = QString::number(static_cast<int>(m_crcInterface->xorValue(model)), 16);
m_xorLineEdit->setText(QString("0x%1").arg(strTmp, bitsWidth / 4, '0'));
m_refinCheckBox->setChecked(m_crcInterface->isInputReversal(model));
m_refoutCheckBox->setChecked(m_crcInterface->isOutputReversal(model));
m_labelPolyFormula->setText(m_crcInterface->friendlyPoly(model));
}
bool xToolsCRCAssistant::eventFilter(QObject* watched, QEvent* event)
{
if (event->type() == QEvent::MouseButtonDblClick) {
if (watched == m_labelInfo) {
QDesktopServices::openUrl(QUrl(QString("http://www.ip33.com/crc.html")));
return true;
}
}
return QWidget::eventFilter(watched, event);
}