UNPKG

@foxglove/ulog

Version:
107 lines 4.05 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.parseMessage = parseMessage; exports.parseFieldValue = parseFieldValue; exports.parseBasicFieldValue = parseBasicFieldValue; exports.messageSize = messageSize; exports.fieldSize = fieldSize; const BASIC_PARSERS = { bool: (view, offset) => view.getUint8(offset) !== 0, int8_t: (view, offset) => view.getInt8(offset), uint8_t: (view, offset) => view.getUint8(offset), int16_t: (view, offset) => view.getInt16(offset, true), uint16_t: (view, offset) => view.getUint16(offset, true), int32_t: (view, offset) => view.getInt32(offset, true), uint32_t: (view, offset) => view.getUint32(offset, true), int64_t: (view, offset) => view.getBigInt64(offset, true), uint64_t: (view, offset) => view.getBigUint64(offset, true), float: (view, offset) => view.getFloat32(offset, true), double: (view, offset) => view.getFloat64(offset, true), char: (view, offset) => String.fromCharCode(view.getUint8(offset)), }; const BASIC_SIZES = { bool: 1, int8_t: 1, uint8_t: 1, int16_t: 2, uint16_t: 2, int32_t: 4, uint32_t: 4, int64_t: 8, uint64_t: 8, float: 4, double: 8, char: 1, }; const textDecoder = new TextDecoder(); function parseMessage(definition, definitions, view, offset = 0) { const output = {}; let curOffset = offset; for (const field of definition.fields) { if (!field.name.startsWith("_")) { output[field.name] = parseFieldValue(field, definitions, view, curOffset); } curOffset += fieldSize(field, definitions) * (field.arrayLength ?? 1); } if (typeof output.timestamp !== "bigint") { throw new Error(`Message "${definition.name}" is missing a timestamp field`); } return output; } function parseFieldValue(field, definitions, view, offset = 0) { if (field.isComplex) { const definition = definitions.get(field.type); if (!definition) { throw new Error(`Unknown type ${field.type}, searched ${definitions.size} definitions`); } if (field.arrayLength != undefined) { const size = fieldSize(field, definitions); const output = new Array(field.arrayLength); for (let i = 0; i < field.arrayLength; i++) { output[i] = parseMessage(definition, definitions, view, offset + i * size); } return output; } return parseMessage(definition, definitions, view, offset); } return parseBasicFieldValue(field, view, offset); } function parseBasicFieldValue(field, view, offset = 0) { const basicType = field.type; const parser = BASIC_PARSERS[basicType]; if (field.arrayLength != undefined) { // String handling if (field.type === "char") { const len = Math.min(field.arrayLength, view.byteLength - offset); const byteOffset = view.byteOffset + offset; return textDecoder.decode(new Uint8Array(view.buffer, byteOffset, len)); } const basicSize = BASIC_SIZES[basicType]; const output = new Array(field.arrayLength); for (let i = 0; i < field.arrayLength; i++) { output[i] = parser(view, offset + i * basicSize); } return output; } return parser(view, offset); } function messageSize(definition, definitions) { return definition.fields.reduce((size, f) => size + fieldSize(f, definitions) * (f.arrayLength ?? 1), 0); } function fieldSize(field, definitions) { if (field.size != undefined) { return field.size; } if (field.isComplex) { const definition = definitions.get(field.type); if (!definition) { throw new Error(`Unknown type ${field.type}, searched ${definitions.size} definitions`); } field.size = messageSize(definition, definitions); } else { field.size = BASIC_SIZES[field.type]; } return field.size; } //# sourceMappingURL=parse.js.map