QBinaryTranslate/TranslateUI/TranslateBasic.cpp

369 lines
7.4 KiB
C++

#include "TranslateBasic.h"
using namespace extract;
using namespace convert;
AbstractExtractor::AbstractExtractor(const QString& name, DataType data)
:_name_store(name), _type_store(data), _byte_offset(0), _byte_count(0) {
}
bool AbstractExtractor::setOffsetFromPrevious(int bytes)
{
this->_byte_offset = bytes;
return true;
}
bool AbstractExtractor::setCountWithinParse(int bytes)
{
this->_byte_count = bytes;
return true;
}
QString AbstractExtractor::name() const
{
return _name_store;
}
DataType AbstractExtractor::outType() const
{
return _type_store;
}
int AbstractExtractor::offsetFromPrevious() const
{
return _byte_offset;
}
int AbstractExtractor::countWithinParse() const
{
return _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_count);
INT32_SAVE(_byte_offset);
}
BytesAsHex::BytesAsHex()
: AbstractExtractor(NAME(BytesAsHex), DataType::ValueSequenceString) {
}
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 + "H";
}
std::shared_ptr<Serializable> BytesAsHex::newDefault() const
{
return std::make_shared<BytesAsHex>();
}
BytesAsBitCombine::BytesAsBitCombine()
: AbstractExtractor(NAME(BytesAsBitCombine), DataType::TextString)
{
}
bool BytesAsBitCombine::setSwitchOption(int bit_index, const QString& keyword)
{
if (bit_index >= 0 && bit_index <= this->countWithinParse() * 8) {
_switch_options[bit_index] = keyword;
return true;
}
return false;
}
QHash<int, QString> 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<Serializable> BytesAsBitCombine::newDefault() const
{
return std::make_shared<BytesAsBitCombine>();
}
void BytesAsInteger::loadFrom(const QJsonObject& obj)
{
AbstractExtractor::loadFrom(obj);
INT32_PEAK(unsigned_mark);
}
void BytesAsInteger::saveTo(QJsonObject& obj) const
{
AbstractExtractor::saveTo(obj);
INT32_SAVE(unsigned_mark);
}
std::shared_ptr<Serializable> BytesAsInteger::newDefault() const
{
return std::make_shared<BytesAsInteger>();
}
BytesAsInteger::BytesAsInteger()
:AbstractExtractor(NAME(BytesAsInteger), DataType::Int64) {
}
void BytesAsInteger::setUnsignedMark(bool ste)
{
this->unsigned_mark = ste;
}
bool BytesAsInteger::unsignedMark() const
{
return unsigned_mark;
}
bool BytesAsInteger::setCountWithinParse(int bytes)
{
bytes = std::min(8, std::max(bytes, 0));
return AbstractExtractor::setCountWithinParse(bytes);
}
QVariant BytesAsInteger::parse(const QByteArray& bytes) const
{
if (unsigned_mark) {
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;
}
else {
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 <QTextCodec>
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<Serializable> BytesAsString::newDefault() const
{
return std::make_shared<BytesAsString>();
}
AbstractValueConvert::AbstractValueConvert(const QString& nm, DataType in, DataType out)
: _name_store(nm), _in_type(in), _out_type(out) {
}
QString AbstractValueConvert::name() const
{
return _name_store;
}
DataType AbstractValueConvert::inType() const
{
return _in_type;
}
DataType AbstractValueConvert::outType() const
{
return _out_type;
}
void AbstractValueConvert::loadFrom(const QJsonObject& obj)
{
auto int_in_type = (int)_in_type;
INT32_PEAK(int_in_type);
_in_type = (DataType)int_in_type;
auto int_out_type = (int)_out_type;
INT32_PEAK(int_out_type);
_out_type = (DataType)int_out_type;
}
void AbstractValueConvert::saveTo(QJsonObject& obj) const
{
auto int_in_type = (int)_in_type;
INT32_SAVE(int_in_type);
auto int_out_type = (int)_out_type;
INT32_SAVE(int_out_type);
}
DoubleWithLSB::DoubleWithLSB()
:AbstractValueConvert(NAME(DoubleWithLSB), DataType::Int64, DataType::Dbl64),
_lsb_value(0)
{
}
void DoubleWithLSB::setLSB(double lsbv)
{
this->_lsb_value = lsbv;
}
double DoubleWithLSB::getLSB() const
{
return this->_lsb_value;
}
QVariant DoubleWithLSB::convert(const QVariant& value) const
{
if (value.canConvert<int64_t>())
return value.toLongLong() * this->_lsb_value;
return value.toULongLong() * this->_lsb_value;
}
std::shared_ptr<Serializable> DoubleWithLSB::newDefault() const
{
return std::make_shared<DoubleWithLSB>();
}
QVariant BytesAsFloat::parse(const QByteArray& bytes) const
{
return *((float*)bytes.data());
}
std::shared_ptr<Serializable> BytesAsFloat::newDefault() const
{
return std::make_shared<BytesAsFloat>();
}
bool BytesAsFloat::setCountWithinParse(int bytes)
{
AbstractExtractor::setCountWithinParse(4);
return true;
}
BytesAsFloat::BytesAsFloat()
:AbstractExtractor(NAME(BytesAsFloat), DataType::Flt32)
{
}
std::shared_ptr<Serializable> BytesAsDouble::newDefault() const
{
return std::make_shared<BytesAsDouble>();
}
QVariant BytesAsDouble::parse(const QByteArray& bytes) const
{
return *((double*)bytes.data());
}
bool BytesAsDouble::setCountWithinParse(int bytes)
{
AbstractExtractor::setCountWithinParse(8);
return true;
}
BytesAsDouble::BytesAsDouble()
:AbstractExtractor(NAME(BytesAsDouble), DataType::Dbl64)
{
}