diff --git a/TranslateUI/ParseUntility.cpp b/TranslateUI/ParseUntility.cpp new file mode 100644 index 0000000..1591db7 --- /dev/null +++ b/TranslateUI/ParseUntility.cpp @@ -0,0 +1,9 @@ +#include "ParseUntility.h" + +ParseUntility::ParseUntility(QWidget* p /*= nullptr*/) + : QMainWindow(p), + _solution_table(new QTableView(this)), + _solution_model(new QStandardItemModel(this)) +{ + _solution_table->setModel(_solution_model); +} diff --git a/TranslateUI/ParseUntility.h b/TranslateUI/ParseUntility.h new file mode 100644 index 0000000..df2fb44 --- /dev/null +++ b/TranslateUI/ParseUntility.h @@ -0,0 +1,18 @@ +#pragma once +#include +#include +#include +#include + + +class ParseUntility : public QMainWindow +{ +private: + QTableView *const _solution_table; + QStandardItemModel *const _solution_model; + +public: + ParseUntility(QWidget *p = nullptr); + +}; + diff --git a/TranslateUI/ReadMe.md b/TranslateUI/ReadMe.md new file mode 100644 index 0000000..e2fd19c --- /dev/null +++ b/TranslateUI/ReadMe.md @@ -0,0 +1 @@ +# 设计思路 diff --git a/TranslateUI/TranslateBasic.cpp b/TranslateUI/TranslateBasic.cpp new file mode 100644 index 0000000..5868f11 --- /dev/null +++ b/TranslateUI/TranslateBasic.cpp @@ -0,0 +1,206 @@ +#include "TranslateBasic.h" + +AbstractTranslateUnit::AbstractTranslateUnit(const QString& name) + :_name_store(name), _byte_offset(0), _byte_count(0) { +} + +bool AbstractTranslateUnit::setOffsetFromPrevious(int bytes) +{ + this->_byte_offset = bytes; + return true; +} + +bool AbstractTranslateUnit::setCountWithinParse(int bytes) +{ + this->_byte_count = bytes; + return true; +} + +QString AbstractTranslateUnit::name() const +{ + return _name_store; +} + +int AbstractTranslateUnit::offsetFromPrevious() const +{ + return _byte_offset; +} + +int AbstractTranslateUnit::countWithinParse() const +{ + return _byte_count; +} + +void AbstractTranslateUnit::loadFrom(const QJsonObject& obj) +{ + INT32_PEAK(_byte_offset); + INT32_PEAK(_byte_count); +} + +void AbstractTranslateUnit::saveTo(QJsonObject& obj) const +{ + INT32_SAVE(_byte_count); + INT32_SAVE(_byte_offset); +} + +BytesAsHex::BytesAsHex() + : AbstractTranslateUnit(NAME(BytesAsHex)) { +} + +QVariant BytesAsHex::parse(const QByteArray& bytes) const +{ + QString result; + for (auto char_v : bytes) { + result += QString("%1").arg(char_v, 2, 16, QChar('0')); + } + return result + "H"; +} + +std::shared_ptr BytesAsHex::newDefault() const +{ + return std::make_shared(); +} + +BytesAsBitCombine::BytesAsBitCombine() + : AbstractTranslateUnit(NAME(BytesAsBitCombine)) +{ + +} + +bool BytesAsBitCombine::setSwitchOption(int bit_index, const QString& keyword) +{ + if (bit_index >= 0 && bit_index <= this->countWithinParse() * 8) { + _switch_options[bit_index] = keyword; + return true; + } + return false; +} + +QHash BytesAsBitCombine::switchOptions() const +{ + return _switch_options; +} + +void BytesAsBitCombine::clearOptions() +{ + _switch_options.clear(); +} + +QVariant BytesAsBitCombine::parse(const QByteArray& bytes) const +{ + auto keys = _switch_options.keys(); + std::sort(keys.begin(), keys.end()); + + QString result; + for (auto idx : keys) { + auto byte_idx = idx / 8; + auto bit_idx = idx % 8; + auto char_v = bytes.at(byte_idx); + if (char_v & (0x1u << bit_idx)) + result += QString("%1<%2>;").arg(_switch_options[idx], "Y"); + else + result += QString("%1<%2>;").arg(_switch_options[idx], "N"); + } + return result; +} + +void BytesAsBitCombine::loadFrom(const QJsonObject& obj) +{ + AbstractTranslateUnit::loadFrom(obj); + + QStringList value_list; + STRLIST_PEAK(value_list); + _switch_options.clear(); + for (auto pair : value_list) { + auto items = pair.split("="); + _switch_options[items.first().toInt()] = items.last(); + } +} + +void BytesAsBitCombine::saveTo(QJsonObject& obj) const +{ + AbstractTranslateUnit::saveTo(obj); + + QStringList value_list; + for (auto key : _switch_options.keys()) { + auto pair = QString("%1=%2").arg(key).arg(_switch_options[key]); + } + STRLIST_SAVE(value_list); +} + +std::shared_ptr BytesAsBitCombine::newDefault() const +{ + return std::make_shared(); +} + +void BytesAsInteger::loadFrom(const QJsonObject& obj) +{ + AbstractTranslateUnit::loadFrom(obj); + INT32_PEAK(unsigned_mark); +} + +void BytesAsInteger::saveTo(QJsonObject& obj) const +{ + AbstractTranslateUnit::saveTo(obj); + INT32_SAVE(unsigned_mark); +} + +std::shared_ptr BytesAsInteger::newDefault() const +{ + return std::make_shared(); +} + +BytesAsInteger::BytesAsInteger() + :AbstractTranslateUnit(NAME(BytesAsInteger)) { + setCountWithinParse(8); +} + +void BytesAsInteger::setUnsignedMark(bool ste) +{ + this->unsigned_mark = ste; +} + +bool BytesAsInteger::unsignedMark() const +{ + return unsigned_mark; +} + +bool BytesAsInteger::setCountWithinParse(int bytes) +{ + if (bytes >= 0 && bytes <= 8) + return AbstractTranslateUnit::setCountWithinParse(bytes); + return false; +} + +QVariant BytesAsInteger::parse(const QByteArray& bytes) const +{ + if (unsigned_mark) { + unsigned long long value = 0; + for (auto vidx = bytes.size() - 1; vidx >= 0; vidx--) { + auto vchar = bytes.at(vidx); + value = value << 8; + value += (uchar)vchar; + } + return value; + } + else { + auto last = bytes[bytes.size() - 1]; + auto mark = last == 0? 0: last / std::abs(last); + + auto xbuffer = bytes; + if (mark >= 0) { + xbuffer.append(8 - bytes.size(), 0); + } + else { + xbuffer.append(8 - bytes.size(), 0xff); + } + + unsigned long long value = 0; + for (auto vidx = xbuffer.size() - 1; vidx >= 0; vidx--) { + auto vchar = xbuffer.at(vidx); + value = value << 8; + value += (uchar)vchar; + } + return *((long long*)(&value)); + } +} diff --git a/TranslateUI/TranslateBasic.h b/TranslateUI/TranslateBasic.h new file mode 100644 index 0000000..9375a40 --- /dev/null +++ b/TranslateUI/TranslateBasic.h @@ -0,0 +1,155 @@ +#pragma once +#include +#include +#include + +/// +/// 序列化实体 +/// +class Serializable { +public: + virtual ~Serializable() = default; + /// + /// 反序列化 + /// + /// + virtual void loadFrom(const QJsonObject &obj) = 0; + /// + /// 序列化 + /// + /// + virtual void saveTo(QJsonObject &obj) const = 0; + /// + /// 创建默认副本 + /// + /// + virtual std::shared_ptr newDefault() const = 0; +}; + +/// +/// 翻译单元抽象接口 +/// +class TranslateUnit : public Serializable { +public: + virtual ~TranslateUnit() = default; + + /// + /// 单元名称 + /// + /// + virtual QString name() const = 0; + + /// + /// 从上一个单元字节偏移字节数量 + /// + /// + virtual int offsetFromPrevious() const = 0; + /// + /// 解析所用的字节数量 + /// + /// + virtual int countWithinParse() const = 0; + + /// + /// 执行解析过程 + /// + /// + /// + virtual QVariant parse(const QByteArray &bytes) const = 0; +}; + +class AbstractTranslateUnit : public TranslateUnit { +private: + QString _name_store; + int _byte_offset, _byte_count; + +public: + AbstractTranslateUnit(const QString &name); + /// + /// 设置偏移字节数量 + /// + /// + virtual bool setOffsetFromPrevious(int bytes); + /// + /// 设置解析字节数量 + /// + /// + virtual bool setCountWithinParse(int bytes); + + // TranslateUnit =========================== + QString name() const override; + int offsetFromPrevious() const override; + int countWithinParse() const override; + + // Serializable ============================== + void loadFrom(const QJsonObject& obj) override; + void saveTo(QJsonObject& obj) const override; +}; + +#define NAME(u) #u +#define INT32_SAVE(varx) obj[NAME(varx)] = varx; +#define INT32_PEAK(varx) varx = obj[NAME(varx)].toInt(); +#define STRLIST_SAVE(list) obj[NAME(list)] = list.join(";"); +#define STRLIST_PEAK(list) list = obj[NAME(list)].toString().split(";"); + +/// +/// 转换源数值未16进制数值,默认分割方式 +/// +class BytesAsHex : public AbstractTranslateUnit { +public: + BytesAsHex(); + + QVariant parse(const QByteArray& bytes) const override; + std::shared_ptr newDefault() const override; +}; + +#include +/// +/// 转换源数值为位联合 +/// +class BytesAsBitCombine : public AbstractTranslateUnit { +private: + QHash _switch_options; + +public: + BytesAsBitCombine(); + + bool setSwitchOption(int bit_index, const QString& keyword); + QHash switchOptions() const; + virtual void clearOptions(); + + // TranslateUnit ============================ + QVariant parse(const QByteArray& bytes) const override; + + // Serializable ============================== + void loadFrom(const QJsonObject& obj) override; + void saveTo(QJsonObject& obj) const override; + std::shared_ptr newDefault() const override; +}; + + +class BytesAsInteger : public AbstractTranslateUnit { +private: + bool unsigned_mark = false; + +public: + BytesAsInteger(); + + void setUnsignedMark(bool ste); + bool unsignedMark() const; + + // TranslateUnit ============================ + bool setCountWithinParse(int bytes) override; + QVariant parse(const QByteArray& bytes) const override; + + // Serializable ============================== + void loadFrom(const QJsonObject& obj) override; + void saveTo(QJsonObject& obj) const override; + std::shared_ptr newDefault() const override; + +}; + +class BytesAsString : public AbstractTranslateUnit { +private: + QTextCodec *_conv_with; +}; \ No newline at end of file diff --git a/TranslateUI/TranslateUI.vcxproj b/TranslateUI/TranslateUI.vcxproj index 164b604..7027612 100644 --- a/TranslateUI/TranslateUI.vcxproj +++ b/TranslateUI/TranslateUI.vcxproj @@ -92,15 +92,22 @@ + + + + + + + diff --git a/TranslateUI/TranslateUI.vcxproj.filters b/TranslateUI/TranslateUI.vcxproj.filters index a25d0b0..79ee0a5 100644 --- a/TranslateUI/TranslateUI.vcxproj.filters +++ b/TranslateUI/TranslateUI.vcxproj.filters @@ -43,10 +43,25 @@ Source Files + + Source Files + + + Source Files + Header Files + + Header Files + + + Header Files + + + + \ No newline at end of file diff --git a/TranslateUI/main.cpp b/TranslateUI/main.cpp index 355938e..17db6a5 100644 --- a/TranslateUI/main.cpp +++ b/TranslateUI/main.cpp @@ -1,13 +1,19 @@ #include "TranslateUI.h" #include #include "StructView.h" +#include +#include "TranslateBasic.h" int main(int argc, char *argv[]) { QApplication app(argc, argv); - BinaryStructView vb; - vb.show(); + QByteArray vbuf; + uint value = 122; + vbuf.append((char*)&value, 4); + BytesAsInteger u; + u.setUnsignedMark(true); + qDebug() << u.parse(vbuf); return app.exec(); }