diff --git a/src/ssn/streams/getFileFromDisks.ts b/src/ssn/streams/getFileFromDisks.ts index 220cf57..1aebc3f 100644 --- a/src/ssn/streams/getFileFromDisks.ts +++ b/src/ssn/streams/getFileFromDisks.ts @@ -12,7 +12,7 @@ interface IGetFileFromDisksOptions { } function getStream(disks: string[], index: number, offset: number, length: number = Infinity) { - return fs.createReadStream(disks[index], { start: offset }); + return fs.createReadStream(disks[index], { start: offset, end: offset + length - 1 }); } /** Takes a list of ReadableStreams (the disks), as well as the offset and length, and returns a stream for just one file. */ @@ -26,12 +26,23 @@ export default async function getFileFromDisks(disks: string[], { diskStart, off const outputStream = new stream.PassThrough(); const onData = (chunk: Buffer) => { - outputStream.write(chunk); totalRead += chunk.length; - //need to end if we have read beyond the file - //TODO: need to also shorten chunk if file ended inside it, before writing it to PassThrough. - if (localFileHeaderLength !== 0 && totalRead >= localFileHeaderLength + storedSize) { - outputStream.end(); + //If we've reached the end, we can stop reading after this chunk + const readTooManyBytes = totalRead - (localFileHeaderLength + storedSize); + if (localFileHeaderLength !== 0 && readTooManyBytes >= 0) { + //We can still write the whole chunk before ending the stream + if (readTooManyBytes === 0) { + outputStream.end(chunk); + } else { + //We must shorten the chunk, write the shortened chunk and the end the stream + const shortenedLength = chunk.length - readTooManyBytes; + const shortenedChunk = new Buffer(shortenedLength); + shortenedChunk.fill(chunk, 0, shortenedLength); + outputStream.end(shortenedChunk); + } + } else { + //Nowhere near the end, so just write normally + outputStream.write(chunk); } }; const onError = (error: any) => { @@ -57,8 +68,7 @@ export default async function getFileFromDisks(disks: string[], { diskStart, off //Read local file header localFileHeaderLength = await readLocalFileHeader(outputStream); - - //TODO: now that local file header has been read, restrict length of stream to storedSize + //now that local file header has been read, we will restrict length of stream to storedSize return outputStream; } diff --git a/src/ssn/streams/readLocalFileHeader.ts b/src/ssn/streams/readLocalFileHeader.ts index 854cafd..b47530b 100644 --- a/src/ssn/streams/readLocalFileHeader.ts +++ b/src/ssn/streams/readLocalFileHeader.ts @@ -25,7 +25,6 @@ export default async function readLocalFileHeader(inputStream: stream.Readable): } //Local file header signature - console.log(localFileHeader); const magic = localFileHeader.readUInt32LE(0); if (magic !== 0x04034B50) { throw new Error(`Local file header had wrong magic; expected 0x04034B50 but got 0x${magic.toString(16).padStart(8, '0')}.`);