改进解析框架,SingleBased、ListBased、UnionBased多种数据组织类型

This commit is contained in:
codeboss 2025-08-10 20:32:42 +08:00
parent efb7d3aa5f
commit f9baad79d4
5 changed files with 382 additions and 377 deletions

View File

@ -28,15 +28,6 @@ TranslateBasic::TranslateBasic()
_basic_extractor_types[u_ptr->unitType()] = u_ptr;
this->_default_translate_rule = u_ptr;
u_ptr = std::make_shared<AsList>();
_complex_extractor_types[u_ptr->unitType()] = u_ptr;
u_ptr = std::make_shared<AsUnion>();
_complex_extractor_types[u_ptr->unitType()] = u_ptr;
u_ptr = std::make_shared<AsRuleSet>();
_complex_extractor_types[u_ptr->unitType()] = u_ptr;
// size-provider type-list
std::shared_ptr<SizeProvider> sz_ptr = std::make_shared<ConstNumberProvider>();
this->_default_size_provider = sz_ptr;
@ -44,14 +35,26 @@ TranslateBasic::TranslateBasic()
sz_ptr = std::make_shared<InterpretedNumberPrivider>();
_size_provider_types[sz_ptr->name()] = sz_ptr;
// extract-unit type-list
std::shared_ptr<ExtractUnit> x_ptr = std::make_shared<SingleBasedUnit>();
_process_unit_types[x_ptr->baseType()] = x_ptr;
_default_process_unit = x_ptr;
x_ptr = std::make_shared<ListBasedUnit>();
_process_unit_types[x_ptr->baseType()] = x_ptr;
x_ptr = std::make_shared<UnionBasedUnit>();
_process_unit_types[x_ptr->baseType()] = x_ptr;
}
std::shared_ptr<ExtractDelegate> TranslateBasic::defaultExtractUnit() const
std::shared_ptr<ExtractDelegate> TranslateBasic::defaultExtractDelegate() const
{
return _default_translate_rule;
}
QHash<QString, std::shared_ptr<ExtractDelegate>> TranslateBasic::basicExtractors() const
QHash<QString, std::shared_ptr<ExtractDelegate>> TranslateBasic::extractorMap() const
{
return _basic_extractor_types;
}
@ -66,15 +69,6 @@ std::shared_ptr<RuleMatch> TranslateBasic::defaultRuleMatch() const
return _default_rule_match;
}
QHash<QString, std::shared_ptr<ExtractDelegate>> TranslateBasic::totalExtractors() const
{
decltype(_basic_extractor_types) ntypes;
for(auto key : _complex_extractor_types.keys())
ntypes[key] = _complex_extractor_types[key];
return ntypes;
}
void TranslateBasic::addDelegate(std::shared_ptr<ExtractDelegate> inst)
{
auto repeat_name_count = std::count_if(
@ -142,16 +136,26 @@ void TranslateBasic::replaceDelegate(const QString& name, std::shared_ptr<Extrac
assert("Ö¸¶¨Name²»´æÔÚ" && 0);
}
QHash<QString, std::shared_ptr<SizeProvider>> TranslateBasic::sizeProviderList() const
QHash<QString, std::shared_ptr<SizeProvider>> TranslateBasic::sizeProviderMap() const
{
return _size_provider_types;
}
QHash<QString, std::shared_ptr<RuleMatch>> TranslateBasic::ruleMatchList() const
QHash<QString, std::shared_ptr<RuleMatch>> TranslateBasic::ruleMatchMap() const
{
return _rule_match_types;
}
std::shared_ptr<ExtractUnit> TranslateBasic::defaultExtractUnit() const
{
return _default_process_unit;
}
QHash<QString, std::shared_ptr<ExtractUnit>> TranslateBasic::extractUnitMap() const
{
return _process_unit_types;
}
void ConstNumberProvider::bindInput(std::shared_ptr<DataContext> inst)
{
@ -257,10 +261,10 @@ void ValueAccessContext::append(const QVariant& value)
this->_cascade._current_value = value;
}
QList<QVariant> ValueAccessContext::dataSeqs() const
QList<std::pair<QString, QVariant>> ValueAccessContext::dataSeqs() const
{
QList<QVariant> values;
values << _cascade._current_value;
QList<std::pair<QString, QVariant>> values;
values << std::make_pair(_cascade._current_field, _cascade._current_value);
for (auto pair : _cascade._children_context) {
values << pair.second->dataSeqs();
}

View File

@ -66,7 +66,7 @@ public:
/// »ñÈ¡Êý¾ÝÐòÁÐ
/// </summary>
/// <returns></returns>
virtual QList<QVariant> dataSeqs() const = 0;
virtual QList<std::pair<QString, QVariant>> dataSeqs() const = 0;
};
// ==================================================================
@ -99,8 +99,12 @@ public:
class RuleMatch : public Serializable {
public:
virtual QString matchType() const = 0;
virtual std::shared_ptr<ExtractUnit> bindRule() const = 0;
virtual void bindRule(std::shared_ptr<ExtractUnit> rule) = 0;
virtual std::shared_ptr<ExtractDelegate> getDelegate() const = 0;
virtual void bindDelegate(std::shared_ptr<ExtractDelegate> rule) = 0;
virtual QString expression() const = 0;
virtual void setExpression(const QString &expr) = 0;
virtual bool checkpass(const QByteArray& buffer) const = 0;
};
@ -110,7 +114,6 @@ public:
class TranslateBasic {
private:
QHash<QString, std::shared_ptr<ExtractDelegate>> _basic_extractor_types;
QHash<QString, std::shared_ptr<ExtractDelegate>> _complex_extractor_types;
std::shared_ptr<ExtractDelegate> _default_translate_rule = nullptr;
QHash<QString, std::shared_ptr<SizeProvider>> _size_provider_types;
@ -119,19 +122,22 @@ private:
QHash<QString, std::shared_ptr<RuleMatch>> _rule_match_types;
std::shared_ptr<RuleMatch> _default_rule_match = nullptr;
QHash<QString, std::shared_ptr<ExtractUnit>> _process_unit_types;
std::shared_ptr<ExtractUnit> _default_process_unit = nullptr;
QList<std::shared_ptr<ExtractDelegate>> _custom_rule_types;
public:
TranslateBasic();
std::shared_ptr<ExtractDelegate> defaultExtractDelegate() const;
QHash<QString, std::shared_ptr<ExtractDelegate>> extractorMap() const;
std::shared_ptr<SizeProvider> defaultSizeProvider() const;
QHash<QString, std::shared_ptr<SizeProvider>> sizeProviderList() const;
QHash<QString, std::shared_ptr<SizeProvider>> sizeProviderMap() const;
std::shared_ptr<RuleMatch> defaultRuleMatch() const;
QHash<QString, std::shared_ptr<RuleMatch>> ruleMatchList() const;
std::shared_ptr<ExtractDelegate> defaultExtractUnit() const;
QHash<QString, std::shared_ptr<ExtractDelegate>> basicExtractors() const;
QHash<QString, std::shared_ptr<ExtractDelegate>> totalExtractors() const;
QHash<QString, std::shared_ptr<RuleMatch>> ruleMatchMap() const;
std::shared_ptr<ExtractUnit> defaultExtractUnit() const;
QHash<QString, std::shared_ptr<ExtractUnit>> extractUnitMap() const;
void addDelegate(std::shared_ptr<ExtractDelegate> inst);
void removeDelegate(const QString& alias);
@ -208,8 +214,7 @@ public:
void setChild(const QString& field, std::shared_ptr<DataContext> inst) override;
void append(const QVariant& value) override;
QList<QVariant> dataSeqs() const override;
QList<std::pair<QString, QVariant>> dataSeqs() const override;
public:
QVariant get(const QString& unique_key) const override;

View File

@ -12,6 +12,8 @@ WrapConfigs::WrapConfigs(std::shared_ptr<TranslateBasic> _base, QWidget* p)
_alias_model(new QStandardItemModel(this)),
_configurations(new QStackedWidget(this))
{
this->setWindowTitle("DelegateAlias Configuration");
auto layout = new QVBoxLayout(this);
auto split = new QSplitter(this);
layout->addWidget(split);
@ -127,7 +129,7 @@ void WrapConfigs::aliasAppend()
while (exists.contains(name))
name += "#";
auto ins = _bind_base->defaultExtractUnit()->newDefault();
auto ins = _bind_base->defaultExtractDelegate()->newDefault();
auto nins = std::dynamic_pointer_cast<ExtractDelegate>(ins);
nins->setAlias(name);
@ -171,7 +173,7 @@ void WrapConfigs::dataChanged(QStandardItem* cell)
auto origin_key = total_alias_set.at(cell->row());
auto new_type = cell->text();
auto new_ins = _bind_base->basicExtractors()[new_type]->newDefault();
auto new_ins = _bind_base->extractorMap()[new_type]->newDefault();
auto new_delegate = std::dynamic_pointer_cast<ExtractDelegate>(new_ins);
new_delegate->setAlias(origin_key);
_bind_base->replaceDelegate(origin_key, new_delegate);
@ -195,7 +197,7 @@ QWidget* RuleSelectDelegate::createEditor(QWidget* parent, const QStyleOptionVie
void RuleSelectDelegate::setEditorData(QWidget* editor, const QModelIndex& index) const
{
auto rule_names = this->_kernel->basicExtractors().keys();
auto rule_names = this->_kernel->extractorMap().keys();
std::sort(rule_names.begin(), rule_names.end());
auto combo = dynamic_cast<QComboBox*>(editor);
@ -253,6 +255,7 @@ void CountWithinConfiguration::currentRuleAccept(std::shared_ptr<ExtractDelegate
this->_bind_u = u;
this->_bind_index = i;
QSignalBlocker v(_count_input);
_count_input->setValue(u->countWithin());
}

View File

@ -44,7 +44,7 @@ void AbstractExtractor::saveTo(QJsonObject& obj) const
INT32_SAVE(_abs_data.byte_count, obj);
}
void AbstractExtractor::registSubField(std::shared_ptr<ScopeFieldsSetter> inst){}
void AbstractExtractor::registSubField(std::shared_ptr<ScopeFieldsSetter> inst) {}
QString AbstractExtractor::aliasName() const
{
@ -56,7 +56,7 @@ void AbstractExtractor::setAlias(const QString& name)
_abs_data.name_alias = name;
}
AsHex::AsHex(): AbstractExtractor(topic(), DataType::TextString) {
AsHex::AsHex() : AbstractExtractor(topic(), DataType::TextString) {
setCountWithin(1);
}
@ -332,256 +332,23 @@ QString AsUnsigned::topic()
}
#include <stdexcept>
std::shared_ptr<ExtractUnit> AsList::elementRule() const
{
return this->_list._bind_unit;
}
bool AsList::setElementRule(std::shared_ptr<ExtractUnit> u)
{
this->_list._bind_unit = u;
return true;
}
std::shared_ptr<SizeProvider> AsList::sizeProvider() const
{
return this->_list._bind_size_v;
}
bool AsList::setSizeProvider(std::shared_ptr<SizeProvider> ins)
{
this->_list._bind_size_v = ins;
return true;
}
QString AsList::unitType() const
{
return topic();
}
DataType AsList::outType() const
{
return DataType::LIST_COLLECTION;
}
int AsList::countWithin() const
{
return _list.count_acculate;
}
void AsList::loadFrom(std::shared_ptr<TranslateBasic> core, const QJsonObject& obj)
{
STRING_PEAK(_list._alias_name, obj);
QString size_provider_name = "";
STRING_PEAK(size_provider_name, obj);
auto xdev = core->sizeProviderList()[size_provider_name]->newDefault();
this->_list._bind_size_v = std::dynamic_pointer_cast<SizeProvider>(xdev);
QString bind_unit_name = "";
STRING_PEAK(bind_unit_name, obj);
xdev = core->operator[](bind_unit_name)->newDefault();
this->_list._bind_unit = std::dynamic_pointer_cast<ExtractUnit>(xdev);
QJsonObject unit_obj;
QJsonObject size_provider_obj;
OBJECT_PEAK(unit_obj, obj);
OBJECT_PEAK(size_provider_obj, obj);
this->_list._bind_size_v->loadFrom(core, size_provider_obj);
this->_list._bind_unit->loadFrom(core, unit_obj);
}
void AsList::saveTo(QJsonObject& obj) const
{
STRING_SAVE(_list._alias_name, obj);
QString size_provider_name = this->_list._bind_size_v->name();
STRING_SAVE(size_provider_name, obj);
QString bind_unit_name = this->_list._bind_unit->name();
STRING_SAVE(bind_unit_name, obj);
QJsonObject unit_obj;
_list._bind_unit->saveTo(unit_obj);
QJsonObject size_provider_obj;
_list._bind_size_v->saveTo(size_provider_obj);
OBJECT_SAVE(unit_obj, obj);
OBJECT_PEAK(size_provider_obj, obj);
}
void AsList::parse(const QByteArray& bytes, std::shared_ptr<DataContext> out) const
{
auto expr = this->_list._bind_size_v->expression();
auto size_value = this->_list._bind_size_v->value(expr);
auto remains = bytes;
const_cast<AsList*>(this)->_list.count_acculate = 0;
for (auto idx = 0; idx < size_value; ++idx) {
this->_list._bind_unit->parse(remains, out);
auto unit_size = this->_list._bind_unit->countWithin();
remains = remains.mid(unit_size);
const_cast<AsList*>(this)->_list.count_acculate += unit_size;
}
}
std::shared_ptr<Serializable> AsList::newDefault() const
{
return std::make_shared<AsList>();
}
void AsList::registSubField(std::shared_ptr<ScopeFieldsSetter> inst){}
QString AsList::topic()
{
return NAME(AsList);
}
QString AsList::aliasName() const
{
return _list._alias_name;
}
void AsList::setAlias(const QString& name)
{
_list._alias_name = name;
}
DataType AsUnion::outType() const
{
return DataType::UNION_COMBINATE;
}
int AsUnion::countWithin() const
{
return _union.byte_count;
}
void AsUnion::parse(const QByteArray& bytes, std::shared_ptr<DataContext> out) const
{
for (auto u : this->elementRules())
if (u->checkpass(bytes)) {
u->bindRule()->parse(bytes, out);
break;
}
}
void AsUnion::loadFrom(std::shared_ptr<TranslateBasic> core, const QJsonObject& obj)
{
INT32_PEAK(_union.byte_count, obj);
STRING_PEAK(_union.alias_name, obj);
QJsonArray array;
ARRAY_PEAK(array, obj);
this->_union._rule_list.clear();
for (auto index = 0; index < array.size(); ++index) {
auto rule_obj = array.at(index);
QString match_name;
STRING_PEAK(match_name, rule_obj);
QJsonObject match_obj;
OBJECT_PEAK(match_obj, rule_obj);
auto match = core->ruleMatchList()[match_name];
auto nmatch = match->newDefault();
nmatch->loadFrom(core, match_obj);
this->_union._rule_list.append(std::dynamic_pointer_cast<RuleMatch>(nmatch));
}
}
void AsUnion::saveTo(QJsonObject& obj) const
{
INT32_SAVE(_union.byte_count, obj);
STRING_SAVE(_union.alias_name, obj);
QJsonArray array;
for (auto insr : this->_union._rule_list) {
QJsonObject rule_obj;
auto match_name = insr->matchType();
STRING_SAVE(match_name, rule_obj);
QJsonObject match_obj;
insr->saveTo(match_obj);
OBJECT_SAVE(match_obj, rule_obj);
array.append(rule_obj);
}
ARRAY_SAVE(array, obj);
}
std::shared_ptr<Serializable> AsUnion::newDefault() const
{
return std::make_shared<AsUnion>();
}
QList<std::shared_ptr<RuleMatch>> AsUnion::elementRules() const
{
return _union._rule_list;
}
bool AsUnion::appendElementRule(std::shared_ptr<RuleMatch> u)
{
this->_union._rule_list << u;
return true;
}
void AsUnion::clearRules()
{
this->_union._rule_list.clear();
}
bool AsUnion::setCountWithin(int bytes)
{
this->_union.byte_count = bytes;
return true;
}
void AsUnion::registSubField(std::shared_ptr<ScopeFieldsSetter> inst)
{
for (auto rl : this->_union._rule_list)
rl->bindRule()->registSubField(inst);
}
QString AsUnion::topic()
{
return NAME(AsUnion);
}
QString AsUnion::aliasName() const
{
return _union.alias_name;
}
void AsUnion::setAlias(const QString& name)
{
_union.alias_name = name;
}
QString AsUnion::unitType() const
{
return topic();
}
void AsRuleSet::registSubField(std::shared_ptr<ScopeFieldsSetter> inst)
{
for (auto rl_key : this->fieldNames()){
auto rlinst = this->operator[](rl_key);
rlinst->registSubField(inst);
for (auto subrule : _bind.sub_units) {
subrule->registSubField(inst);
}
}
void AsRuleSet::parse(const QByteArray& bytes, std::shared_ptr<DataContext> out) const
{
const_cast<AsRuleSet*>(this)->_bind.count_within_rt = 0;
auto bufx = bytes;
for (auto keym : this->fieldNames()) {
auto rule = this->operator[](keym);
for (auto rule : _bind.sub_units) {
rule->parse(bufx, out);
auto size_u = rule->countWithin();
bufx = bufx.mid(size_u);
const_cast<AsRuleSet*>(this)->_bind.count_within_rt += size_u;
}
}
@ -597,11 +364,7 @@ DataType AsRuleSet::outType() const
int AsRuleSet::countWithin() const
{
auto count = 0;
for (auto inst : _bind.sub_units)
count += inst->countWithin();
return count;
return _bind.count_within_rt;
}
void AsRuleSet::loadFrom(std::shared_ptr<TranslateBasic> core, const QJsonObject& obj)
@ -610,18 +373,18 @@ void AsRuleSet::loadFrom(std::shared_ptr<TranslateBasic> core, const QJsonObject
QJsonArray array;
ARRAY_SAVE(array, obj);
_bind.sub_units.clear();
for (auto index = 0; index < array.size(); ++index) {
auto rule_obj = array.at(index);
QString match_name, field_name;
QString unit_type, field_name;
STRING_PEAK(field_name, rule_obj);
STRING_PEAK(match_name, rule_obj);
STRING_PEAK(unit_type, rule_obj);
QJsonObject match_obj;
OBJECT_PEAK(match_obj, rule_obj);
auto xdev = core->operator[](match_name)->newDefault();
auto xdev = core->extractUnitMap()[unit_type]->newDefault();
xdev->loadFrom(core, match_obj);
_bind.sub_units << std::dynamic_pointer_cast<ExtractUnit>(xdev);
}
@ -637,9 +400,8 @@ void AsRuleSet::saveTo(QJsonObject& obj) const
auto field_name = pairk->name();
STRING_SAVE(field_name, rule_obj);
QString match_name = pairk->delegateInst()->aliasName();
STRING_SAVE(match_name, rule_obj);
auto unit_type = pairk->baseType();
STRING_SAVE(unit_type, rule_obj);
pairk->saveTo(match_obj);
OBJECT_SAVE(match_obj, rule_obj);
@ -686,7 +448,7 @@ QList<QString> AsRuleSet::fieldNames() const
std::shared_ptr<ExtractUnit> AsRuleSet::operator[](const QString& field) const
{
for (auto pair : this->_bind.sub_units) {
if(pair->name() == field)
if (pair->name() == field)
return pair;
}
@ -802,3 +564,237 @@ int SingleBasedUnit::countWithin() const
{
return _inst._delegate_inst->countWithin() + offsetSpan();
}
QString SingleBasedUnit::baseType() const
{
return NAME(SingleBasedUnit);
}
QString ListBasedUnit::name() const
{
return _list.field_name;
}
void ListBasedUnit::setName(const QString& name)
{
_list.field_name = name;
}
bool ListBasedUnit::setOffsetSpan(int bytes)
{
_list.bytes_offset = bytes;
return true;
}
int ListBasedUnit::offsetSpan() const
{
return _list.bytes_offset;
}
std::shared_ptr<ExtractDelegate> ListBasedUnit::delegateInst() const
{
return _list.delegate_inst;
}
void ListBasedUnit::setDelegate(std::shared_ptr<ExtractDelegate> inst)
{
_list.delegate_inst = inst;
}
void ListBasedUnit::registSubField(std::shared_ptr<ScopeFieldsSetter> inst) {}
int ListBasedUnit::countWithin() const
{
return _list.count_with_runtime;
}
void ListBasedUnit::parse(const QByteArray& bytes, std::shared_ptr<DataContext> out) const
{
const_cast<ListBasedUnit*>(this)->_list.count_with_runtime = 0;
_list.size_provider_inst->bindInput(out);
auto expr = _list.size_provider_inst->expression();
auto count = _list.size_provider_inst->value(expr);
auto buffer = bytes.mid(_list.bytes_offset);
for (auto index = 0; index < count; ++index) {
auto context = std::shared_ptr<ValueAccessContext>();
context->init(name() + QString("<%1>").arg(index), out);
delegateInst()->parse(buffer, context);
auto size_u = delegateInst()->countWithin();
buffer = buffer.mid(size_u);
}
}
void ListBasedUnit::loadFrom(std::shared_ptr<TranslateBasic> core, const QJsonObject& obj)
{
STRING_PEAK(_list.field_name, obj);
INT32_PEAK(_list.bytes_offset, obj);
QString provider_name, delegate_name;
STRING_PEAK(provider_name, obj);
STRING_PEAK(delegate_name, obj);
QJsonObject provider_obj, delegate_obj;
OBJECT_PEAK(provider_obj, obj);
OBJECT_PEAK(delegate_obj, obj);
auto ins_size = core->sizeProviderMap()[provider_name]->newDefault();
ins_size->loadFrom(core, provider_obj);
auto ins_delt = core->operator[](delegate_name)->newDefault();
ins_delt->loadFrom(core, delegate_obj);
_list.size_provider_inst = std::dynamic_pointer_cast<SizeProvider>(ins_size);
_list.delegate_inst = std::dynamic_pointer_cast<ExtractDelegate>(ins_delt);
}
void ListBasedUnit::saveTo(QJsonObject& obj) const
{
STRING_SAVE(_list.field_name, obj);
INT32_SAVE(_list.bytes_offset, obj);
auto provider_name = _list.size_provider_inst->name();
auto delegate_name = _list.delegate_inst->aliasName();
STRING_SAVE(provider_name, obj);
STRING_SAVE(delegate_name, obj);
QJsonObject provider_obj, delegate_obj;
_list.size_provider_inst->saveTo(provider_obj);
_list.delegate_inst->saveTo(delegate_obj);
OBJECT_SAVE(provider_obj, obj);
OBJECT_SAVE(delegate_obj, obj);
}
std::shared_ptr<Serializable> ListBasedUnit::newDefault() const
{
return std::make_shared<ListBasedUnit>();
}
QString ListBasedUnit::baseType() const
{
return NAME(ListBasedUnit);
}
std::shared_ptr<SizeProvider> ListBasedUnit::sizeProvider() const
{
return _list.size_provider_inst;
}
void ListBasedUnit::setSizeProvider(std::shared_ptr<SizeProvider> inst)
{
_list.size_provider_inst = inst;
}
void UnionBasedUnit::updateMatch(int index, std::shared_ptr<RuleMatch> rule)
{
auto nidx = std::min(std::max(0, index), _union.rulematch_list.size() - 1);
_union.rulematch_list.replace(nidx, rule);
}
QList<std::shared_ptr<RuleMatch>> UnionBasedUnit::matchRules() const
{
return _union.rulematch_list;
}
void UnionBasedUnit::clearRules()
{
_union.rulematch_list.clear();
}
QString UnionBasedUnit::baseType() const
{
return NAME(UnionBasedUnit);
}
QString UnionBasedUnit::name() const
{
return _union.alias_name;
}
void UnionBasedUnit::setName(const QString& name)
{
_union.alias_name = name;
}
bool UnionBasedUnit::setOffsetSpan(int bytes)
{
_union.bytes_offset = bytes;
return true;
}
int UnionBasedUnit::offsetSpan() const
{
return _union.bytes_offset;
}
void UnionBasedUnit::registSubField(std::shared_ptr<ScopeFieldsSetter> inst) {}
int UnionBasedUnit::countWithin() const
{
return _union.bytes_count;
}
void UnionBasedUnit::parse(const QByteArray& bytes, std::shared_ptr<DataContext> out) const
{
auto buffer = bytes.mid(_union.bytes_offset);
for (auto instr : _union.rulematch_list) {
if (instr->checkpass(buffer)) {
auto context = std::make_shared<ValueAccessContext>();
context->init(instr->getDelegate()->aliasName(), out);
instr->getDelegate()->parse(buffer, context);
if (instr->getDelegate()->countWithin() > _union.bytes_count)
throw new BaseException(u8"指定规则类型长度超过最大限值");
break;
}
}
}
void UnionBasedUnit::loadFrom(std::shared_ptr<TranslateBasic> core, const QJsonObject& obj)
{
INT32_PEAK(_union.bytes_offset, obj);
INT32_PEAK(_union.bytes_count, obj);
STRING_PEAK(_union.alias_name, obj);
QJsonArray array;
ARRAY_PEAK(array, obj);
_union.rulematch_list.clear();
for (auto index = 0; index < array.size(); ++index) {
auto rule_obj = array.at(index);
QString match_type;
STRING_PEAK(match_type, rule_obj);
auto ninst = core->ruleMatchMap()[match_type]->newDefault();
QJsonObject content_obj;
OBJECT_PEAK(content_obj, rule_obj);
ninst->loadFrom(core, content_obj);
_union.rulematch_list.append(std::dynamic_pointer_cast<RuleMatch>(ninst));
}
}
void UnionBasedUnit::saveTo(QJsonObject& obj) const
{
INT32_SAVE(_union.bytes_offset, obj);
INT32_SAVE(_union.bytes_count, obj);
STRING_SAVE(_union.alias_name, obj);
QJsonArray array;
for (auto instr : _union.rulematch_list) {
QJsonObject rule_obj;
auto match_type = instr->matchType();
STRING_SAVE(match_type, rule_obj);
QJsonObject content_obj;
instr->saveTo(content_obj);
OBJECT_SAVE(content_obj, rule_obj);
array.append(rule_obj);
}
ARRAY_SAVE(array, obj);
}
std::shared_ptr<Serializable> UnionBasedUnit::newDefault() const
{
return std::make_shared<UnionBasedUnit>();
}
void UnionBasedUnit::setCountWithin(int count)
{
_union.bytes_count = count;
}

View File

@ -65,12 +65,18 @@ public:
/// </summary>
class ExtractUnit : public ExtractStruct {
public:
/// <summary>
/// »ù´¡µ¥ÔªÀàÐÍ
/// </summary>
/// <returns></returns>
virtual QString baseType() const = 0;
/// <summary>
/// 字段名称
/// </summary>
/// <returns></returns>
virtual QString name() const = 0;
virtual void setName(const QString &name) = 0;
virtual void setName(const QString& name) = 0;
/// <summary>
/// 设置偏移字节数量
@ -82,17 +88,6 @@ public:
/// </summary>
/// <returns></returns>
virtual int offsetSpan() const = 0;
/// <summary>
/// ίÍÐʵÀý
/// </summary>
/// <returns></returns>
virtual std::shared_ptr<ExtractDelegate> delegateInst() const = 0;
/// <summary>
/// ÉèÖÃίÍÐʵÀý
/// </summary>
/// <param typeAlias="inst"></param>
virtual void setDelegate(std::shared_ptr<ExtractDelegate> inst) = 0;
};
@ -240,79 +235,13 @@ namespace extract {
std::shared_ptr<Serializable> newDefault() const override;
};
class AsList : public ExtractDelegate {
private:
struct __Private {
QString _alias_name = "";
int count_acculate = 0;
std::shared_ptr<ExtractUnit> _bind_unit = nullptr;
std::shared_ptr<SizeProvider> _bind_size_v = nullptr;
} _list;
public:
static QString topic();
std::shared_ptr<ExtractUnit> elementRule() const;
bool setElementRule(std::shared_ptr<ExtractUnit> u);
std::shared_ptr<SizeProvider> sizeProvider() const;
bool setSizeProvider(std::shared_ptr<SizeProvider> ins);
public:
QString unitType() const override;
int countWithin() const override;
DataType outType() const override;
QString aliasName() const override;
void setAlias(const QString& name) override;
void registSubField(std::shared_ptr<ScopeFieldsSetter> inst) override;
void parse(const QByteArray& bytes, std::shared_ptr<DataContext> out) const override;
std::shared_ptr<Serializable> newDefault() const override;
void loadFrom(std::shared_ptr<TranslateBasic> core, const QJsonObject& obj) override;
void saveTo(QJsonObject& obj) const override;
};
class AsUnion : public ExtractDelegate {
private:
struct __Private {
int byte_count = 1;
QString alias_name = "";
QList<std::shared_ptr<RuleMatch>> _rule_list;
} _union;
public:
static QString topic();
bool setCountWithin(int bytes);
void clearRules();
QList<std::shared_ptr<RuleMatch>> elementRules() const;
bool appendElementRule(std::shared_ptr<RuleMatch> u);
public:
QString unitType() const override;
void registSubField(std::shared_ptr<ScopeFieldsSetter> inst) override;
DataType outType() const override;
int countWithin() const override;
QString aliasName() const override;
void setAlias(const QString& name) override;
void parse(const QByteArray& bytes, std::shared_ptr<DataContext> out) const override;
void loadFrom(std::shared_ptr<TranslateBasic> core, const QJsonObject& obj) override;
void saveTo(QJsonObject& obj) const override;
std::shared_ptr<Serializable> newDefault() const override;
};
class AsRuleSet : public ExtractDelegate {
private:
struct __Private {
QString alias_name = "";
QList<std::shared_ptr<ExtractUnit>> sub_units;
int count_within_rt = 0;
}_bind;
public:
@ -354,24 +283,92 @@ namespace extract {
} _inst;
public:
std::shared_ptr<ExtractDelegate> delegateInst() const;
void setDelegate(std::shared_ptr<ExtractDelegate> inst);
public:
QString baseType() const;
QString name() const override;
void setName(const QString &name) override;
void setName(const QString& name) override;
bool setOffsetSpan(int bytes) override;
int offsetSpan() const override;
virtual int countWithin() const;
std::shared_ptr<ExtractDelegate> delegateInst() const override;
void setDelegate(std::shared_ptr<ExtractDelegate> inst) override;
void registSubField(std::shared_ptr<ScopeFieldsSetter> inst) override;
void parse(const QByteArray& bytes, std::shared_ptr<DataContext> out) const override;
void loadFrom(std::shared_ptr<TranslateBasic> core, const QJsonObject& obj) override;
void saveTo(QJsonObject& obj) const override;
std::shared_ptr<Serializable> newDefault() const override;
};
class ListBasedUnit : public ExtractUnit {
private:
struct __Private {
QString field_name = "";
int bytes_offset = 0;
std::shared_ptr<SizeProvider> size_provider_inst = nullptr;
std::shared_ptr<ExtractDelegate> delegate_inst = nullptr;
int count_with_runtime = 0;
} _list;
public:
void setSizeProvider(std::shared_ptr<SizeProvider> inst);
std::shared_ptr<SizeProvider> sizeProvider() const;
void setDelegate(std::shared_ptr<ExtractDelegate> inst);
std::shared_ptr<ExtractDelegate> delegateInst() const;
public:
QString baseType() const;
QString name() const override;
void setName(const QString& name) override;
void registSubField(std::shared_ptr<ScopeFieldsSetter> inst) override;
bool setOffsetSpan(int bytes) override;
int offsetSpan() const override;
int countWithin() const override;
void loadFrom(std::shared_ptr<TranslateBasic> core, const QJsonObject& obj) override;
void saveTo(QJsonObject& obj) const override;
void parse(const QByteArray& bytes, std::shared_ptr<DataContext> out) const override;
std::shared_ptr<Serializable> newDefault() const override;
};
class UnionBasedUnit : public ExtractUnit {
private:
struct __Private {
int bytes_offset = 0;
int bytes_count = 1;
QString alias_name = "";
QList<std::shared_ptr<RuleMatch>> rulematch_list;
} _union;
public:
void updateMatch(int index, std::shared_ptr<RuleMatch> rule);
QList<std::shared_ptr<RuleMatch>> matchRules() const;
void clearRules();
void setCountWithin(int count);
public:
QString baseType() const override;
void registSubField(std::shared_ptr<ScopeFieldsSetter> inst) override;
QString name() const override;
void setName(const QString& name) override;
bool setOffsetSpan(int bytes) override;
int offsetSpan() const override;
int countWithin() const override;
void loadFrom(std::shared_ptr<TranslateBasic> core, const QJsonObject& obj) override;
void saveTo(QJsonObject& obj) const override;
void parse(const QByteArray& bytes, std::shared_ptr<DataContext> out) const override;
std::shared_ptr<Serializable> newDefault() const override;
};
}