import { MAX_DATA_LENGTH } from '../common' import { numberToUint16BE } from '../utilities/number' import { SmartBuffer } from '../utilities/smart-buffer' export interface IncomingPacket { messageType: number senderId: number data: Uint8Array } export interface OutgoingPacket { messageType: Uint8Array data: Uint8Array } /** * Create an outgoing packet ready-to-send over a WebSocket in line with the BENNC basic message strucure specification. * @param outgoingPacket The message type and data to send. * @returns A buffer containing the ready-to-send packet. */ export function packOutgoingPacket (outgoingPacket: OutgoingPacket): Uint8Array { // Verify that the data does not exceed the maximum data length. if (outgoingPacket.data.length > MAX_DATA_LENGTH) { throw RangeError(`Specified data of length ${outgoingPacket.data.length} exceeds max data length ${MAX_DATA_LENGTH}.`) } // Prepare the outgoing packet. const buffer = new SmartBuffer() buffer.writeBytes(outgoingPacket.messageType) buffer.writeBytes(numberToUint16BE(outgoingPacket.data.length)) buffer.writeBytes(outgoingPacket.data) return buffer.data } /** * Unpack an incoming packet coming from a WebSocket in line with the BENNC basic message strucure specification. * @param incomingPacket The incoming buffer from a WebSocket to unpack. * @returns The unpacked data. */ export function unpackIncomingPacket (incomingPacket: ArrayBuffer): IncomingPacket { const buffer = SmartBuffer.from(incomingPacket) const messageType = buffer.readUInt16() const senderId = buffer.readUInt32() const length = buffer.readUInt16() const data = buffer.readBytes(length) return { messageType: messageType, senderId: senderId, data: data } }