diff --git a/TranslateUI/TranslateBasic.cpp b/TranslateUI/TranslateBasic.cpp index 30f5761..4bcfbe2 100644 --- a/TranslateUI/TranslateBasic.cpp +++ b/TranslateUI/TranslateBasic.cpp @@ -31,6 +31,12 @@ TranslateBasic::TranslateBasic() u_ptr = std::make_shared(); _extractor_types[u_ptr->name()] = u_ptr; + u_ptr = std::make_shared(); + _extractor_types[u_ptr->name()] = u_ptr; + + u_ptr = std::make_shared(); + _extractor_types[u_ptr->name()] = u_ptr; + // size-provider type-list auto sz_ptr = std::make_shared(); this->_default_size_provider = sz_ptr; @@ -57,6 +63,21 @@ QHash> TranslateBasic::extractUnitList() c return _extractor_types; } +void TranslateBasic::setCustomRule(const QString& name, std::shared_ptr inst) +{ + this->_extractor_types[name] = inst; +} + +void TranslateBasic::removeCustomRule(const QString& name) +{ + _extractor_types.remove(name); +} + +QHash> TranslateBasic::customRules() const +{ + return this->_custom_rule_types; +} + QHash> TranslateBasic::sizeProviderList() const { return _size_provider_types; @@ -67,6 +88,11 @@ QHash> TranslateBasic::ruleMatchList() const return _rule_match_types; } +void ConstNumberProvider::bindInput(std::shared_ptr inst) +{ + +} + QString ConstNumberProvider::name() const { return NAME(ConstNumberProvider); @@ -101,3 +127,91 @@ std::shared_ptr ConstNumberProvider::newDefault() const { return std::make_shared(); } + +void InterpretedNumberPrivider::bindInput(std::shared_ptr inst) +{ + this->_refer._context_inst = inst; +} + +QString InterpretedNumberPrivider::name() const +{ + return NAME(InterpretedNumberPrivider); +} + +#include +int32_t InterpretedNumberPrivider::value(const QString& expr) const +{ + auto value = this->_refer._context_inst->get(expr); + if (value.userType() == QMetaType::Int) + return value.toInt(); + + return 0; +} + +void InterpretedNumberPrivider::setExpression(const QString& expr) +{ + this->_refer._field_refer = expr; +} + +QString InterpretedNumberPrivider::expression() const +{ + return this->_refer._field_refer; +} + +void InterpretedNumberPrivider::loadFrom(std::shared_ptr core, const QJsonObject& obj) +{ + STRING_PEAK(this->_refer._field_refer, obj); +} + +void InterpretedNumberPrivider::saveTo(QJsonObject& obj) const +{ + STRING_SAVE(this->_refer._field_refer, obj); +} + +std::shared_ptr InterpretedNumberPrivider::newDefault() const +{ + return std::make_shared(); +} + +void ValueAccess::init(const QString& field, std::shared_ptr parent) +{ + this->_cascade._current_field = field; + + if (parent) + parent->setChild(field, this->shared_from_this()); +} + +void ValueAccess::setChild(const QString& field, std::shared_ptr inst) +{ + this->_cascade._children_context[field] = inst; +} + +void ValueAccess::append(const QVariant& value) +{ + this->_cascade._current_value = value; +} + +QVariant ValueAccess::get(const QString& unique_key) const +{ + if (_cascade._current_field == unique_key) + return _cascade._current_value; + + for (auto unit : _cascade._children_context) + { + auto value = unit->get(unique_key); + if (value.isValid()) + return value; + } + return QVariant(); +} + +FieldSetterLayer::FieldSetterLayer(const QString& self, std::shared_ptr instp) +{ + _setter._rule_name = self; + _setter._parent_setter = instp; +} + +void FieldSetterLayer::setField(const QString& name, DataType type) +{ + _setter._parent_setter->setField(QString("%1.%2").arg(_setter._rule_name, name), type); +} diff --git a/TranslateUI/TranslateBasic.h b/TranslateUI/TranslateBasic.h index fd64761..0e7e072 100644 --- a/TranslateUI/TranslateBasic.h +++ b/TranslateUI/TranslateBasic.h @@ -2,22 +2,116 @@ #include "extract_basic.h" #include "convert_basic.h" - +#include /// -/// 翻译程序核心 +/// 范围字段获取上下文 +/// +class ScopeFieldsGetter { +public: + /// + /// 绑定当前字段 + /// + /// + /// + virtual bool bindCurrent(const QString& unique_key) = 0; + + /// + /// 获取本字段可用字段 + /// + /// + virtual QHash prevFields() const = 0; +}; + +/// +/// 范围字段设置上下文 +/// +class ScopeFieldsSetter { +public: + /// + /// 注册可用字段 + /// + /// + /// + virtual void setField(const QString& name, DataType type) = 0; +}; + +// ================================================================ +/// +/// 解释环境数据上下文 +/// +class DataAccessContext { +public: + /// + /// 设置本提取器解释数值 + /// + /// + virtual void append(const QVariant& value) = 0; + /// + /// 通过unique_key获取解释期数据 + /// + /// + /// + virtual QVariant get(const QString& unique_key) const = 0; + /// + /// 关联上下文 + /// + /// + /// + virtual void setChild(const QString& field, std::shared_ptr inst) = 0; +}; + +// ================================================================== +/// +/// 尺寸解析器 +/// +class SizeProvider : public Serializable { +public: + virtual void bindInput(std::shared_ptr inst) = 0; + + /// + /// 解析器名称 + /// + /// + virtual QString name() const = 0; + /// + /// 获取值,如果该值无法预先计算得知,返回-1 + /// + /// 尺寸值 + virtual int32_t value(const QString& expr) const = 0; + + virtual void setExpression(const QString& expr) = 0; + virtual QString expression() const = 0; +}; + +// ==================================================================== +/// +/// 规则匹配器 +/// +class RuleMatch : public Serializable { +public: + virtual QString name() const = 0; + virtual std::shared_ptr bindRule() const = 0; + virtual void bindRule(std::shared_ptr rule) = 0; + virtual bool checkpass(const QByteArray& buffer) const = 0; +}; + +/// +/// 翻译环境核心 /// class TranslateBasic { private: QHash> _extractor_types; std::shared_ptr _default_translate_rule = nullptr; - + QHash> _size_provider_types; std::shared_ptr _default_size_provider = nullptr; QHash> _rule_match_types; std::shared_ptr _default_rule_match = nullptr; + QHash> _custom_rule_types; + public: TranslateBasic(); @@ -28,17 +122,27 @@ public: std::shared_ptr defaultExtractUnit() const; QHash> extractUnitList() const; + + void setCustomRule(const QString &name, std::shared_ptr inst); + void removeCustomRule(const QString &name); + QHash> customRules() const; }; +/// +/// 常量数字提供 +/// class ConstNumberProvider : public SizeProvider { public: struct __Private { QString _value_string; } _number; + public: QString name() const override; + void bindInput(std::shared_ptr inst) override; + int32_t value(const QString& expr) const override; void setExpression(const QString& expr) override; QString expression() const override; @@ -48,3 +152,62 @@ public: std::shared_ptr newDefault() const override; }; + +/// +/// 解释期数字提供器 +/// +class InterpretedNumberPrivider : public SizeProvider { +public: + struct __Private { + QString _field_refer; + std::shared_ptr _context_inst; + } _refer; + + +public: + QString name() const override; + + void bindInput(std::shared_ptr inst) override; + + int32_t value(const QString& expr) const override; + void setExpression(const QString& expr) override; + QString expression() const override; + + void loadFrom(std::shared_ptr core, const QJsonObject& obj) override; + void saveTo(QJsonObject& obj) const override; + + std::shared_ptr newDefault() const override; +}; + +class ValueAccess : public DataAccessContext, + std::enable_shared_from_this { +public: + struct __Private { + QString _current_field = ""; + QVariant _current_value; + + QHash> _children_context; + } _cascade; + + + void init(const QString& field, std::shared_ptr parent); + void setChild(const QString& field, std::shared_ptr inst) override; + + void append(const QVariant& value) override; + +public: + QVariant get(const QString& unique_key) const override; +}; + +class FieldSetterLayer : public ScopeFieldsSetter { +public: + struct __Private { + QString _rule_name; + std::shared_ptr _parent_setter; + }_setter; + +public: + FieldSetterLayer(const QString &self, std::shared_ptr instp); + + void setField(const QString& name, DataType type) override; +}; \ No newline at end of file diff --git a/TranslateUI/extract_basic.cpp b/TranslateUI/extract_basic.cpp index fd276ad..87bb117 100644 --- a/TranslateUI/extract_basic.cpp +++ b/TranslateUI/extract_basic.cpp @@ -55,18 +55,24 @@ void AbstractExtractor::saveTo(QJsonObject& obj) const INT32_SAVE(_abs_data.byte_count, obj); } +void AbstractExtractor::registSubField(std::shared_ptr inst) +{ + +} + BytesAsHex::BytesAsHex() : AbstractExtractor(NAME(BytesAsHex), DataType::TextString) { setCountWithin(1); } -QVariant BytesAsHex::parse(const QByteArray& bytes) const +#include "TranslateBasic.h" +void BytesAsHex::parse(const QByteArray& bytes, std::shared_ptr out) const { QString result; for (auto char_v : bytes) { result += QString("%1").arg(char_v, 2, 16, QChar('0')); } - return result; + out->append(result); } std::shared_ptr BytesAsHex::newDefault() const @@ -99,7 +105,7 @@ void BytesAsBitCombine::clearOptions() _combine._switch_options.clear(); } -QVariant BytesAsBitCombine::parse(const QByteArray& bytes) const +void BytesAsBitCombine::parse(const QByteArray& bytes, std::shared_ptr out) const { auto keys = _combine._switch_options.keys(); std::sort(keys.begin(), keys.end()); @@ -114,7 +120,7 @@ QVariant BytesAsBitCombine::parse(const QByteArray& bytes) const else result += QString("%1<%2>;").arg(_combine._switch_options[idx], "N"); } - return result; + out->append(result); } #include @@ -168,7 +174,7 @@ bool BytesAsInteger::setCountWithin(int bytes) return AbstractExtractor::setCountWithin(bytes); } -QVariant BytesAsInteger::parse(const QByteArray& bytes) const +void BytesAsInteger::parse(const QByteArray& bytes, std::shared_ptr out) const { auto last = bytes[bytes.size() - 1]; auto mark = last == 0 ? 0 : last / std::abs(last); @@ -187,9 +193,9 @@ QVariant BytesAsInteger::parse(const QByteArray& bytes) const value = value << 8; value += (uchar)vchar; } - return *((long long*)(&value)); -} + out->append(*((long long*)(&value))); +} #include @@ -208,9 +214,10 @@ QString BytesAsString::codecName() const return this->_strings._conv_with->name(); } -QVariant BytesAsString::parse(const QByteArray& bytes) const +void BytesAsString::parse(const QByteArray& bytes, std::shared_ptr out) const { - return _strings._conv_with->toUnicode(bytes); + auto v = _strings._conv_with->toUnicode(bytes); + out->append(v); } void BytesAsString::loadFrom(std::shared_ptr core, const QJsonObject& obj) @@ -235,9 +242,9 @@ std::shared_ptr BytesAsString::newDefault() const return std::make_shared(); } -QVariant BytesAsFloat::parse(const QByteArray& bytes) const +void BytesAsFloat::parse(const QByteArray& bytes, std::shared_ptr out) const { - return *((float*)bytes.data()); + out->append(*((float*)bytes.data())); } std::shared_ptr BytesAsFloat::newDefault() const @@ -256,9 +263,9 @@ std::shared_ptr BytesAsDouble::newDefault() const return std::make_shared(); } -QVariant BytesAsDouble::parse(const QByteArray& bytes) const +void BytesAsDouble::parse(const QByteArray& bytes, std::shared_ptr out) const { - return *((double*)bytes.data()); + out->append(*((double*)bytes.data())); } BytesAsDouble::BytesAsDouble() @@ -279,7 +286,7 @@ bool BytesAsUnsigned::setCountWithin(int bytes) return AbstractExtractor::setCountWithin(count); } -QVariant BytesAsUnsigned::parse(const QByteArray& bytes) const +void BytesAsUnsigned::parse(const QByteArray& bytes, std::shared_ptr out) const { unsigned long long value = 0; for (auto vidx = bytes.size() - 1; vidx >= 0; vidx--) { @@ -287,7 +294,7 @@ QVariant BytesAsUnsigned::parse(const QByteArray& bytes) const value = value << 8; value += (uchar)vchar; } - return value; + out->append(value); } std::shared_ptr BytesAsUnsigned::newDefault() const @@ -405,21 +412,19 @@ void BytesAsList::saveTo(QJsonObject& obj) const OBJECT_SAVE(size_provider_obj, obj); } -QVariant BytesAsList::parse(const QByteArray& bytes) const +void BytesAsList::parse(const QByteArray& bytes, std::shared_ptr out) const { - QVariantList value_list; - auto expr = this->_list._bind_size_v->expression(); auto size_value = this->_list._bind_size_v->value(expr); auto unit_size = this->_list._bind_unit->countWithin(); for (auto idx = 0; idx < size_value; ++idx) { auto secn = bytes.mid(unit_size * idx, unit_size); - auto value_v = this->_list._bind_unit->parse(secn); - value_list << value_v; - } - return value_list; + auto slice_context = std::make_shared(); + slice_context->init(QString("ls<%1>").arg(idx), out); + this->_list._bind_unit->parse(secn, slice_context); + } } std::shared_ptr BytesAsList::newDefault() const @@ -427,6 +432,13 @@ std::shared_ptr BytesAsList::newDefault() const return std::make_shared(); } +void BytesAsList::registSubField(std::shared_ptr inst) +{ + inst->setField("ls", this->_list._bind_unit->outType()); + auto layer = std::make_shared("ls", inst); + this->_list._bind_unit->registSubField(layer); +} + QString BytesAsUnion::name() const { return NAME(BytesAsUnion); @@ -447,13 +459,14 @@ int BytesAsUnion::countWithin() const return _union.byte_count; } -QVariant BytesAsUnion::parse(const QByteArray& bytes) const +void BytesAsUnion::parse(const QByteArray& bytes, std::shared_ptr out) const { for (auto u : this->elementRules()) - if (u->checkpass(bytes)) - return u->bindRule()->parse(bytes); - - return QVariant(); + if (u->checkpass(bytes)) { + auto enum_context = std::make_shared(); + enum_context->init(u->name(), out); + u->bindRule()->parse(bytes, enum_context); + } } void BytesAsUnion::loadFrom( @@ -535,43 +548,68 @@ bool BytesAsUnion::setOffsetSpan(int value) return true; } -void extract::BytesAsSubRule::setActualName(const QString& name) +void BytesAsUnion::registSubField(std::shared_ptr inst) { - this->_rules._actual_name = name; + for (auto rl : this->_union._rule_list) { + inst->setField(rl->name(), rl->bindRule()->outType()); + auto layer = std::make_shared(rl->name(), inst); + rl->bindRule()->registSubField(layer); + } } -QString BytesAsSubRule::name() const +void BytesAsRuleSet::registSubField(std::shared_ptr inst) { - return this->_rules._actual_name; + for (auto rl_key : this->_rules._sub_rules.keys()){ + auto rlinst = this->_rules._sub_rules[rl_key]; + inst->setField(rl_key, rlinst->outType()); + auto layer = std::make_shared(rl_key, inst); + rlinst->registSubField(layer); + } } -DataType BytesAsSubRule::outType() const +void BytesAsRuleSet::parse(const QByteArray& bytes, std::shared_ptr out) const +{ + auto bufx = bytes; + for (auto keym : this->_rules._sub_rules.keys()) { + auto rule_context = std::make_shared(); + rule_context->init(keym, out); + + auto rule = this->_rules._sub_rules[keym]; + bufx = bufx.mid(rule->offsetSpan()); + auto count = rule->countWithin(); + auto secx = bufx.mid(0, count); + rule->parse(secx, rule_context); + bufx = bufx.mid(count); + } +} + +QString BytesAsRuleSet::name() const +{ + return NAME(BytesAsRuleSet); +} + +DataType BytesAsRuleSet::outType() const { return DataType::SUB_RULE; } -bool BytesAsSubRule::setOffsetSpan(int bytes) +bool BytesAsRuleSet::setOffsetSpan(int bytes) { this->_rules._byte_offset = bytes; return true; } -int BytesAsSubRule::offsetSpan() const +int BytesAsRuleSet::offsetSpan() const { return this->_rules._byte_offset; } -int BytesAsSubRule::countWithin() const +int BytesAsRuleSet::countWithin() const { return this->_rules._byte_count; } -QVariant BytesAsSubRule::parse(const QByteArray& bytes) const -{ - throw std::logic_error("The method or operation is not implemented."); -} - -void BytesAsSubRule::loadFrom(std::shared_ptr core, const QJsonObject& obj) +void BytesAsRuleSet::loadFrom(std::shared_ptr core, const QJsonObject& obj) { INT32_PEAK(_rules._byte_count, obj); INT32_PEAK(_rules._byte_offset, obj); @@ -581,26 +619,29 @@ void BytesAsSubRule::loadFrom(std::shared_ptr core, const QJsonO for (auto index = 0; index < array.size(); ++index) { auto rule_obj = array.at(index); - QString match_name; + QString match_name, key; QJsonObject match_obj; STRING_PEAK(match_name, rule_obj); + STRING_PEAK(key, rule_obj); OBJECT_PEAK(match_obj, rule_obj); auto xdev = core->extractUnitList()[match_name]->newDefault(); xdev->loadFrom(core, match_obj); - _rules._sub_rules.append(std::dynamic_pointer_cast(xdev)); + _rules._sub_rules[key] = std::dynamic_pointer_cast(xdev); } } -void BytesAsSubRule::saveTo(QJsonObject& obj) const +void BytesAsRuleSet::saveTo(QJsonObject& obj) const { INT32_SAVE(_rules._byte_count, obj); INT32_SAVE(_rules._byte_offset, obj); QJsonArray array; - for (auto info : _rules._sub_rules) { + for (auto key : _rules._sub_rules.keys()) { QJsonObject rule_obj, match_obj; - + + auto info = _rules._sub_rules[key]; + STRING_SAVE(key, rule_obj); QString match_name = info->name(); STRING_SAVE(match_name, rule_obj); info->saveTo(match_obj); @@ -611,7 +652,7 @@ void BytesAsSubRule::saveTo(QJsonObject& obj) const ARRAY_SAVE(array, obj); } -std::shared_ptr BytesAsSubRule::newDefault() const +std::shared_ptr BytesAsRuleSet::newDefault() const { - return std::make_shared(); + return std::make_shared(); } diff --git a/TranslateUI/extract_basic.h b/TranslateUI/extract_basic.h index 77038f6..26498b7 100644 --- a/TranslateUI/extract_basic.h +++ b/TranslateUI/extract_basic.h @@ -3,12 +3,17 @@ #include "common.h" #include +class SizeProvider; +class RuleMatch; +class ScopeFieldsSetter; +class DataAccessContext; + + /// /// 翻译单元抽象接口 /// class ExtractUnit : public Serializable { public: - virtual ~ExtractUnit() = default; /// /// 单元名称 @@ -16,6 +21,12 @@ public: /// virtual QString name() const = 0; + /// + /// 注册自身 + /// + /// + virtual void registSubField(std::shared_ptr inst) = 0; + /// /// /// @@ -42,37 +53,9 @@ public: /// /// /// - virtual QVariant parse(const QByteArray& bytes) const = 0; + virtual void parse(const QByteArray& bytes, std::shared_ptr out) const = 0; }; -/// -/// 尺寸解析器 -/// -class SizeProvider : public Serializable { -public: - virtual QString name() const = 0; - /// - /// 获取值,如果该值无法预先计算得知,返回-1 - /// - /// 尺寸值 - virtual int32_t value(const QString& expr) const = 0; - - virtual void setExpression(const QString& expr) = 0; - virtual QString expression() const = 0; -}; - -/// -/// 规则匹配器 -/// -class RuleMatch : public Serializable { -public: - virtual QString name() const = 0; - virtual std::shared_ptr bindRule() const = 0; - virtual void bindRule(std::shared_ptr rule) = 0; - virtual bool checkpass(const QByteArray& buffer) const = 0; -}; - - namespace extract { class AbstractExtractor : public ExtractUnit { public: @@ -86,7 +69,8 @@ namespace extract { virtual bool setCountWithin(int bytes); // ExtractUnit =========================== - QString name() const override; + QString name() const override; + void registSubField(std::shared_ptr inst) override; virtual DataType outType() const; /// /// 设置偏移字节数量 @@ -108,7 +92,7 @@ namespace extract { public: BytesAsHex(); - QVariant parse(const QByteArray& bytes) const override; + void parse(const QByteArray& bytes, std::shared_ptr out) const override; std::shared_ptr newDefault() const override; }; @@ -128,7 +112,7 @@ namespace extract { virtual void clearOptions(); // ExtractUnit ============================ - QVariant parse(const QByteArray& bytes) const override; + void parse(const QByteArray& bytes, std::shared_ptr out) const override; // Serializable ============================== void loadFrom(std::shared_ptr core, const QJsonObject& obj) override; @@ -145,7 +129,7 @@ namespace extract { // ExtractUnit ============================ bool setCountWithin(int bytes) override; - QVariant parse(const QByteArray& bytes) const override; + void parse(const QByteArray& bytes, std::shared_ptr out) const override; // Serializable ============================== std::shared_ptr newDefault() const override; @@ -160,7 +144,7 @@ namespace extract { // ExtractUnit ============================ bool setCountWithin(int bytes) override; - QVariant parse(const QByteArray& bytes) const override; + void parse(const QByteArray& bytes, std::shared_ptr out) const override; // Serializable ============================== std::shared_ptr newDefault() const override; @@ -182,7 +166,7 @@ namespace extract { QString codecName() const; // ExtractUnit ============================ - QVariant parse(const QByteArray& bytes) const override; + void parse(const QByteArray& bytes, std::shared_ptr out) const override; // Serializable ============================== void loadFrom(std::shared_ptr core, const QJsonObject& obj) override; @@ -194,7 +178,7 @@ namespace extract { public: BytesAsFloat(); - QVariant parse(const QByteArray& bytes) const override; + void parse(const QByteArray& bytes, std::shared_ptr out) const override; std::shared_ptr newDefault() const override; }; @@ -202,7 +186,7 @@ namespace extract { public: BytesAsDouble(); - QVariant parse(const QByteArray& bytes) const override; + void parse(const QByteArray& bytes, std::shared_ptr out) const override; std::shared_ptr newDefault() const override; }; @@ -224,6 +208,7 @@ namespace extract { public: QString name() const override; + void registSubField(std::shared_ptr inst) override; DataType outType() const override; int offsetSpan() const override; int countWithin() const override; @@ -231,7 +216,7 @@ namespace extract { void loadFrom(std::shared_ptr core, const QJsonObject& obj) override; void saveTo(QJsonObject& obj) const override; - QVariant parse(const QByteArray& bytes) const override; + void parse(const QByteArray& bytes, std::shared_ptr out) const override; std::shared_ptr newDefault() const override; }; @@ -252,12 +237,13 @@ namespace extract { public: QString name() const override; + void registSubField(std::shared_ptr inst) override; DataType outType() const override; bool setOffsetSpan(int value); int offsetSpan() const override; int countWithin() const override; - QVariant parse(const QByteArray& bytes) const override; + void parse(const QByteArray& bytes, std::shared_ptr out) const override; void loadFrom(std::shared_ptr core, const QJsonObject& obj) override; void saveTo(QJsonObject& obj) const override; @@ -265,19 +251,16 @@ namespace extract { }; - class BytesAsSubRule : public ExtractUnit { + class BytesAsRuleSet : public ExtractUnit { public: struct __Private { int _byte_offset = 0, _byte_count = 1; - QList> _sub_rules; - - QString _actual_name; + QHash> _sub_rules; }_rules; - void setActualName(const QString &name); - public: QString name() const override; + void registSubField(std::shared_ptr inst) override; DataType outType() const override; bool setOffsetSpan(int bytes) override; int offsetSpan() const override; @@ -285,8 +268,7 @@ namespace extract { std::shared_ptr newDefault() const override; - QVariant parse(const QByteArray& bytes) const override; - + void parse(const QByteArray& bytes, std::shared_ptr out) const override; void loadFrom(std::shared_ptr core, const QJsonObject& obj) override; void saveTo(QJsonObject& obj) const override;