UNPKG

bencodec

Version:

Library for decoding and encoding bencode data

106 lines (105 loc) 3.51 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.BencodeEncoder = void 0; const types_1 = require("./types"); const node_buffer_1 = require("node:buffer"); class BencodeEncoder { /** * Constructor */ constructor(options) { this._integerIdentifier = node_buffer_1.Buffer.from([types_1.FLAG.INTEGER]); this._stringDelimiterIdentifier = node_buffer_1.Buffer.from([types_1.FLAG.STR_DELIMITER]); this._listIdentifier = node_buffer_1.Buffer.from([types_1.FLAG.LIST]); this._dictionaryIdentifier = node_buffer_1.Buffer.from([types_1.FLAG.DICTIONARY]); this._endIdentifier = node_buffer_1.Buffer.from([types_1.FLAG.END]); this._buffer = []; this._options = options || {}; } /** * Encode data */ encode(data) { this._encodeType(data); return this._options.stringify ? node_buffer_1.Buffer.concat(this._buffer).toString('utf8') : node_buffer_1.Buffer.concat(this._buffer); } /** * Encode data by type */ _encodeType(data) { if (node_buffer_1.Buffer.isBuffer(data)) { return this._encodeBuffer(data); } if (Array.isArray(data)) { return this._encodeList(data); } if (ArrayBuffer.isView(data)) { return this._encodeBuffer(node_buffer_1.Buffer.from(data.buffer, data.byteOffset, data.byteLength)); } if (data instanceof ArrayBuffer) { return this._encodeBuffer(node_buffer_1.Buffer.from(data)); } if (typeof data === 'boolean') { return this._encodeInteger(data ? 1 : 0); } if (typeof data === 'number') { return this._encodeInteger(data); } if (typeof data === 'string') { return this._encodeString(data); } if (typeof data === 'object') { return this._encodeDictionary(data); } throw new Error(`${typeof data} is unsupported type.`); } /** * Encode buffer */ _encodeBuffer(data) { this._buffer.push(node_buffer_1.Buffer.from(String(data.length)), this._stringDelimiterIdentifier, data); } /** * Encode string */ _encodeString(data) { this._buffer.push(node_buffer_1.Buffer.from(String(node_buffer_1.Buffer.byteLength(data))), this._stringDelimiterIdentifier, node_buffer_1.Buffer.from(data)); } /** * Encode integer */ _encodeInteger(data) { this._buffer.push(this._integerIdentifier, node_buffer_1.Buffer.from(String(Math.round(data))), this._endIdentifier); } /** * Encode list */ _encodeList(data) { this._buffer.push(this._listIdentifier); for (const item of data) { if (item === null || item === undefined) { continue; } this._encodeType(item); } this._buffer.push(this._endIdentifier); } /** * Encode dictionary */ _encodeDictionary(data) { this._buffer.push(this._dictionaryIdentifier); const keys = Object.keys(data).sort(); for (const key of keys) { if (data[key] === null || data[key] === undefined) { continue; } this._encodeString(key); this._encodeType(data[key]); } this._buffer.push(this._endIdentifier); } } exports.BencodeEncoder = BencodeEncoder;