@foxglove/ulog
Version:
PX4 ULog file reader
209 lines • 9.24 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.readMessageHeader = readMessageHeader;
exports.readRawMessage = readRawMessage;
exports.readMessageFlagBits = readMessageFlagBits;
exports.readMessageInformation = readMessageInformation;
exports.readMessageInformationMulti = readMessageInformationMulti;
exports.readMessageFormatDefinition = readMessageFormatDefinition;
exports.readMessageParameter = readMessageParameter;
exports.readMessageParameterDefault = readMessageParameterDefault;
exports.readMessageAddLogged = readMessageAddLogged;
exports.readMessageRemoveLogged = readMessageRemoveLogged;
exports.readMessageData = readMessageData;
exports.readMessageLog = readMessageLog;
exports.readMessageLogTagged = readMessageLogTagged;
exports.readMessageSynchronization = readMessageSynchronization;
exports.readMessageDropout = readMessageDropout;
exports.readMessageUnknown = readMessageUnknown;
const enums_1 = require("./enums");
const hex_1 = require("./hex");
const SYNC_MAGIC = [0x2f, 0x73, 0x13, 0x20, 0x25, 0x0c, 0xbb, 0x12];
async function readMessageHeader(reader) {
const size = await reader.readUint16();
const type = await reader.readUint8();
return { size, type };
}
async function readRawMessage(reader, dataEnd) {
if (dataEnd != undefined) {
if (dataEnd - reader.position() < 3) {
return undefined;
}
}
else if (reader.remaining() < 3) {
return undefined;
}
try {
const header = await readMessageHeader(reader);
switch (header.type) {
case enums_1.MessageType.FlagBits:
return await readMessageFlagBits(reader, header);
case enums_1.MessageType.Information:
return await readMessageInformation(reader, header);
case enums_1.MessageType.InformationMulti:
return await readMessageInformationMulti(reader, header);
case enums_1.MessageType.FormatDefinition:
return await readMessageFormatDefinition(reader, header);
case enums_1.MessageType.Parameter:
return await readMessageParameter(reader, header);
case enums_1.MessageType.ParameterDefault:
return await readMessageParameterDefault(reader, header);
case enums_1.MessageType.AddLogged:
return await readMessageAddLogged(reader, header);
case enums_1.MessageType.RemoveLogged:
return await readMessageRemoveLogged(reader, header);
case enums_1.MessageType.Data:
return await readMessageData(reader, header);
case enums_1.MessageType.Log:
return await readMessageLog(reader, header);
case enums_1.MessageType.LogTagged:
return await readMessageLogTagged(reader, header);
case enums_1.MessageType.Synchronization:
return await readMessageSynchronization(reader, header);
case enums_1.MessageType.Dropout:
return await readMessageDropout(reader, header);
case enums_1.MessageType.Unknown:
default:
return await readMessageUnknown(reader, header);
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
}
catch (_err) {
return undefined;
}
}
async function readMessageFlagBits(reader, header) {
if (header.size < 40) {
throw new Error(`Invalid 'B' message, expected 40 bytes but got ${header.size}`);
}
const compatFlags = await reader.readBytes(8);
const incompatFlags = await reader.readBytes(8);
for (let i = 0; i < 8; i++) {
if ((i === 0 && incompatFlags[i] > 1) || (i !== 0 && incompatFlags[i] !== 0)) {
throw new Error(`Incompatible flag bit: ${i} is ${incompatFlags[i]}`);
}
}
return {
size: header.size,
type: header.type,
compatibleFlags: Array.from(compatFlags),
incompatibleFlags: Array.from(incompatFlags),
appendedOffsets: [
await reader.readUint64(),
await reader.readUint64(),
await reader.readUint64(),
],
};
}
async function readMessageInformation(reader, header) {
const keyLen = await reader.readUint8();
if (keyLen > header.size - 1) {
throw new Error(`Invalid 'I' message, size is ${header.size} but key_len is ${keyLen}`);
}
return {
size: header.size,
type: header.type,
key: await reader.readString(keyLen),
value: await reader.readBytes(header.size - 1 - keyLen),
};
}
async function readMessageInformationMulti(reader, header) {
const isContinued = Boolean(await reader.readUint8());
const keyLen = await reader.readUint8();
if (keyLen > header.size - 1) {
throw new Error(`Invalid 'I' message, size is ${header.size} but key_len is ${keyLen}`);
}
const key = await reader.readString(keyLen);
const value = await reader.readBytes(header.size - 2 - keyLen);
return { size: header.size, type: header.type, isContinued, key, value };
}
async function readMessageFormatDefinition(reader, header) {
const format = await reader.readString(header.size);
return { size: header.size, type: header.type, format };
}
async function readMessageParameter(reader, header) {
const keyLen = await reader.readUint8();
if (keyLen > header.size - 1) {
throw new Error(`Invalid 'P' message, size is ${header.size} but key_len is ${keyLen}`);
}
const key = await reader.readString(keyLen);
const value = await reader.readBytes(header.size - 1 - keyLen);
return { size: header.size, type: header.type, key, value };
}
async function readMessageParameterDefault(reader, header) {
const defaultTypes = (await reader.readUint8());
const keyLen = await reader.readUint8();
if (keyLen > header.size - 2) {
throw new Error(`Invalid 'Q' message, size is ${header.size} but key_len is ${keyLen}`);
}
const key = await reader.readString(keyLen);
const value = await reader.readBytes(header.size - 2 - keyLen);
return { size: header.size, type: header.type, defaultTypes, key, value };
}
async function readMessageAddLogged(reader, header) {
if (header.size < 3) {
throw new Error(`Invalid 'A' message, size is ${header.size} but expected at least 3`);
}
const multiId = await reader.readUint8();
const msgId = await reader.readUint16();
const messageName = await reader.readString(header.size - 3);
return { size: header.size, type: header.type, multiId, msgId, messageName };
}
async function readMessageRemoveLogged(reader, header) {
if (header.size < 1) {
throw new Error(`Invalid 'R' message, size is ${header.size} but expected at least 1`);
}
const msgId = await reader.readUint8();
return { size: header.size, type: header.type, msgId };
}
async function readMessageData(reader, header) {
if (header.size < 2) {
throw new Error(`Invalid 'D' message, size is ${header.size} but expected at least 2`);
}
const msgId = await reader.readUint16();
const data = await reader.readBytes(header.size - 2);
return { size: header.size, type: header.type, msgId, data };
}
async function readMessageLog(reader, header) {
if (header.size < 9) {
throw new Error(`Invalid 'L' message, size is ${header.size} but expected at least 9`);
}
const logLevel = (await reader.readUint8());
const timestamp = await reader.readUint64();
const message = await reader.readString(header.size - 9);
return { size: header.size, type: header.type, logLevel, timestamp, message };
}
async function readMessageLogTagged(reader, header) {
if (header.size < 11) {
throw new Error(`Invalid 'T' message, size is ${header.size} but expected at least 11`);
}
const logLevel = (await reader.readUint8());
const tag = await reader.readUint16();
const timestamp = await reader.readUint64();
const message = await reader.readString(header.size - 11);
return { size: header.size, type: header.type, logLevel, tag, timestamp, message };
}
async function readMessageSynchronization(reader, header) {
if (header.size !== 8) {
throw new Error(`Invalid 'S' message, size is ${header.size} but expected 8`);
}
const syncMagic = await reader.readBytes(8);
for (let i = 0; i < 8; i++) {
if (syncMagic[i] !== SYNC_MAGIC[i]) {
throw new Error(`Invalid 'S' message: ${(0, hex_1.toHex)(syncMagic)}`);
}
}
return { size: header.size, type: header.type, syncMagic: SYNC_MAGIC };
}
async function readMessageDropout(reader, header) {
if (header.size < 2) {
throw new Error(`Invalid 'O' message, size is ${header.size} but expected at least 2`);
}
const duration = await reader.readUint16();
return { size: header.size, type: header.type, duration };
}
async function readMessageUnknown(reader, header) {
const data = await reader.readBytes(header.size);
return { size: header.size, type: enums_1.MessageType.Unknown, unknownType: header.type, data };
}
//# sourceMappingURL=readMessage.js.map