🚀 Add xdelta3 support

This commit is contained in:
C-3PO 2018-07-09 18:29:46 +02:00
parent b5037c2a71
commit 6bb8ccea22
Signed by: c3po
GPG key ID: 62993C4BB4D86F24
2 changed files with 52 additions and 3 deletions

View file

@ -11,6 +11,7 @@ import readSsnFile from './reader/readSsnFile';
import getFileFromDisks from './streams/getFileFromDisks'; import getFileFromDisks from './streams/getFileFromDisks';
import verifyPatch from './verify/verifyPatch'; import verifyPatch from './verify/verifyPatch';
import verifyProductName from './verify/verifyProductName'; import verifyProductName from './verify/verifyProductName';
import performDiffing from './xdelta3/performDiffing';
interface IGetPatchArgs { interface IGetPatchArgs {
/** The product that should be patched. */ /** The product that should be patched. */
@ -103,9 +104,31 @@ export default async function getPatch({ product, from, to, sourceDirectory, tar
const fileStream = await getFileFromDisks(diskFilenames, { diskStart: file.diskNumberStart, offset: file.offset, length: file.compressedSize }); const fileStream = await getFileFromDisks(diskFilenames, { diskStart: file.diskNumberStart, offset: file.offset, length: file.compressedSize });
const fileContents = await extractFileAsStream(file, fileStream); const fileContents = await extractFileAsStream(file, fileStream);
//TODO: need to apply xdelta3 diffing, then write to disk //need to apply xdelta3 diffing, then write to disk
//if source === target, need to create .temp file, and when it's done, delete source file and rename .temp to actual name const sourceFile = path.join(sourceDir, file.name);
console.warn(`Could not extract "${file.name}"; xdelta3 diffing is not yet implemented.`); const outputName = path.join(targetDir, file.name);
const outputNameTemp = `${outputName}.tmp`;
await performDiffing(sourceFile, fileContents, outputNameTemp);
//clean up: delete source file if necessary, and remove .tmp file extension
if (sourceDir === targetDir) {
fs.unlink(sourceFile, (deleteError) => {
if (deleteError) {
throw new Error(`Could not delete old source file "${sourceFile}": ${deleteError.name}`);
}
fs.rename(outputNameTemp, outputName, (renameError) => {
if (renameError) {
throw new Error(`Could not rename output file "${outputNameTemp}": ${renameError.name}`);
}
});
});
} else {
fs.rename(outputNameTemp, outputName, (renameError) => {
if (renameError) {
throw new Error(`Could not rename output file "${outputNameTemp}": ${renameError.name}`);
}
});
}
} catch (error) { } catch (error) {
console.error(`Could not extract file "${file.name}"`, error); console.error(`Could not extract file "${file.name}"`, error);
} }

View file

@ -0,0 +1,26 @@
import * as childProcess from 'child_process';
import * as fs from 'fs';
import * as stream from 'stream';
export default function performDiffing(sourceFile: string, diffStream: stream.Readable, targetFile: string): Promise<void> {
return new Promise((resolve, reject) => {
//const sourceStream = fs.createReadStream(sourceFile);
const targetStream = fs.createWriteStream(targetFile);
//spawn xdelta3 process, set up listeners
const process = childProcess.spawn('xdelta3', ['-d', '-s', sourceFile]);
diffStream.pipe(process.stdin);
process.stdout.pipe(targetStream);
process.stderr.on('data', (chunk) => {
reject(`Error during xdelta3: ${chunk}`);
});
process.on('exit', (code, signal) => {
if (code === 0) {
resolve();
} else {
reject(`xdelta3 exited with code "${code}" due to signal "${signal}".`);
}
});
});
}