#include "extract_basic.h" #include using namespace extract; AbstractExtractor::AbstractExtractor(const QString& name, DataType data) :_name_store(name), _type_store(data), _byte_offset(0), _byte_count(1) { } bool AbstractExtractor::setOffsetSpan(int bytes) { this->_byte_offset = bytes; return true; } bool AbstractExtractor::setCountWithin(int bytes) { this->_byte_count = bytes; return true; } QString AbstractExtractor::name() const { return _name_store; } DataType AbstractExtractor::outType() const { return _type_store; } int AbstractExtractor::offsetSpan() const { return _byte_offset; } int AbstractExtractor::countWithin() const { return this->_byte_count; } void AbstractExtractor::loadFrom(const QJsonObject& obj) { INT32_PEAK(_byte_offset); INT32_PEAK(_byte_count); } void AbstractExtractor::saveTo(QJsonObject& obj) const { INT32_SAVE(_byte_offset); INT32_SAVE(_byte_count); } BytesAsHex::BytesAsHex() : AbstractExtractor(NAME(BytesAsHex), DataType::TextString) { } 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) { _switch_options[bit_index] = keyword; return true; } return false; } QHash BytesAsBitCombine::switchOptions() const { return _switch_options; } void BytesAsBitCombine::clearOptions() { _switch_options.clear(); } QVariant BytesAsBitCombine::parse(const QByteArray& bytes) const { auto keys = _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(_switch_options[idx], "Y"); else result += QString("%1<%2>;").arg(_switch_options[idx], "N"); } return result; } void BytesAsBitCombine::loadFrom(const QJsonObject& obj) { AbstractExtractor::loadFrom(obj); QStringList value_list; STRLIST_PEAK(value_list); _switch_options.clear(); for (auto pair : value_list) { auto items = pair.split("="); _switch_options[items.first().toInt()] = items.last(); } } void BytesAsBitCombine::saveTo(QJsonObject& obj) const { AbstractExtractor::saveTo(obj); QStringList value_list; for (auto key : _switch_options.keys()) { auto pair = QString("%1=%2").arg(key).arg(_switch_options[key]); } 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(), 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) { _conv_with = QTextCodec::codecForName("GBK"); } void BytesAsString::setStrCodec(QTextCodec* ins) { this->_conv_with = ins; } QString BytesAsString::codecName() const { return this->_conv_with->name(); } QVariant BytesAsString::parse(const QByteArray& bytes) const { return _conv_with->toUnicode(bytes); } void BytesAsString::loadFrom(const QJsonObject& obj) { AbstractExtractor::loadFrom(obj); QString codec_name; STRING_PEAK(codec_name); this->_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 QVariant BytesAsList::parse(const QByteArray& bytes) const { throw std::logic_error("The method or operation is not implemented."); } std::shared_ptr BytesAsList::newDefault() const { throw std::logic_error("The method or operation is not implemented."); } bool BytesAsUnion::setSizeProvider(std::shared_ptr ins) { if(ins->value() < 1) return false; 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 BytesAsUnion::newDefault() const { throw std::logic_error("The method or operation is not implemented."); }