816 lines
18 KiB
C++
816 lines
18 KiB
C++
#include "extract_basic.h"
|
||
#include <QVariant>
|
||
|
||
using namespace extract;
|
||
|
||
|
||
AbstractExtractor::AbstractExtractor(const QString& typeAlias, DataType data)
|
||
{
|
||
_abs_data.typename_store = typeAlias;
|
||
_abs_data.type_store = data;
|
||
}
|
||
|
||
bool AbstractExtractor::setCountWithin(int bytes)
|
||
{
|
||
this->_abs_data.byte_count = bytes;
|
||
return true;
|
||
}
|
||
|
||
QString AbstractExtractor::unitType() const
|
||
{
|
||
return _abs_data.typename_store;
|
||
}
|
||
|
||
DataType AbstractExtractor::outType() const
|
||
{
|
||
return _abs_data.type_store;
|
||
}
|
||
|
||
int AbstractExtractor::countWithin() const
|
||
{
|
||
return this->_abs_data.byte_count;
|
||
}
|
||
|
||
void AbstractExtractor::loadFrom(
|
||
std::shared_ptr<TranslateBasic> core, const QJsonObject& obj)
|
||
{
|
||
STRING_PEAK(_abs_data.name_alias, obj);
|
||
INT32_PEAK(_abs_data.byte_count, obj);
|
||
}
|
||
|
||
void AbstractExtractor::saveTo(QJsonObject& obj) const
|
||
{
|
||
STRING_SAVE(_abs_data.name_alias, obj);
|
||
INT32_SAVE(_abs_data.byte_count, obj);
|
||
}
|
||
|
||
void AbstractExtractor::registSubField(std::shared_ptr<ScopeFieldsSetter> inst) const {}
|
||
|
||
QString AbstractExtractor::aliasName() const
|
||
{
|
||
return _abs_data.name_alias;
|
||
}
|
||
|
||
void AbstractExtractor::setAlias(const QString& name)
|
||
{
|
||
_abs_data.name_alias = name;
|
||
}
|
||
|
||
AsHex::AsHex() : AbstractExtractor(topic(), DataType::TextString) {
|
||
setCountWithin(1);
|
||
}
|
||
|
||
#include "TranslateBasic.h"
|
||
void AsHex::parse(const QByteArray& bytes, std::shared_ptr<DataContext> out) const
|
||
{
|
||
QString result;
|
||
for (auto char_v : bytes) {
|
||
result += QString("%1").arg(char_v, 2, 16, QChar('0'));
|
||
}
|
||
out->append(result);
|
||
}
|
||
|
||
std::shared_ptr<Serializable> AsHex::newDefault() const
|
||
{
|
||
return std::make_shared<AsHex>();
|
||
}
|
||
|
||
QString AsHex::topic()
|
||
{
|
||
return NAME(AsHex);
|
||
}
|
||
|
||
AsBitCombine::AsBitCombine()
|
||
: AbstractExtractor(topic(), DataType::TextString)
|
||
{
|
||
|
||
}
|
||
|
||
bool AsBitCombine::setSwitchOption(int bit_index, const QString& keyword)
|
||
{
|
||
if (bit_index >= 0 && bit_index <= this->countWithin() * 8) {
|
||
_combine._switch_options[bit_index] = keyword;
|
||
return true;
|
||
}
|
||
return false;
|
||
}
|
||
|
||
QHash<int, QString> AsBitCombine::switchOptions() const
|
||
{
|
||
return _combine._switch_options;
|
||
}
|
||
|
||
void AsBitCombine::clearOptions()
|
||
{
|
||
_combine._switch_options.clear();
|
||
}
|
||
|
||
void AsBitCombine::parse(const QByteArray& bytes, std::shared_ptr<DataContext> out) const
|
||
{
|
||
auto keys = _combine._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(_combine._switch_options[idx], "Y");
|
||
else
|
||
result += QString("%1<%2>;").arg(_combine._switch_options[idx], "N");
|
||
}
|
||
out->append(result);
|
||
}
|
||
|
||
#include <QJsonArray>
|
||
void AsBitCombine::loadFrom(
|
||
std::shared_ptr<TranslateBasic> core, const QJsonObject& obj)
|
||
{
|
||
AbstractExtractor::loadFrom(core, obj);
|
||
|
||
_combine._switch_options.clear();
|
||
QJsonArray arr;
|
||
ARRAY_PEAK(arr, obj);
|
||
for (auto index = 0; index < arr.size(); ++index) {
|
||
auto switch_obj = arr.at(index);
|
||
auto key = switch_obj["index"].toInt();
|
||
auto content = switch_obj["content"].toString();
|
||
_combine._switch_options[key] = content;
|
||
}
|
||
}
|
||
|
||
void AsBitCombine::saveTo(QJsonObject& obj) const
|
||
{
|
||
AbstractExtractor::saveTo(obj);
|
||
|
||
QJsonArray arr;
|
||
for (auto key : _combine._switch_options.keys()) {
|
||
QJsonObject switch_obj;
|
||
switch_obj["index"] = key;
|
||
switch_obj["content"] = _combine._switch_options[key];
|
||
arr.append(switch_obj);
|
||
}
|
||
ARRAY_SAVE(arr, obj);
|
||
}
|
||
|
||
std::shared_ptr<Serializable> AsBitCombine::newDefault() const
|
||
{
|
||
return std::make_shared<AsBitCombine>();
|
||
}
|
||
|
||
QString AsBitCombine::topic()
|
||
{
|
||
return NAME(AsBitCombine);
|
||
}
|
||
|
||
std::shared_ptr<Serializable> AsInteger::newDefault() const
|
||
{
|
||
return std::make_shared<AsInteger>();
|
||
}
|
||
|
||
AsInteger::AsInteger() :AbstractExtractor(topic(), DataType::Integer) {
|
||
}
|
||
|
||
bool AsInteger::setCountWithin(int bytes)
|
||
{
|
||
bytes = std::min(8, std::max(bytes, 0));
|
||
return AbstractExtractor::setCountWithin(bytes);
|
||
}
|
||
|
||
void AsInteger::parse(const QByteArray& bytes, std::shared_ptr<DataContext> out) const
|
||
{
|
||
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(), static_cast<char>(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;
|
||
}
|
||
|
||
out->append(*((long long*)(&value)));
|
||
}
|
||
|
||
QString AsInteger::topic()
|
||
{
|
||
return NAME(AsInteger);
|
||
}
|
||
|
||
#include <QTextCodec>
|
||
|
||
AsString::AsString()
|
||
:AbstractExtractor(topic(), DataType::TextString) {
|
||
_strings._conv_with = QTextCodec::codecForName("GBK");
|
||
}
|
||
|
||
void AsString::setStrCodec(QTextCodec* ins)
|
||
{
|
||
this->_strings._conv_with = ins;
|
||
}
|
||
|
||
QString AsString::codecName() const
|
||
{
|
||
return this->_strings._conv_with->name();
|
||
}
|
||
|
||
void AsString::parse(const QByteArray& bytes, std::shared_ptr<DataContext> out) const
|
||
{
|
||
auto v = _strings._conv_with->toUnicode(bytes);
|
||
out->append(v);
|
||
}
|
||
|
||
void AsString::loadFrom(std::shared_ptr<TranslateBasic> core, const QJsonObject& obj)
|
||
{
|
||
AbstractExtractor::loadFrom(core, obj);
|
||
|
||
QString codec_name;
|
||
STRING_PEAK(codec_name, obj);
|
||
this->_strings._conv_with = QTextCodec::codecForName(codec_name.toLatin1());
|
||
}
|
||
|
||
void AsString::saveTo(QJsonObject& obj) const
|
||
{
|
||
AbstractExtractor::saveTo(obj);
|
||
|
||
auto codec_name = this->codecName();
|
||
STRING_SAVE(codec_name, obj);
|
||
}
|
||
|
||
std::shared_ptr<Serializable> AsString::newDefault() const
|
||
{
|
||
return std::make_shared<AsString>();
|
||
}
|
||
|
||
QString AsString::topic()
|
||
{
|
||
return NAME(AsString);
|
||
}
|
||
|
||
void AsFloat::parse(const QByteArray& bytes, std::shared_ptr<DataContext> out) const
|
||
{
|
||
out->append(*((float*)bytes.data()));
|
||
}
|
||
|
||
std::shared_ptr<Serializable> AsFloat::newDefault() const
|
||
{
|
||
return std::make_shared<AsFloat>();
|
||
}
|
||
|
||
AsFloat::AsFloat()
|
||
:AbstractExtractor(topic(), DataType::Flt32)
|
||
{
|
||
this->setCountWithin(4);
|
||
}
|
||
|
||
QString AsFloat::topic()
|
||
{
|
||
return NAME(AsFloat);
|
||
}
|
||
|
||
std::shared_ptr<Serializable> AsDouble::newDefault() const
|
||
{
|
||
return std::make_shared<AsDouble>();
|
||
}
|
||
|
||
void AsDouble::parse(const QByteArray& bytes, std::shared_ptr<DataContext> out) const
|
||
{
|
||
out->append(*((double*)bytes.data()));
|
||
}
|
||
|
||
AsDouble::AsDouble()
|
||
:AbstractExtractor(topic(), DataType::Dbl64)
|
||
{
|
||
this->setCountWithin(8);
|
||
}
|
||
|
||
QString AsDouble::topic()
|
||
{
|
||
return NAME(AsDouble);
|
||
}
|
||
|
||
AsUnsigned::AsUnsigned()
|
||
:AbstractExtractor(topic(), DataType::Unsigned)
|
||
{
|
||
|
||
}
|
||
|
||
bool AsUnsigned::setCountWithin(int bytes)
|
||
{
|
||
auto count = std::max(1, std::min(8, bytes));
|
||
return AbstractExtractor::setCountWithin(count);
|
||
}
|
||
|
||
void AsUnsigned::parse(const QByteArray& bytes, std::shared_ptr<DataContext> out) const
|
||
{
|
||
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;
|
||
}
|
||
out->append(value);
|
||
}
|
||
|
||
std::shared_ptr<Serializable> AsUnsigned::newDefault() const
|
||
{
|
||
return std::make_shared<AsUnsigned>();
|
||
}
|
||
|
||
QString AsUnsigned::topic()
|
||
{
|
||
return NAME(AsUnsigned);
|
||
}
|
||
|
||
#include <stdexcept>
|
||
void AsRuleSet::registSubField(std::shared_ptr<ScopeFieldsSetter> inst) const
|
||
{
|
||
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 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;
|
||
}
|
||
}
|
||
|
||
QString AsRuleSet::unitType() const
|
||
{
|
||
return topic();
|
||
}
|
||
|
||
DataType AsRuleSet::outType() const
|
||
{
|
||
return DataType::COMPLEX_RULESET;
|
||
}
|
||
|
||
int AsRuleSet::countWithin() const
|
||
{
|
||
return _bind.count_within_rt;
|
||
}
|
||
|
||
void AsRuleSet::loadFrom(std::shared_ptr<TranslateBasic> core, const QJsonObject& obj)
|
||
{
|
||
STRING_PEAK(_bind.alias_name, obj);
|
||
|
||
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 unit_type, field_name;
|
||
|
||
STRING_PEAK(field_name, rule_obj);
|
||
STRING_PEAK(unit_type, rule_obj);
|
||
|
||
QJsonObject match_obj;
|
||
OBJECT_PEAK(match_obj, rule_obj);
|
||
|
||
auto xdev = core->extractUnitTypeMap()[unit_type]->newDefault();
|
||
xdev->loadFrom(core, match_obj);
|
||
_bind.sub_units << std::dynamic_pointer_cast<ExtractUnit>(xdev);
|
||
}
|
||
}
|
||
|
||
void AsRuleSet::saveTo(QJsonObject& obj) const
|
||
{
|
||
STRING_SAVE(_bind.alias_name, obj);
|
||
|
||
QJsonArray array;
|
||
for (auto pairk : _bind.sub_units) {
|
||
QJsonObject rule_obj, match_obj;
|
||
|
||
auto field_name = pairk->name();
|
||
STRING_SAVE(field_name, rule_obj);
|
||
auto unit_type = pairk->baseType();
|
||
STRING_SAVE(unit_type, rule_obj);
|
||
pairk->saveTo(match_obj);
|
||
OBJECT_SAVE(match_obj, rule_obj);
|
||
|
||
array.append(rule_obj);
|
||
}
|
||
ARRAY_SAVE(array, obj);
|
||
}
|
||
|
||
std::shared_ptr<Serializable> AsRuleSet::newDefault() const
|
||
{
|
||
return std::make_shared<AsRuleSet>();
|
||
}
|
||
|
||
std::shared_ptr<ExtractUnit> AsRuleSet::operator[](int index) const
|
||
{
|
||
return this->_bind.sub_units[index];
|
||
}
|
||
|
||
void AsRuleSet::replace(int index, std::shared_ptr<ExtractUnit> inst)
|
||
{
|
||
this->_bind.sub_units.replace(index, inst);
|
||
}
|
||
|
||
extract::AsRuleSet& AsRuleSet::append(std::shared_ptr<ExtractUnit> u)
|
||
{
|
||
this->_bind.sub_units.append(u);
|
||
return *this;
|
||
}
|
||
|
||
void AsRuleSet::removeAt(int index)
|
||
{
|
||
this->_bind.sub_units.removeAt(index);
|
||
}
|
||
|
||
QList<QString> AsRuleSet::fieldNames() const
|
||
{
|
||
QList<QString> fields_store;
|
||
for (auto fins : this->_bind.sub_units) {
|
||
fields_store << fins->name();
|
||
}
|
||
return fields_store;;
|
||
}
|
||
|
||
std::shared_ptr<ExtractUnit> AsRuleSet::operator[](const QString& field) const
|
||
{
|
||
for (auto pair : this->_bind.sub_units) {
|
||
if (pair->name() == field)
|
||
return pair;
|
||
}
|
||
|
||
return std::shared_ptr<ExtractUnit>();
|
||
}
|
||
|
||
void AsRuleSet::setAlias(const QString& typeAlias)
|
||
{
|
||
_bind.alias_name = typeAlias;
|
||
}
|
||
|
||
QString AsRuleSet::aliasName() const
|
||
{
|
||
return _bind.alias_name;
|
||
}
|
||
|
||
int AsRuleSet::memberCount() const
|
||
{
|
||
return _bind.sub_units.size();
|
||
}
|
||
|
||
QString AsRuleSet::topic()
|
||
{
|
||
return NAME(AsRuleSet);
|
||
}
|
||
|
||
QString SingleBasedUnit::name() const
|
||
{
|
||
return _inst._field_name;
|
||
}
|
||
|
||
bool SingleBasedUnit::setOffsetSpan(int bytes)
|
||
{
|
||
_inst._bytes_offset = bytes;
|
||
return true;
|
||
}
|
||
|
||
int SingleBasedUnit::offsetSpan() const
|
||
{
|
||
return _inst._bytes_offset;
|
||
}
|
||
|
||
std::shared_ptr<ExtractDelegate> SingleBasedUnit::delegateInst() const
|
||
{
|
||
return _inst._delegate_inst;
|
||
}
|
||
|
||
void SingleBasedUnit::setDelegate(std::shared_ptr<ExtractDelegate> inst)
|
||
{
|
||
_inst._delegate_inst = inst;
|
||
}
|
||
|
||
void SingleBasedUnit::registSubField(std::shared_ptr<ScopeFieldsSetter> inst) const
|
||
{
|
||
inst->setField(name(), _inst._delegate_inst->outType());
|
||
|
||
auto nlayer = std::make_shared<FieldManagerLayer>(name(), inst);
|
||
_inst._delegate_inst->registSubField(nlayer);
|
||
}
|
||
|
||
void SingleBasedUnit::parse(const QByteArray& bytes, std::shared_ptr<DataContext> out) const
|
||
{
|
||
auto context = std::make_shared<ValueAccessContext>();
|
||
context->init(name(), out);
|
||
|
||
auto bytes_sec = bytes.mid(this->offsetSpan());
|
||
_inst._delegate_inst->parse(bytes_sec, context);
|
||
}
|
||
|
||
void SingleBasedUnit::loadFrom(std::shared_ptr<TranslateBasic> core, const QJsonObject& obj)
|
||
{
|
||
QJsonObject field_obj;
|
||
OBJECT_PEAK(field_obj, obj);
|
||
STRING_PEAK(_inst._field_name, field_obj);
|
||
INT32_PEAK(_inst._bytes_offset, field_obj);
|
||
|
||
QString delegate_alias;
|
||
STRING_PEAK(delegate_alias, obj);
|
||
auto vcopy = core->operator[](delegate_alias)->newDefault();
|
||
_inst._delegate_inst = std::dynamic_pointer_cast<ExtractDelegate>(vcopy);
|
||
|
||
QJsonObject data_obj;
|
||
OBJECT_PEAK(data_obj, field_obj);
|
||
_inst._delegate_inst->loadFrom(core, data_obj);
|
||
}
|
||
|
||
void SingleBasedUnit::saveTo(QJsonObject& obj) const
|
||
{
|
||
QJsonObject field_obj;
|
||
STRING_SAVE(_inst._field_name, field_obj);
|
||
INT32_SAVE(_inst._bytes_offset, field_obj);
|
||
auto delegate_alias = _inst._delegate_inst->aliasName();
|
||
STRING_SAVE(delegate_alias, obj);
|
||
|
||
QJsonObject data_obj;
|
||
_inst._delegate_inst->saveTo(data_obj);
|
||
OBJECT_SAVE(data_obj, field_obj);
|
||
|
||
OBJECT_SAVE(field_obj, obj);
|
||
}
|
||
|
||
std::shared_ptr<Serializable> SingleBasedUnit::newDefault() const
|
||
{
|
||
return std::make_shared<SingleBasedUnit>();
|
||
}
|
||
|
||
void SingleBasedUnit::setName(const QString& name)
|
||
{
|
||
_inst._field_name = name;
|
||
}
|
||
|
||
int SingleBasedUnit::countWithin() const
|
||
{
|
||
return _inst._delegate_inst->countWithin() + offsetSpan();
|
||
}
|
||
|
||
QString SingleBasedUnit::baseType() const
|
||
{
|
||
return topic();
|
||
}
|
||
|
||
QString SingleBasedUnit::topic()
|
||
{
|
||
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) const {}
|
||
|
||
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->sizeProviderTypeMap()[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 topic();
|
||
}
|
||
|
||
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;
|
||
}
|
||
|
||
QString ListBasedUnit::topic()
|
||
{
|
||
return NAME(ListBasedUnit);
|
||
}
|
||
|
||
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 topic();
|
||
}
|
||
|
||
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) const {}
|
||
|
||
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"ָ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͳ<EFBFBD><EFBFBD>ȳ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ");
|
||
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->ruleMatchTypeMap()[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;
|
||
}
|
||
|
||
QString UnionBasedUnit::topic()
|
||
{
|
||
return NAME(UnionBasedUnit);
|
||
}
|