bencodec
Version:
Library for decoding and encoding bencode data
106 lines (105 loc) • 3.51 kB
JavaScript
"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;