构建List解析框架

This commit is contained in:
codeboss 2025-08-02 07:06:42 +08:00
parent 1c43423cbe
commit 4503ee0d88
4 changed files with 212 additions and 40 deletions

View File

@ -37,18 +37,15 @@ void IntDelegate::updateEditorGeometry(QWidget* editor, const QStyleOptionViewIt
void SequenceRulesView::currentRuleRefresh(const QModelIndex& idx)
{
auto new_inst = _rule_sequence.at(idx.row());
auto rule_insv = std::dynamic_pointer_cast<AbstractExtractor>(new_inst);
auto rule_insv = _rule_sequence.at(idx.row());
auto offset_index = idx.sibling(idx.row(), 1);
if (rule_insv) {
auto offset_number = offset_index.data(Qt::DisplayRole).toInt();
rule_insv->setOffsetSpan(offset_number);
}
auto count_index = idx.sibling(idx.row(), 3);
_sequence_model->setData(offset_index, new_inst->offsetSpan(), Qt::EditRole);
_sequence_model->setData(count_index, new_inst->countWithin(), Qt::EditRole);
_sequence_model->setData(offset_index, rule_insv->offsetSpan(), Qt::EditRole);
_sequence_model->setData(count_index, rule_insv->countWithin(), Qt::EditRole);
auto param_index = idx.sibling(idx.row(), 4);
QJsonObject obj;
@ -66,6 +63,17 @@ void SequenceRulesView::peersRuleChanged(const QModelIndex& idx)
auto new_inst = std::dynamic_pointer_cast<ExtractUnit>(rule_nm->newDefault());
_rule_sequence.replace(idx.row(), new_inst);
if (typeid(*new_inst.get()) == typeid(BytesAsList)) {
auto conv = std::dynamic_pointer_cast<BytesAsList>(new_inst);
if (!conv->elementRule()) {
conv->setElementRule(this->base->defaultRule());
}
if (!conv->sizeProvider()) {
conv->setSizeProvider(this->base->defaultSizeProvider());
}
}
currentRuleRefresh(idx);
}
@ -147,6 +155,7 @@ void SequenceRulesView::removeTranslateUnit()
TranslateBasic::TranslateBasic()
{
// extractor type-list
std::shared_ptr<ExtractUnit> u_ptr = std::make_shared<BytesAsBitCombine>();
_extractor_types[u_ptr->name()] = u_ptr;
@ -168,6 +177,14 @@ TranslateBasic::TranslateBasic()
u_ptr = std::make_shared<BytesAsDouble>();
_extractor_types[u_ptr->name()] = u_ptr;
u_ptr = std::make_shared<BytesAsList>();
_extractor_types[u_ptr->name()] = u_ptr;
// size-provider type-list
auto sz_ptr = std::make_shared<ConstNumberProvider>();
this->_default_size_provider = sz_ptr;
_size_provider_types[sz_ptr->name()] = sz_ptr;
}
std::shared_ptr<ExtractUnit> TranslateBasic::defaultRule() const
@ -175,11 +192,21 @@ std::shared_ptr<ExtractUnit> TranslateBasic::defaultRule() const
return _default_translate_rule;
}
std::shared_ptr<extract::SizeProvider> TranslateBasic::defaultSizeProvider() const
{
return _default_size_provider;
}
QHash<QString, std::shared_ptr<ExtractUnit>> TranslateBasic::extactors() const
{
return _extractor_types;
}
QHash<QString, std::shared_ptr<extract::SizeProvider>> TranslateBasic::sizeProviders() const
{
return _size_provider_types;
}
RuleSelectDelegate::RuleSelectDelegate(std::shared_ptr<TranslateBasic> ins)
:_kernel(ins) {
}
@ -212,3 +239,23 @@ void RuleSelectDelegate::updateEditorGeometry(QWidget* editor, const QStyleOptio
{
editor->setGeometry(option.rect);
}
QString ConstNumberProvider::name() const
{
return NAME(ConstNumberProvider);
}
int32_t ConstNumberProvider::value(const QString& expr) const
{
return expr.toInt();
}
void ConstNumberProvider::setExpression(const QString& expr)
{
this->_number_value = expr;
}
QString ConstNumberProvider::expression() const
{
return this->_number_value;
}

View File

@ -6,7 +6,8 @@
#include <QItemDelegate>
#include <QHash>
#include <memory>
class ExtractUnit;
#include "TranslateBasic.h"
/// <summary>
/// ·­Òë³ÌÐòºËÐÄ
@ -14,13 +15,17 @@ class ExtractUnit;
class TranslateBasic {
private:
QHash<QString, std::shared_ptr<ExtractUnit>> _extractor_types;
std::shared_ptr<ExtractUnit> _default_translate_rule;
std::shared_ptr<ExtractUnit> _default_translate_rule = nullptr;
QHash<QString, std::shared_ptr<extract::SizeProvider>> _size_provider_types;
std::shared_ptr<extract::SizeProvider> _default_size_provider = nullptr;
public:
TranslateBasic();
std::shared_ptr<ExtractUnit> defaultRule() const;
std::shared_ptr<extract::SizeProvider> defaultSizeProvider() const;
QHash<QString, std::shared_ptr<ExtractUnit>> extactors() const;
QHash<QString, std::shared_ptr<extract::SizeProvider>> sizeProviders() const;
};
@ -65,6 +70,17 @@ public:
virtual void updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index) const override;
};
class ConstNumberProvider : public extract::SizeProvider {
private:
QString _number_value;
public:
QString name() const override;
int32_t value(const QString& expr) const override;
void setExpression(const QString &expr) override;
QString expression() const override;
};
/// <summary>
/// ÐòÁл¯¹æÔòÊÓͼ

View File

@ -286,21 +286,9 @@ std::shared_ptr<Serializable> BytesAsUnsigned::newDefault() const
}
#include <stdexcept>
QVariant BytesAsList::parse(const QByteArray& bytes) const
{
throw std::logic_error("The method or operation is not implemented.");
}
std::shared_ptr<Serializable> BytesAsList::newDefault() const
{
throw std::logic_error("The method or operation is not implemented.");
}
bool BytesAsUnion::setSizeProvider(std::shared_ptr<SizeProvider> ins)
{
if(ins->value() < 1)
return false;
this->_provider_ins = ins;
return true;
}
@ -314,3 +302,107 @@ std::shared_ptr<Serializable> BytesAsUnion::newDefault() const
{
throw std::logic_error("The method or operation is not implemented.");
}
bool BytesAsList::setOffsetSpan(int value)
{
this->_bytes_offset = value;
return true;
}
std::shared_ptr<ExtractUnit> BytesAsList::elementRule() const
{
return this->_bind_unit;
}
bool BytesAsList::setElementRule(std::shared_ptr<ExtractUnit> u)
{
this->_bind_unit = u;
return true;
}
std::shared_ptr<extract::SizeProvider> BytesAsList::sizeProvider() const
{
return this->_bind_size_v;
}
bool BytesAsList::setSizeProvider(std::shared_ptr<SizeProvider> ins)
{
this->_bind_size_v = ins;
return true;
}
QString BytesAsList::name() const
{
return NAME(BytesAsList);
}
DataType BytesAsList::outType() const
{
return DataType::LIST_COLLECTION;
}
int BytesAsList::offsetSpan() const
{
return _bytes_offset;
}
int BytesAsList::countWithin() const
{
auto expr = this->_bind_size_v->expression();
if (this->_bind_size_v->value(expr) < 0) {
return 0;
}
return this->_bind_size_v->value(expr) * this->_bind_unit->countWithin();
}
void BytesAsList::loadFrom(const QJsonObject& obj)
{
INT32_PEAK(_bytes_offset);
QString bind_provider_expr = "";
STRING_SAVE(bind_provider_expr);
if (this->_bind_size_v)
this->_bind_size_v->setExpression(bind_provider_expr);
}
void BytesAsList::saveTo(QJsonObject& obj) const
{
QString bind_unit_name = "";
if (this->_bind_unit)
bind_unit_name = this->_bind_unit->name();
STRING_SAVE(bind_unit_name);
INT32_SAVE(_bytes_offset);
QString bind_size_provider_name = "";
QString bind_provider_expr = "";
if (this->_bind_size_v) {
bind_provider_expr = this->_bind_size_v->expression();
bind_size_provider_name = this->_bind_size_v->name();
}
STRING_SAVE(bind_size_provider_name);
STRING_SAVE(bind_provider_expr);
}
QVariant BytesAsList::parse(const QByteArray& bytes) const
{
QVariantList value_list;
auto expr = this->_bind_size_v->expression();
auto size_value = this->_bind_size_v->value(expr);
auto unit_size = this->_bind_unit->countWithin();
for (auto idx = 0; idx < size_value; ++idx) {
auto secn = bytes.mid(unit_size * idx, unit_size);
auto value_v = this->_bind_unit->parse(secn);
value_list << value_v;
}
return value_list;
}
std::shared_ptr<Serializable> BytesAsList::newDefault() const
{
return std::make_shared<BytesAsList>();
}

View File

@ -22,7 +22,11 @@ public:
/// </summary>
/// <returns></returns>
virtual DataType outType() const = 0;
/// <summary>
/// 设置偏移字节数量
/// </summary>
/// <param name="bytes"></param>
virtual bool setOffsetSpan(int bytes) = 0;
/// <summary>
/// 从上一个单元字节偏移字节数量
/// </summary>
@ -51,16 +55,16 @@ namespace extract {
public:
AbstractExtractor(const QString& name, DataType data);
/// <summary>
/// 设置偏移字节数量
/// </summary>
/// <param name="bytes"></param>
virtual bool setOffsetSpan(int bytes);
virtual bool setCountWithin(int bytes);
// ExtractUnit ===========================
QString name() const override;
virtual DataType outType() const;
/// <summary>
/// 设置偏移字节数量
/// </summary>
/// <param name="bytes"></param>
virtual bool setOffsetSpan(int bytes);
int offsetSpan() const override;
int countWithin() const override;
@ -183,28 +187,41 @@ namespace extract {
/// </summary>
class SizeProvider {
public:
virtual QString name() const = 0;
/// <summary>
/// 获取值,如果该值无法预先计算得知,返回-1
/// </summary>
/// <returns>尺寸值</returns>
virtual int32_t value() const = 0;
virtual int32_t value(const QString& expr) const = 0;
virtual void setExpression(const QString& expr) = 0;
virtual QString expression() const = 0;
};
class BytesAsList : public AbstractExtractor {
class BytesAsList : public ExtractUnit {
private:
std::shared_ptr<ExtractUnit> _bind_unit = nullptr;
int _bytes_offset = 0;
std::shared_ptr<SizeProvider> _bind_size_v = nullptr;
public:
bool setOffsetSpan(int value);
std::shared_ptr<ExtractUnit> elementRule() const;
bool setElementRule(std::shared_ptr<ExtractUnit> u);
/// <summary>
/// 设置尺寸解析器,返回值标志是否接受该设置
/// </summary>
/// <param name="ins"></param>
/// <returns>true-有效false-无效</returns>
virtual bool setSizeProvider(std::shared_ptr<SizeProvider> ins) = 0;
std::shared_ptr<SizeProvider> sizeProvider() const;
bool setSizeProvider(std::shared_ptr<SizeProvider> ins);
public:
QString name() const override;
DataType outType() const override;
int offsetSpan() const override;
int countWithin() const override;
void loadFrom(const QJsonObject& obj) override;
void saveTo(QJsonObject& obj) const override;
QVariant parse(const QByteArray& bytes) const override;
std::shared_ptr<Serializable> newDefault() const override;