#include "extract_basic.h" #include using namespace extract; AbstractExtractor::AbstractExtractor(const QString& name, DataType data) { _abs_data.name_store = name; _abs_data.type_store = data; } bool AbstractExtractor::setOffsetSpan(int bytes) { this->_abs_data.byte_offset = bytes; return true; } bool AbstractExtractor::setCountWithin(int bytes) { this->_abs_data.byte_count = bytes; return true; } QString AbstractExtractor::name() const { return _abs_data.name_store; } DataType AbstractExtractor::outType() const { return _abs_data.type_store; } int AbstractExtractor::offsetSpan() const { return _abs_data.byte_offset; } int AbstractExtractor::countWithin() const { return this->_abs_data.byte_count; } void AbstractExtractor::loadFrom(const QJsonObject& obj) { INT32_PEAK(_abs_data.byte_offset); INT32_PEAK(_abs_data.byte_count); } void AbstractExtractor::saveTo(QJsonObject& obj) const { 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 { QString result; for (auto char_v : bytes) { result += QString("%1").arg(char_v, 2, 16, QChar('0')); } return result; } std::shared_ptr BytesAsHex::newDefault() const { return std::make_shared(); } BytesAsBitCombine::BytesAsBitCombine() : AbstractExtractor(NAME(BytesAsBitCombine), DataType::TextString) { } bool BytesAsBitCombine::setSwitchOption(int bit_index, const QString& keyword) { if (bit_index >= 0 && bit_index <= this->countWithin() * 8) { _combines._switch_options[bit_index] = keyword; return true; } return false; } QHash BytesAsBitCombine::switchOptions() const { return _combines._switch_options; } void BytesAsBitCombine::clearOptions() { _combines._switch_options.clear(); } QVariant BytesAsBitCombine::parse(const QByteArray& bytes) const { auto keys = _combines._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(_combines._switch_options[idx], "Y"); else result += QString("%1<%2>;").arg(_combines._switch_options[idx], "N"); } return result; } void BytesAsBitCombine::loadFrom(const QJsonObject& obj) { AbstractExtractor::loadFrom(obj); QStringList value_list; STRLIST_PEAK(value_list); _combines._switch_options.clear(); for (auto pair : value_list) { auto items = pair.split("="); _combines._switch_options[items.first().toInt()] = items.last(); } } void BytesAsBitCombine::saveTo(QJsonObject& obj) const { AbstractExtractor::saveTo(obj); QStringList value_list; 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); } std::shared_ptr BytesAsBitCombine::newDefault() const { return std::make_shared(); } std::shared_ptr BytesAsInteger::newDefault() const { return std::make_shared(); } BytesAsInteger::BytesAsInteger() :AbstractExtractor(NAME(BytesAsInteger), DataType::Integer) { } bool BytesAsInteger::setCountWithin(int bytes) { bytes = std::min(8, std::max(bytes, 0)); return AbstractExtractor::setCountWithin(bytes); } QVariant BytesAsInteger::parse(const QByteArray& bytes) 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(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; } return *((long long*)(&value)); } #include BytesAsString::BytesAsString() :AbstractExtractor(NAME(BytesAsString), DataType::TextString) { _strings._conv_with = QTextCodec::codecForName("GBK"); } void BytesAsString::setStrCodec(QTextCodec* ins) { this->_strings._conv_with = ins; } QString BytesAsString::codecName() const { return this->_strings._conv_with->name(); } QVariant BytesAsString::parse(const QByteArray& bytes) const { return _strings._conv_with->toUnicode(bytes); } void BytesAsString::loadFrom(const QJsonObject& obj) { AbstractExtractor::loadFrom(obj); QString codec_name; STRING_PEAK(codec_name); this->_strings._conv_with = QTextCodec::codecForName(codec_name.toLatin1()); } void BytesAsString::saveTo(QJsonObject& obj) const { AbstractExtractor::saveTo(obj); auto codec_name = this->codecName(); STRING_SAVE(codec_name); } std::shared_ptr BytesAsString::newDefault() const { return std::make_shared(); } QVariant BytesAsFloat::parse(const QByteArray& bytes) const { return *((float*)bytes.data()); } std::shared_ptr BytesAsFloat::newDefault() const { return std::make_shared(); } BytesAsFloat::BytesAsFloat() :AbstractExtractor(NAME(BytesAsFloat), DataType::Flt32) { this->setCountWithin(4); } std::shared_ptr BytesAsDouble::newDefault() const { return std::make_shared(); } QVariant BytesAsDouble::parse(const QByteArray& bytes) const { return *((double*)bytes.data()); } BytesAsDouble::BytesAsDouble() :AbstractExtractor(NAME(BytesAsDouble), DataType::Dbl64) { this->setCountWithin(8); } BytesAsUnsigned::BytesAsUnsigned() :AbstractExtractor(NAME(BytesAsUnsigned), DataType::Unsigned) { } bool BytesAsUnsigned::setCountWithin(int bytes) { auto count = std::max(1, std::min(8, bytes)); return AbstractExtractor::setCountWithin(count); } QVariant BytesAsUnsigned::parse(const QByteArray& bytes) 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; } return value; } std::shared_ptr BytesAsUnsigned::newDefault() const { return std::make_shared(); } #include bool BytesAsList::setOffsetSpan(int value) { this->_list._bytes_offset = value; return true; } std::shared_ptr BytesAsList::elementRule() const { return this->_list._bind_unit; } bool BytesAsList::setElementRule(std::shared_ptr u) { this->_list._bind_unit = u; return true; } std::shared_ptr BytesAsList::sizeProvider() const { return this->_list._bind_size_v; } bool BytesAsList::setSizeProvider(std::shared_ptr ins) { this->_list._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 _list._bytes_offset; } int BytesAsList::countWithin() const { auto expr = this->_list._bind_size_v->expression(); if (this->_list._bind_size_v->value(expr) < 0) { return 0; } return this->_list._bind_size_v->value(expr) * this->_list._bind_unit->countWithin(); } void BytesAsList::loadFrom(const QJsonObject& obj) { INT32_PEAK(_list._bytes_offset); QString bind_provider_expr = ""; STRING_SAVE(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->_list._bind_unit) bind_unit_name = this->_list._bind_unit->name(); STRING_SAVE(bind_unit_name); INT32_SAVE(_list._bytes_offset); QString bind_size_provider_name = ""; QString bind_provider_expr = ""; 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); } QVariant BytesAsList::parse(const QByteArray& bytes) 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; } std::shared_ptr BytesAsList::newDefault() const { return std::make_shared(); } 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 BytesAsUnion::newDefault() const { return std::make_shared(); } QList> BytesAsUnion::elementRules() const { return _union._rule_list; } bool BytesAsUnion::setElementRule(std::shared_ptr 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; }