为灵活性做改造

This commit is contained in:
codeboss 2025-08-02 10:04:30 +08:00
parent 4503ee0d88
commit 0e68e0c66e
8 changed files with 229 additions and 140 deletions

View File

@ -192,7 +192,7 @@ std::shared_ptr<ExtractUnit> TranslateBasic::defaultRule() const
return _default_translate_rule;
}
std::shared_ptr<extract::SizeProvider> TranslateBasic::defaultSizeProvider() const
std::shared_ptr<SizeProvider> TranslateBasic::defaultSizeProvider() const
{
return _default_size_provider;
}
@ -202,7 +202,7 @@ QHash<QString, std::shared_ptr<ExtractUnit>> TranslateBasic::extactors() const
return _extractor_types;
}
QHash<QString, std::shared_ptr<extract::SizeProvider>> TranslateBasic::sizeProviders() const
QHash<QString, std::shared_ptr<SizeProvider>> TranslateBasic::sizeProviders() const
{
return _size_provider_types;
}

View File

@ -9,24 +9,6 @@
#include "TranslateBasic.h"
/// <summary>
/// ·­Òë³ÌÐòºËÐÄ
/// </summary>
class TranslateBasic {
private:
QHash<QString, std::shared_ptr<ExtractUnit>> _extractor_types;
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;
};
/// <summary>
@ -70,7 +52,7 @@ public:
virtual void updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index) const override;
};
class ConstNumberProvider : public extract::SizeProvider {
class ConstNumberProvider : public SizeProvider {
private:
QString _number_value;

View File

@ -2,3 +2,23 @@
#include "extract_basic.h"
#include "convert_basic.h"
/// <summary>
/// ·­Òë³ÌÐòºËÐÄ
/// </summary>
class TranslateBasic {
private:
QHash<QString, std::shared_ptr<ExtractUnit>> _extractor_types;
std::shared_ptr<ExtractUnit> _default_translate_rule = nullptr;
QHash<QString, std::shared_ptr<SizeProvider>> _size_provider_types;
std::shared_ptr<SizeProvider> _default_size_provider = nullptr;
public:
TranslateBasic();
std::shared_ptr<ExtractUnit> defaultRule() const;
std::shared_ptr<SizeProvider> defaultSizeProvider() const;
QHash<QString, std::shared_ptr<ExtractUnit>> extactors() const;
QHash<QString, std::shared_ptr<SizeProvider>> sizeProviders() const;
};

View File

@ -3,6 +3,14 @@
#include <QJsonObject>
#include <memory>
#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(";");
#define STRING_PEAK(codec_name) codec_name = obj[NAME(codec_name)].toString();
#define STRING_SAVE(codec_name) obj[NAME(codec_name)] = codec_name;
/// <summary>
/// 序列化实体
/// </summary>

View File

@ -6,12 +6,12 @@ using namespace convert;
AbstractValueConvert::AbstractValueConvert(const QString& nm, DataType in, DataType out)
: _name_store(nm), _in_type(in), _out_type(out) {
: name_store(nm), _in_type(in), _out_type(out) {
}
QString AbstractValueConvert::name() const
{
return _name_store;
return name_store;
}
DataType AbstractValueConvert::inType() const

View File

@ -18,7 +18,7 @@ public:
namespace convert {
class AbstractValueConvert : public ValueConvert {
private:
QString _name_store;
QString name_store;
DataType _in_type, _out_type;
public:

View File

@ -5,55 +5,58 @@ using namespace extract;
AbstractExtractor::AbstractExtractor(const QString& name, DataType data)
:_name_store(name), _type_store(data), _byte_offset(0), _byte_count(1) {
{
_abs_data.name_store = name;
_abs_data.type_store = data;
}
bool AbstractExtractor::setOffsetSpan(int bytes)
{
this->_byte_offset = bytes;
this->_abs_data.byte_offset = bytes;
return true;
}
bool AbstractExtractor::setCountWithin(int bytes)
{
this->_byte_count = bytes;
this->_abs_data.byte_count = bytes;
return true;
}
QString AbstractExtractor::name() const
{
return _name_store;
return _abs_data.name_store;
}
DataType AbstractExtractor::outType() const
{
return _type_store;
return _abs_data.type_store;
}
int AbstractExtractor::offsetSpan() const
{
return _byte_offset;
return _abs_data.byte_offset;
}
int AbstractExtractor::countWithin() const
{
return this->_byte_count;
return this->_abs_data.byte_count;
}
void AbstractExtractor::loadFrom(const QJsonObject& obj)
{
INT32_PEAK(_byte_offset);
INT32_PEAK(_byte_count);
INT32_PEAK(_abs_data.byte_offset);
INT32_PEAK(_abs_data.byte_count);
}
void AbstractExtractor::saveTo(QJsonObject& obj) const
{
INT32_SAVE(_byte_offset);
INT32_SAVE(_byte_count);
INT32_SAVE(_abs_data.byte_offset);
INT32_SAVE(_abs_data.byte_count);
}
BytesAsHex::BytesAsHex()
: AbstractExtractor(NAME(BytesAsHex), DataType::TextString) {
setCountWithin(1);
}
QVariant BytesAsHex::parse(const QByteArray& bytes) const
@ -79,7 +82,7 @@ BytesAsBitCombine::BytesAsBitCombine()
bool BytesAsBitCombine::setSwitchOption(int bit_index, const QString& keyword)
{
if (bit_index >= 0 && bit_index <= this->countWithin() * 8) {
_switch_options[bit_index] = keyword;
_combines._switch_options[bit_index] = keyword;
return true;
}
return false;
@ -87,17 +90,17 @@ bool BytesAsBitCombine::setSwitchOption(int bit_index, const QString& keyword)
QHash<int, QString> BytesAsBitCombine::switchOptions() const
{
return _switch_options;
return _combines._switch_options;
}
void BytesAsBitCombine::clearOptions()
{
_switch_options.clear();
_combines._switch_options.clear();
}
QVariant BytesAsBitCombine::parse(const QByteArray& bytes) const
{
auto keys = _switch_options.keys();
auto keys = _combines._switch_options.keys();
std::sort(keys.begin(), keys.end());
QString result;
@ -106,9 +109,9 @@ QVariant BytesAsBitCombine::parse(const QByteArray& bytes) const
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");
result += QString("%1<%2>;").arg(_combines._switch_options[idx], "Y");
else
result += QString("%1<%2>;").arg(_switch_options[idx], "N");
result += QString("%1<%2>;").arg(_combines._switch_options[idx], "N");
}
return result;
}
@ -119,10 +122,10 @@ void BytesAsBitCombine::loadFrom(const QJsonObject& obj)
QStringList value_list;
STRLIST_PEAK(value_list);
_switch_options.clear();
_combines._switch_options.clear();
for (auto pair : value_list) {
auto items = pair.split("=");
_switch_options[items.first().toInt()] = items.last();
_combines._switch_options[items.first().toInt()] = items.last();
}
}
@ -131,8 +134,9 @@ void BytesAsBitCombine::saveTo(QJsonObject& obj) const
AbstractExtractor::saveTo(obj);
QStringList value_list;
for (auto key : _switch_options.keys()) {
auto pair_str = QString("%1=%2").arg(key).arg(_switch_options[key]);
for (auto key : _combines._switch_options.keys()) {
auto pair_str = QString("%1=%2").arg(key)
.arg(_combines._switch_options[key]);
value_list << pair_str;
}
STRLIST_SAVE(value_list);
@ -168,7 +172,7 @@ QVariant BytesAsInteger::parse(const QByteArray& bytes) const
xbuffer.append(8 - bytes.size(), 0);
}
else {
xbuffer.append(8 - bytes.size(), 0xff);
xbuffer.append(8 - bytes.size(), static_cast<char>(0xff));
}
unsigned long long value = 0;
@ -185,22 +189,22 @@ QVariant BytesAsInteger::parse(const QByteArray& bytes) const
BytesAsString::BytesAsString()
:AbstractExtractor(NAME(BytesAsString), DataType::TextString) {
_conv_with = QTextCodec::codecForName("GBK");
_strings._conv_with = QTextCodec::codecForName("GBK");
}
void BytesAsString::setStrCodec(QTextCodec* ins)
{
this->_conv_with = ins;
this->_strings._conv_with = ins;
}
QString BytesAsString::codecName() const
{
return this->_conv_with->name();
return this->_strings._conv_with->name();
}
QVariant BytesAsString::parse(const QByteArray& bytes) const
{
return _conv_with->toUnicode(bytes);
return _strings._conv_with->toUnicode(bytes);
}
void BytesAsString::loadFrom(const QJsonObject& obj)
@ -209,7 +213,7 @@ void BytesAsString::loadFrom(const QJsonObject& obj)
QString codec_name;
STRING_PEAK(codec_name);
this->_conv_with = QTextCodec::codecForName(codec_name.toLatin1());
this->_strings._conv_with = QTextCodec::codecForName(codec_name.toLatin1());
}
void BytesAsString::saveTo(QJsonObject& obj) const
@ -287,47 +291,31 @@ std::shared_ptr<Serializable> BytesAsUnsigned::newDefault() const
#include <stdexcept>
bool BytesAsUnion::setSizeProvider(std::shared_ptr<SizeProvider> ins)
{
this->_provider_ins = ins;
return true;
}
QVariant BytesAsUnion::parse(const QByteArray& bytes) const
{
throw std::logic_error("The method or operation is not implemented.");
}
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;
this->_list._bytes_offset = value;
return true;
}
std::shared_ptr<ExtractUnit> BytesAsList::elementRule() const
{
return this->_bind_unit;
return this->_list._bind_unit;
}
bool BytesAsList::setElementRule(std::shared_ptr<ExtractUnit> u)
{
this->_bind_unit = u;
this->_list._bind_unit = u;
return true;
}
std::shared_ptr<extract::SizeProvider> BytesAsList::sizeProvider() const
std::shared_ptr<SizeProvider> BytesAsList::sizeProvider() const
{
return this->_bind_size_v;
return this->_list._bind_size_v;
}
bool BytesAsList::setSizeProvider(std::shared_ptr<SizeProvider> ins)
{
this->_bind_size_v = ins;
this->_list._bind_size_v = ins;
return true;
}
@ -343,43 +331,44 @@ DataType BytesAsList::outType() const
int BytesAsList::offsetSpan() const
{
return _bytes_offset;
return _list._bytes_offset;
}
int BytesAsList::countWithin() const
{
auto expr = this->_bind_size_v->expression();
if (this->_bind_size_v->value(expr) < 0) {
auto expr = this->_list._bind_size_v->expression();
if (this->_list._bind_size_v->value(expr) < 0) {
return 0;
}
return this->_bind_size_v->value(expr) * this->_bind_unit->countWithin();
return this->_list._bind_size_v->value(expr)
* this->_list._bind_unit->countWithin();
}
void BytesAsList::loadFrom(const QJsonObject& obj)
{
INT32_PEAK(_bytes_offset);
INT32_PEAK(_list._bytes_offset);
QString bind_provider_expr = "";
STRING_SAVE(bind_provider_expr);
if (this->_bind_size_v)
this->_bind_size_v->setExpression(bind_provider_expr);
if (this->_list._bind_size_v)
this->_list._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();
if (this->_list._bind_unit)
bind_unit_name = this->_list._bind_unit->name();
STRING_SAVE(bind_unit_name);
INT32_SAVE(_bytes_offset);
INT32_SAVE(_list._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();
if (this->_list._bind_size_v) {
bind_provider_expr = this->_list._bind_size_v->expression();
bind_size_provider_name = this->_list._bind_size_v->name();
}
STRING_SAVE(bind_size_provider_name);
STRING_SAVE(bind_provider_expr);
@ -389,13 +378,13 @@ 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();
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->_bind_unit->parse(secn);
auto value_v = this->_list._bind_unit->parse(secn);
value_list << value_v;
}
@ -406,3 +395,76 @@ std::shared_ptr<Serializable> BytesAsList::newDefault() const
{
return std::make_shared<BytesAsList>();
}
QString BytesAsUnion::name() const
{
return NAME(BytesAsUnion);
}
DataType BytesAsUnion::outType() const
{
return DataType::UNION_COMBINATE;
}
int BytesAsUnion::offsetSpan() const
{
return _union.byte_offset;
}
int BytesAsUnion::countWithin() const
{
return _union.byte_count;
}
QVariant BytesAsUnion::parse(const QByteArray& bytes) const
{
for (auto u : this->elementRules())
if (u->checkpass(bytes))
return u->bindRule()->parse(bytes);
return QVariant();
}
void BytesAsUnion::loadFrom(const QJsonObject& obj)
{
throw std::logic_error("The method or operation is not implemented.");
}
void BytesAsUnion::saveTo(QJsonObject& obj) const
{
INT32_SAVE(_union.byte_count);
INT32_SAVE(_union.byte_offset);
}
std::shared_ptr<Serializable> BytesAsUnion::newDefault() const
{
return std::make_shared<BytesAsUnion>();
}
QList<std::shared_ptr<RuleMatch>> BytesAsUnion::elementRules() const
{
return _union._rule_list;
}
bool BytesAsUnion::setElementRule(std::shared_ptr<RuleMatch> u)
{
this->_union._rule_list << u;
return true;
}
void BytesAsUnion::clearRules()
{
this->_union._rule_list.clear();
}
bool BytesAsUnion::setCountWithin(int bytes)
{
this->_union.byte_count = bytes;
return true;
}
bool BytesAsUnion::setOffsetSpan(int value)
{
this->_union.byte_offset = value;
return true;
}

View File

@ -3,7 +3,6 @@
#include "common.h"
#include <QHash>
/// <summary>
/// 翻译单元抽象接口
/// </summary>
@ -46,14 +45,42 @@ public:
virtual QVariant parse(const QByteArray& bytes) const = 0;
};
/// <summary>
/// 尺寸解析器
/// </summary>
class SizeProvider {
public:
virtual QString name() const = 0;
/// <summary>
/// 获取值,如果该值无法预先计算得知,返回-1
/// </summary>
/// <returns>尺寸值</returns>
virtual int32_t value(const QString& expr) const = 0;
virtual void setExpression(const QString& expr) = 0;
virtual QString expression() const = 0;
};
/// <summary>
/// 规则匹配器
/// </summary>
class RuleMatch {
public:
virtual QString name() const = 0;
virtual std::shared_ptr<ExtractUnit> bindRule() const = 0;
virtual bool checkpass(const QByteArray& buffer) const = 0;
};
namespace extract {
class AbstractExtractor : public ExtractUnit {
private:
QString _name_store;
DataType _type_store;
int _byte_offset, _byte_count;
public:
struct __Private {
QString name_store = "";
DataType type_store = DataType::Integer;
int byte_offset = 0, byte_count = 1;
} _abs_data;
AbstractExtractor(const QString& name, DataType data);
virtual bool setCountWithin(int bytes);
@ -73,14 +100,6 @@ namespace extract {
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(";");
#define STRING_PEAK(codec_name) codec_name = obj[NAME(codec_name)].toString();
#define STRING_SAVE(codec_name) obj[NAME(codec_name)] = codec_name;
/// <summary>
/// 转换源数值未16进制数值默认分割方式
/// </summary>
@ -96,10 +115,11 @@ namespace extract {
/// 转换源数值为位联合
/// </summary>
class BytesAsBitCombine : public AbstractExtractor {
private:
QHash<int, QString> _switch_options;
public:
struct __Private {
QHash<int, QString> _switch_options;
} _combines;
BytesAsBitCombine();
bool setSwitchOption(int bit_index, const QString& keyword);
@ -129,6 +149,7 @@ namespace extract {
// Serializable ==============================
std::shared_ptr<Serializable> newDefault() const override;
};
/// <summary>
/// 转换源数据为整形
/// </summary>
@ -148,8 +169,10 @@ namespace extract {
/// 转换源数据为字符串
/// </summary>
class BytesAsString : public AbstractExtractor {
private:
public:
struct __Private {
QTextCodec* _conv_with = nullptr;
} _strings;
public:
BytesAsString();
@ -182,28 +205,14 @@ namespace extract {
std::shared_ptr<Serializable> newDefault() const override;
};
/// <summary>
/// 尺寸解析器
/// </summary>
class SizeProvider {
public:
virtual QString name() const = 0;
/// <summary>
/// 获取值,如果该值无法预先计算得知,返回-1
/// </summary>
/// <returns>尺寸值</returns>
virtual int32_t value(const QString& expr) const = 0;
virtual void setExpression(const QString& expr) = 0;
virtual QString expression() const = 0;
};
class BytesAsList : public ExtractUnit {
private:
public:
struct __Private {
std::shared_ptr<ExtractUnit> _bind_unit = nullptr;
int _bytes_offset = 0;
std::shared_ptr<SizeProvider> _bind_size_v = nullptr;
} _list;
public:
bool setOffsetSpan(int value);
@ -213,7 +222,6 @@ namespace extract {
bool setSizeProvider(std::shared_ptr<SizeProvider> ins);
public:
QString name() const override;
DataType outType() const override;
int offsetSpan() const override;
@ -227,22 +235,31 @@ namespace extract {
};
class RuleMatch {
class BytesAsUnion : public ExtractUnit {
public:
virtual std::shared_ptr<ExtractUnit> bindRule() const = 0;
virtual bool checkpass() const = 0;
};
class BytesAsUnion : public AbstractExtractor {
protected:
std::shared_ptr<SizeProvider> _provider_ins = nullptr;
struct __Private {
int byte_offset, byte_count;
QList<std::shared_ptr<RuleMatch>> _rule_list;
} _union;
public:
bool setSizeProvider(std::shared_ptr<SizeProvider> ins);
bool setCountWithin(int bytes);
void clearRules();
QList<std::shared_ptr<RuleMatch>> elementRules() const;
bool setElementRule(std::shared_ptr<RuleMatch> u);
public:
QString name() const 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 loadFrom(const QJsonObject& obj) override;
void saveTo(QJsonObject& obj) const override;
std::shared_ptr<Serializable> newDefault() const override;
};