18 case 'b':
case 'B':
case 'M':
20 case 'h':
case 'H':
case 'c':
case 'C':
case 'g':
22 case 'i':
case 'I':
case 'e':
case 'E':
case 'L':
case 'f':
24 case 'd':
case 'q':
case 'Q':
40 for (
const QChar &ch : format) {
52 const uint32_t sign = (bits & 0x8000) << 16;
53 const uint32_t exponent = (bits >> 10) & 0x1F;
54 const uint32_t mantissa = bits & 0x3FF;
59 }
else if (exponent == 31) {
60 result = sign | 0x7F800000 | (mantissa << 13);
62 result = sign | ((exponent + 112) << 23) | (mantissa << 13);
66 memcpy(&fval, &result,
sizeof(fval));
78 return static_cast<int8_t
>(*data);
81 return static_cast<uint8_t
>(*data);
84 memcpy(&val, data,
sizeof(val));
89 memcpy(&val, data,
sizeof(val));
94 memcpy(&val, data,
sizeof(val));
99 memcpy(&val, data,
sizeof(val));
104 memcpy(&val, data,
sizeof(val));
109 memcpy(&val, data,
sizeof(val));
114 memcpy(&val, data,
sizeof(val));
119 memcpy(&val, data,
sizeof(val));
124 memcpy(&val, data,
sizeof(val));
129 memcpy(&val, data,
sizeof(val));
130 return static_cast<double>(val);
134 memcpy(&val, data,
sizeof(val));
139 memcpy(&val, data,
sizeof(val));
140 return static_cast<qlonglong
>(val);
144 memcpy(&val, data,
sizeof(val));
145 return static_cast<qulonglong
>(val);
149 memcpy(&bits, data,
sizeof(bits));
153 return QString::fromLatin1(data, qstrnlen(data, 4));
155 return QString::fromLatin1(data, qstrnlen(data, 16));
157 return QString::fromLatin1(data, qstrnlen(data, 64));
160 return QByteArray(data, 64);
168 QMap<QString, QVariant> result;
171 for (
int i = 0; i < fmt.
format.length() && i < fmt.
columns.size(); ++i) {
172 const char formatChar = fmt.
format.at(i).toLatin1();
173 const QString &columnName = fmt.
columns.at(i);
180 result[columnName] =
parseValue(data + offset, formatChar);
202 while (offset + 2 < size) {
203 if (
static_cast<uint8_t
>(data[offset]) ==
kHeaderByte1 &&
204 static_cast<uint8_t
>(data[offset + 1]) ==
kHeaderByte2) {
219 fmt.
type =
static_cast<uint8_t
>(data[0]);
220 fmt.
length =
static_cast<uint8_t
>(data[1]);
221 fmt.
name = QString::fromLatin1(data + 2, qstrnlen(data + 2, 4));
222 fmt.
format = QString::fromLatin1(data + 6, qstrnlen(data + 6, 16));
223 const QString columnsStr = QString::fromLatin1(data + 22, qstrnlen(data + 22, 64));
224 fmt.
columns = columnsStr.trimmed().split(
',');
238 while (pos + 3 <= size) {
246 const uint8_t msgType =
static_cast<uint8_t
>(data[pos + 2]);
255 formats[fmt.
type] = fmt;
259 if (formats.contains(msgType)) {
260 pos += formats[msgType].length - 3;
268 return !formats.isEmpty();
276 const QMap<uint8_t, MessageFormat> &formats,
282 while (pos + 3 <= size) {
290 const uint8_t msgType =
static_cast<uint8_t
>(data[pos + 2]);
293 if (!formats.contains(msgType)) {
298 const int payloadSize = fmt.
length - 3;
300 if (pos + payloadSize > size) {
305 if (!callback(msgType, data + pos, payloadSize, fmt)) {
#define QGC_LOGGING_CATEGORY(name, categoryStr)
float halfToFloat(uint16_t bits)
int formatCharSize(char c)
qint64 findNextHeader(const char *data, qint64 size, qint64 offset)
bool parseFmtMessages(const char *data, qint64 size, QMap< uint8_t, MessageFormat > &formats)
int iterateMessages(const char *data, qint64 size, const QMap< uint8_t, MessageFormat > &formats, const MessageCallback &callback)
constexpr uint8_t kHeaderByte1
QMap< QString, QVariant > parseMessage(const char *data, const MessageFormat &fmt)
std::function< bool(uint8_t msgType, const char *payload, int payloadSize, const MessageFormat &fmt)> MessageCallback
MessageFormat parseFmtPayload(const char *data)
int calculatePayloadSize(const QString &format)
constexpr uint8_t kFmtMessageType
bool isValidHeader(const char *data, qint64 size)
QVariant parseValue(const char *data, char formatChar)
constexpr int kFmtPayloadSize
constexpr uint8_t kHeaderByte2