@seriousme/opifex
Version:
MQTT client & server for Deno & NodeJS
104 lines • 4.01 kB
JavaScript
/**
* @module MQTT Packet Encoding/Decoding
* @description This module provides comprehensive encoding and decoding functionality for MQTT packets
* used in both server and client implementations. It handles all MQTT packet types and their
* transformations between binary and object representations.
*/
import { PacketNameByType, PacketType } from "./PacketType.js";
import { invalidTopic, invalidTopicFilter, invalidUTF8 } from "./validators.js";
import { decodeLength, encodeLength } from "./length.js";
import { connect } from "./connect.js";
import { connack } from "./connack.js";
import { AuthenticationResult, AuthenticationResultByNumber, } from "./AuthenticationResult.js";
import { publish } from "./publish.js";
import { puback } from "./puback.js";
import { pubrec } from "./pubrec.js";
import { pubrel } from "./pubrel.js";
import { pubcomp } from "./pubcomp.js";
import { subscribe } from "./subscribe.js";
import { suback } from "./suback.js";
import { unsubscribe } from "./unsubscribe.js";
import { unsuback } from "./unsuback.js";
import { pingreq } from "./pingreq.js";
import { pingres } from "./pingres.js";
import { disconnect } from "./disconnect.js";
import { DecoderError } from "./decoder.js";
export { AuthenticationResult, AuthenticationResultByNumber, decodeLength, encodeLength, invalidTopic, invalidTopicFilter, invalidUTF8, PacketNameByType, PacketType, };
/**
* Array mapping MQTT packet types to their corresponding encode/decode handlers
* Index corresponds to packet type number.
*/
export const packetsByType = [
null,
connect, // 1
connack, // 2
publish, // 3
puback, // 4
pubrec, // 5
pubrel, // 6
pubcomp, // 7
subscribe, // 8
suback, // 9
unsubscribe, // 10
unsuback, // 11
pingreq, // 12
pingres, // 13
disconnect, // 14
];
/**
* @function encode
* @description Encodes an MQTT packet object into a binary Uint8Array format
* @param {AnyPacket} packet - The MQTT packet object to encode
* @returns {Uint8Array} The encoded packet as a binary buffer
* @throws {Error} If packet encoding fails
*/
export function encode(packet) {
const packetType = packet.type;
// deno-lint-ignore no-explicit-any
const pkt = packet;
const encoded = packetsByType[packetType]?.encode(pkt);
if (!encoded) {
throw Error("Packet encoding failed");
}
const { flags, bytes } = encoded;
return Uint8Array.from([
(packetType << 4) | flags,
...encodeLength(bytes.length),
...bytes,
]);
}
/**
* @function decodePayload
* @description Decodes a packet payload from binary format into an MQTT packet object
* @param {number} firstByte - The first byte of the MQTT packet containing type and flags
* @param {Uint8Array} buffer - The binary buffer containing the packet payload
* @returns {AnyPacket} The decoded MQTT packet object
* @throws {Error} If packet decoding fails
*/
export function decodePayload(firstByte, buffer) {
const packetType = firstByte >> 4;
const flags = firstByte & 0x0f;
const packet = packetsByType[packetType]?.decode(buffer, flags);
if (packet !== undefined) {
return packet;
}
throw new Error("packet decoding failed");
}
/**
* @function decode
* @description Decodes a complete MQTT packet from binary format into a packet object
* @param {Uint8Array} buffer - The binary buffer containing the complete MQTT packet
* @returns {AnyPacket} The decoded MQTT packet object
* @throws {DecoderError} If packet decoding fails due to invalid format or insufficient data
*/
export function decode(buffer) {
if (buffer.length < 2) {
throw new DecoderError("Packet decoding failed");
}
const { length, numLengthBytes } = decodeLength(buffer, 1);
const start = numLengthBytes + 1;
const end = start + length;
return decodePayload(buffer[0], buffer.subarray(start, end));
}
export { getLengthDecoder } from "../mqttPacket/length.js";
//# sourceMappingURL=mod.js.map