UNPKG

@foxglove/ros1

Version:

Standalone TypeScript implementation of the ROS 1 (Robot Operating System) protocol with a pluggable transport layer

60 lines 2.83 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.RosTcpMessageStream = void 0; const eventemitter3_1 = require("eventemitter3"); const concatData_1 = require("./concatData"); // This is the maximum message length allowed by ros_comm. See // <https://github.com/strawlab/ros_comm/blob/master/clients/cpp/roscpp/src/libros/transport_publisher_link.cpp#L164-L167> const MAX_MSG_LENGTH = 1000000000; // A stateful transformer that takes a raw TCPROS data stream and parses the // TCPROS format of 4 byte length prefixes followed by message payloads into one // complete message per "message" event, discarding the length prefix class RosTcpMessageStream extends eventemitter3_1.EventEmitter { constructor() { super(...arguments); this._inMessage = false; this._bytesNeeded = 4; this._chunks = []; } addData(chunk) { let idx = 0; while (idx < chunk.length) { if (chunk.length - idx < this._bytesNeeded) { // If we didn't receive enough bytes to complete the current message or // message length field, store this chunk and continue on this._chunks.push(new Uint8Array(chunk.buffer, chunk.byteOffset + idx)); this._bytesNeeded -= chunk.length - idx; return; } // Store the final chunk needed to complete the current message or message // length field this._chunks.push(new Uint8Array(chunk.buffer, chunk.byteOffset + idx, this._bytesNeeded)); idx += this._bytesNeeded; const payload = (0, concatData_1.concatData)(this._chunks); this._chunks = []; if (this._inMessage) { // Produce a Uint8Array representing a single message and transition to // reading a message length field this._bytesNeeded = 4; this.emit("message", payload); this._inMessage = false; } else { // Decode the message length field and transition to reading a message this._bytesNeeded = new DataView(payload.buffer, payload.byteOffset, payload.byteLength).getUint32(0, true); if (this._bytesNeeded > MAX_MSG_LENGTH) { throw new Error(`Invalid message length of ${this._bytesNeeded} decoded in a tcp stream`); } else if (this._bytesNeeded === 0) { this._bytesNeeded = 4; this.emit("message", new Uint8Array()); } else { this._inMessage = true; } } } } } exports.RosTcpMessageStream = RosTcpMessageStream; //# sourceMappingURL=RosTcpMessageStream.js.map