Skip to content

Commit

Permalink
feat: implement missing bugout features
Browse files Browse the repository at this point in the history
  • Loading branch information
fabianbormann committed Dec 9, 2022
1 parent 9d93681 commit 7f623da
Show file tree
Hide file tree
Showing 8 changed files with 555 additions and 140 deletions.
186 changes: 185 additions & 1 deletion lib/bencode.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Buffer } from 'buffer';
import { BufferData } from '../types';
import type { BufferData, Paket } from '../types';

/**
* source:
Expand Down Expand Up @@ -183,3 +183,187 @@ encode.listSet = function (buffers: Buffer[], data: any) {

buffers.push(buffE);
};

const INTEGER_START = 0x69; // 'i'
const STRING_DELIM = 0x3a; // ':'
const DICTIONARY_START = 0x64; // 'd'
const LIST_START = 0x6c; // 'l'
const END_OF_TYPE = 0x65; // 'e'

/**
* replaces parseInt(buffer.toString('ascii', start, end)).
* For strings with less then ~30 charachters, this is actually a lot faster.
*
* @param {Buffer} data
* @param {Number} start
* @param {Number} end
* @return {Number} calculated number
*/
function getIntFromBuffer(buffer: Buffer, start: number, end: number) {
let sum = 0;
let sign = 1;

for (let i = start; i < end; i++) {
const num = buffer[i];

if (num < 58 && num >= 48) {
sum = sum * 10 + (num - 48);
continue;
}

if (i === start && num === 43) {
// +
continue;
}

if (i === start && num === 45) {
// -
sign = -1;
continue;
}

if (num === 46) {
// .
// its a float. break here.
break;
}

throw new Error('not a number: buffer[' + i + '] = ' + num);
}

return sum * sign;
}

/**
* Decodes bencoded data.
*
* @param {Buffer} data
* @param {Number} start (optional)
* @param {Number} end (optional)
* @param {String} encoding (optional)
* @return {Object|Array|Buffer|String|Number}
*/
export function decode(
data: Buffer | Uint8Array,
start?: number,
end?: number,
encoding?: string | null
): Paket {
if (data == null || data.length === 0) {
return {};
}

if (typeof start !== 'number' && encoding == null) {
encoding = start;
start = undefined;
}

if (typeof end !== 'number' && encoding == null) {
encoding = end;
end = undefined;
}

decode.position = 0;
decode.encoding = encoding || null;

decode.data = !Buffer.isBuffer(data)
? Buffer.from(data)
: data.slice(start, end);

decode.bytes = decode.data.length;

const raw = decode.next();

if (typeof raw !== 'object') {
return {};
} else {
const packet: Paket = { ...raw };
return packet;
}
}

decode.bytes = 0;
decode.position = 0;
decode.data = null;
decode.encoding = null;

decode.next = (): { [key: string]: any } | Array<any> | number | string => {
switch (decode.data[decode.position]) {
case DICTIONARY_START:
return decode.dictionary();
case LIST_START:
return decode.list();
case INTEGER_START:
return decode.integer();
default:
return decode.buffer();
}
};

decode.find = function (chr: number) {
let i = decode.position;
const c = decode.data.length;
const d = decode.data;

while (i < c) {
if (d[i] === chr) return i;
i++;
}

throw new Error(
'Invalid data: Missing delimiter "' +
String.fromCharCode(chr) +
'" [0x' +
chr.toString(16) +
']'
);
};

decode.dictionary = (): Object => {
decode.position++;

const dict = {};

while (decode.data[decode.position] !== END_OF_TYPE) {
dict[decode.buffer()] = decode.next();
}

decode.position++;

return dict;
};

decode.list = (): Array<any> => {
decode.position++;

const lst = [];

while (decode.data[decode.position] !== END_OF_TYPE) {
lst.push(decode.next());
}

decode.position++;

return lst;
};

decode.integer = (): number => {
const end = decode.find(END_OF_TYPE);
const number = getIntFromBuffer(decode.data, decode.position + 1, end);

decode.position += end + 1 - decode.position;

return number;
};

decode.buffer = (): string => {
let sep = decode.find(STRING_DELIM);
const length = getIntFromBuffer(decode.data, decode.position, sep);
const end = ++sep + length;

decode.position = end;

return decode.encoding
? decode.data.toString(decode.encoding, sep, end)
: decode.data.slice(sep, end);
};
9 changes: 7 additions & 2 deletions meerkat.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ describe('testing meerkat', () => {
const meerkat = new Meerkat({
seed: 'BogKWM9LYR1C631b96Qz6U2tc2GR6XnhPSqe6YXBNCuS3aDePtPt',
});
let connected = false;
/*let connected = false;
meerkat.on('connections', (clients) => {
if (clients == 0 && connected == false) {
connected = true;
Expand All @@ -18,6 +18,11 @@ describe('testing meerkat', () => {
expect(clients.toBe(0));
done();
});*/

meerkat.on('torrent', () => {
done();
meerkat.close();
});
}, 5000);
}, 15000);
});
Loading

0 comments on commit 7f623da

Please sign in to comment.