Last active
July 5, 2020 07:09
-
-
Save z-------------/b14c008d9e45a90169b6b87de7eb63f5 to your computer and use it in GitHub Desktop.
Seems to work... Not nearly as fast as node-bencode
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const MODE_NONE = 0, | |
MODE_BYTESTRING = 1, | |
MODE_INT = 2, | |
MODE_LIST = 3, | |
MODE_DICT = 4; | |
function getInt(buf) { | |
let n = 0; | |
for (let i = 0; i < buf.length; ++i) { | |
n += (buf[buf.length - 1 - i] - 48) * 10 ** i; | |
} | |
return n; | |
} | |
function _decode(data) { | |
const items = []; | |
let buf = []; | |
const l = data.length; | |
let i = 0; | |
let mode = MODE_NONE; | |
let bytesLength = 0; | |
let bytesRead = 0; | |
let bytesBuf; | |
while (i < l) { | |
const byte = data[i]; | |
if (mode === MODE_NONE) { | |
if (byte === 101) { // e | |
i += 1; | |
break; | |
} else if (byte === 105) { // i | |
mode = MODE_INT; | |
} else if (byte === 108) { // l | |
mode = MODE_LIST; | |
const [listItems, listSize] = _decode(data.slice(i + 1)); | |
items.push(listItems); | |
i += listSize + 1; | |
mode = MODE_NONE; | |
continue; | |
} else if (byte === 100) { // d | |
mode = MODE_DICT; | |
const [dictItems, dictSize] = _decode(data.slice(i + 1)); | |
const dict = {}; | |
for (let j = 0; j < dictItems.length; j += 2) { | |
dict[dictItems[j]] = dictItems[j + 1]; | |
} | |
items.push(dict); | |
i += dictSize + 1; | |
mode = MODE_NONE; | |
continue; | |
} else if (byte >= 48 && byte <= 57) { // 0-9 | |
bytesLength *= 10; | |
bytesLength += byte - 48; | |
} else if (byte === 58) { // : | |
mode = MODE_BYTESTRING; | |
bytesBuf = Buffer.allocUnsafe(bytesLength); | |
} | |
} else if (mode === MODE_INT && byte === 101) { // e | |
const int = getInt(buf); | |
items.push(int); | |
mode = MODE_NONE; | |
buf = []; | |
} else if (mode === MODE_BYTESTRING) { | |
bytesBuf[bytesRead++] = byte; | |
if (bytesRead === bytesLength) { | |
items.push(bytesBuf); | |
bytesRead = 0; | |
bytesLength = 0; | |
mode = MODE_NONE; | |
} | |
} else { | |
buf.push(byte); | |
} | |
++i; | |
} | |
return [items, i]; | |
} | |
module.exports = function decode(data) { | |
return _decode(data)[0]; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment