🎨 Use buffers instead of DataView since Node.js is unstable with dv

This commit is contained in:
C-3PO 2018-07-08 22:16:33 +02:00
parent e6d42844f5
commit d3fa6d7c29
Signed by: c3po
GPG key ID: 62993C4BB4D86F24
2 changed files with 15 additions and 19 deletions

View file

@ -44,7 +44,7 @@ export default async function getSolidpkg(product: Product, from: number, to: nu
await readLocalFileHeader(stream, true); await readLocalFileHeader(stream, true);
const solidFileStream = await extractFileStream(firstFile, stream); const solidFileStream = await extractFileStream(firstFile, stream);
const solidFileArrayBuffer = await streamToArrayBuffer(solidFileStream); const solidFileArrayBuffer = await streamToArrayBuffer(solidFileStream);
const solidContents = parseBencode(new DataView(solidFileArrayBuffer.buffer)) as ISolid; const solidContents = parseBencode(solidFileArrayBuffer) as ISolid;
//Verify metafile.solid for correctness //Verify metafile.solid for correctness
verifySolidpkg(solidContents, { product, from, to }); verifySolidpkg(solidContents, { product, from, to });

View file

@ -2,30 +2,26 @@
* A parser for .torrent files encoded with Bencode <https://en.wikipedia.org/wiki/Bencode>. * A parser for .torrent files encoded with Bencode <https://en.wikipedia.org/wiki/Bencode>.
*/ */
import { TextDecoder } from 'util';
const decoder = new TextDecoder('utf-8');
/** Takes a Bencoded-encoded file, parses it at the given starting position and returns a JSON object, or rejects on error. */ /** Takes a Bencoded-encoded file, parses it at the given starting position and returns a JSON object, or rejects on error. */
function bpParse(dv: DataView, posIn: number = 0): { obj: any, pos: number } { function bpParse(buffer: Buffer, posIn: number = 0): { obj: any, pos: number } {
let pos = posIn; let pos = posIn;
let obj: any; let obj: any;
const header = dv.getUint8(pos); pos += 1; const header = buffer.readUInt8(pos); pos += 1;
switch (header) { switch (header) {
case 0x64: { //'d' - dictionary (key-value object) case 0x64: { //'d' - dictionary (key-value object)
obj = {}; obj = {};
do { do {
//read key //read key
const outKey = bpParse(dv, pos); const outKey = bpParse(buffer, pos);
pos = outKey.pos; pos = outKey.pos;
if (typeof outKey.obj !== 'string') { if (typeof outKey.obj !== 'string') {
throw new Error(`Expected dictionary key to be string but it is "${typeof outKey.obj}".`); throw new Error(`Expected dictionary key to be string but it is "${typeof outKey.obj}".`);
} }
//read value //read value
const outValue = bpParse(dv, pos); const outValue = bpParse(buffer, pos);
pos = outValue.pos; pos = outValue.pos;
obj[outKey.obj] = outValue.obj; obj[outKey.obj] = outValue.obj;
} while (dv.getUint8(pos) !== 0x65); //'e' - end } while (buffer.readUInt8(pos) !== 0x65); //'e' - end
pos += 1; pos += 1;
break; break;
} }
@ -33,15 +29,15 @@ function bpParse(dv: DataView, posIn: number = 0): { obj: any, pos: number } {
obj = []; obj = [];
do { do {
//read entry //read entry
const out = bpParse(dv, pos); const out = bpParse(buffer, pos);
pos = out.pos; pos = out.pos;
obj.push(out.obj); obj.push(out.obj);
} while (dv.getUint8(pos) !== 0x65); //'e' - end } while (buffer.readUInt8(pos) !== 0x65); //'e' - end
pos += 1; pos += 1;
break; break;
} }
case 0x69: { //'i' - integer case 0x69: { //'i' - integer
let curChar = dv.getUint8(pos); pos += 1; let curChar = buffer.readUInt8(pos); pos += 1;
let curNumber = 0; let curNumber = 0;
while (curChar !== 0x65) { //'e' - end while (curChar !== 0x65) { //'e' - end
if (curChar < 0x30 || curChar > 0x39) { if (curChar < 0x30 || curChar > 0x39) {
@ -49,7 +45,7 @@ function bpParse(dv: DataView, posIn: number = 0): { obj: any, pos: number } {
} }
curNumber *= 10; curNumber *= 10;
curNumber += curChar - 0x30; curNumber += curChar - 0x30;
curChar = dv.getUint8(pos); pos += 1; curChar = buffer.readUInt8(pos); pos += 1;
} }
obj = curNumber; obj = curNumber;
break; break;
@ -65,19 +61,19 @@ function bpParse(dv: DataView, posIn: number = 0): { obj: any, pos: number } {
} }
strLen *= 10; strLen *= 10;
strLen += curChar - 0x30; strLen += curChar - 0x30;
curChar = dv.getUint8(pos); pos += 1; curChar = buffer.readUInt8(pos); pos += 1;
} }
//read string //read string
obj = decoder.decode(new DataView(dv.buffer, pos, strLen)); obj = buffer.toString('utf-8', pos, pos + strLen);
pos += strLen; pos += strLen;
break; break;
} }
default: default:
throw new Error(`Unexpected leading char 0x${header.toString(16)} during Bencode parsing at position ${pos - 1}. Full text:\n${decoder.decode(dv)}`); throw new Error(`Unexpected leading char 0x${header.toString(16)} during Bencode parsing at position ${pos - 1}. Full text:\n${buffer.toString('utf-8')}`);
} }
return { obj, pos }; return { obj, pos };
} }
export default function parseBencode(dv: DataView): any { export default function parseBencode(buffer: Buffer): any {
return bpParse(dv).obj; return bpParse(buffer).obj;
} }