64QVariant
parseValue(
const char* data, qint64 size,
char formatChar)
67 if (requiredSize == 0) {
68 qCWarning(APMDataFlashUtilityLog) <<
"Unsupported DataFlash format character:" << formatChar;
71 if (!data || size < requiredSize) {
72 qCWarning(APMDataFlashUtilityLog) <<
"Missing or truncated DataFlash value for format:" << formatChar;
76 const std::span<const uint8_t> bytes{
reinterpret_cast<const uint8_t*
>(data),
77 static_cast<std::size_t
>(requiredSize)};
80 return *LittleEndian::read<int8_t>(bytes);
83 return *LittleEndian::read<uint8_t>(bytes);
85 const auto val = *LittleEndian::read<int16_t>(bytes);
89 const auto val = *LittleEndian::read<uint16_t>(bytes);
93 const auto val = *LittleEndian::read<int16_t>(bytes);
97 const auto val = *LittleEndian::read<uint16_t>(bytes);
101 const auto val = *LittleEndian::read<int32_t>(bytes);
105 const auto val = *LittleEndian::read<uint32_t>(bytes);
109 const auto val = *LittleEndian::read<int32_t>(bytes);
113 const auto val = *LittleEndian::read<uint32_t>(bytes);
117 const auto val = *LittleEndian::read<int32_t>(bytes);
121 const auto val = *LittleEndian::read<float>(bytes);
122 return static_cast<double>(val);
125 const auto val = *LittleEndian::read<double>(bytes);
129 const auto val = *LittleEndian::read<int64_t>(bytes);
130 return static_cast<qlonglong
>(val);
133 const auto val = *LittleEndian::read<uint64_t>(bytes);
134 return static_cast<qulonglong
>(val);
137 const auto bits = *LittleEndian::read<uint16_t>(bytes);
141 return QString::fromLatin1(data, qstrnlen(data, 4));
143 return QString::fromLatin1(data, qstrnlen(data, 16));
145 return QString::fromLatin1(data, qstrnlen(data, 64));
148 return QByteArray(data, 64);
213 fmt.
type =
static_cast<uint8_t
>(data[0]);
214 fmt.
length =
static_cast<uint8_t
>(data[1]);
215 fmt.
name = QString::fromLatin1(data + 2, qstrnlen(data + 2, 4));
216 fmt.
format = QString::fromLatin1(data + 6, qstrnlen(data + 6, 16));
217 const QString columnsStr = QString::fromLatin1(data + 22, qstrnlen(data + 22, 64));
218 fmt.
columns = columnsStr.trimmed().split(
',');
230 QHash<uint8_t, QString> unitsByType;
233 while (pos + 3 <= size) {
241 const uint8_t msgType =
static_cast<uint8_t
>(data[pos + 2]);
251 qCWarning(APMDataFlashUtilityLog)
252 <<
"Ignoring FMT with invalid length:" << fmt.
name <<
static_cast<int>(fmt.
length);
254 formats[fmt.
type] = fmt;
259 if (formats.contains(msgType)) {
261 const int payloadSize = msgFmt.
length - 3;
262 if ((msgFmt.
name == QLatin1String(
"FMTU")) && (pos + payloadSize <= size)) {
263 const QMap<QString, QVariant> values =
parseMessage(data + pos, payloadSize, msgFmt);
264 const QVariant fmtType = values.value(QStringLiteral(
"FmtType"));
265 if (fmtType.isValid()) {
266 unitsByType.insert(
static_cast<uint8_t
>(fmtType.toUInt()),
267 values.value(QStringLiteral(
"UnitIds")).toString());
278 for (
auto it = unitsByType.cbegin(); it != unitsByType.cend(); ++it) {
279 const auto fmtIt = formats.find(it.key());
280 if (fmtIt == formats.end()) {
283 const qsizetype index = it.value().indexOf(QLatin1Char(
'#'));
284 if ((index >= 0) && (index < fmtIt->columns.size())) {
285 fmtIt->instanceColumn = fmtIt->columns.at(index);
289 return !formats.isEmpty();
297 const QMap<uint8_t, MessageFormat> &formats,
299 const std::function<
void(
float)> &progressCallback)
304 while (pos + 3 <= size) {
312 const uint8_t msgType =
static_cast<uint8_t
>(data[pos + 2]);
315 if (!formats.contains(msgType)) {
320 const int payloadSize = fmt.
length - 3;
322 if (pos + payloadSize > size) {
327 if (!callback(msgType, data + pos, payloadSize, fmt)) {
333 if (progressCallback && (count % 1000 == 0)) {
334 progressCallback(
static_cast<float>(pos) /
static_cast<float>(size));