public void MaxFileSize_Test() { using var srcStream = File.OpenRead($"patches{Path.DirectorySeparatorChar}a.test"); using var targetStream = File.OpenRead($"patches{Path.DirectorySeparatorChar}b.test"); using var deltaStream = new MemoryStream(); using var outputStream = new MemoryStream(); using VcEncoder coder = new VcEncoder(srcStream, targetStream, deltaStream); VCDiffResult result = coder.Encode(); Assert.Equal(VCDiffResult.SUCCESS, result); srcStream.Position = 0; targetStream.Position = 0; deltaStream.Position = 0; long bytesWritten = 0; using VcDecoder decoder = new VcDecoder(srcStream, deltaStream, outputStream, -1); ArgumentException ex = Assert.Throws <ArgumentException>(() => decoder.Decode(out bytesWritten)); Assert.Matches(@"maxWindowSize must be a positive value", ex.Message); srcStream.Position = 0; targetStream.Position = 0; deltaStream.Position = 0; using VcDecoder decoder1 = new VcDecoder(srcStream, deltaStream, outputStream, 2); InvalidOperationException ex1 = Assert.Throws <InvalidOperationException>(() => decoder1.Decode(out bytesWritten)); Assert.Matches(@"Length of target window \(\d*\) exceeds limit of 2 bytes", ex1.Message); }
public void NoChecksumGoogleTo_Test() { using var srcStream = File.OpenRead($"patches{Path.DirectorySeparatorChar}size-overflow-64"); using var targetStream = File.OpenRead($"patches{Path.DirectorySeparatorChar}size-overflow-32"); using var md5 = MD5.Create(); var originalHash = md5.ComputeHash(targetStream); targetStream.Position = 0; using var deltaStream = new MemoryStream(); using var outputStream = new MemoryStream(); using VcEncoder coder = new VcEncoder(srcStream, targetStream, deltaStream); VCDiffResult result = coder.Encode(); Assert.Equal(VCDiffResult.SUCCESS, result); srcStream.Position = 0; targetStream.Position = 0; deltaStream.Position = 0; using VcDecoder decoder = new VcDecoder(srcStream, deltaStream, outputStream); Assert.Equal(VCDiffResult.SUCCESS, decoder.Decode(out long bytesWritten)); outputStream.Position = 0; var outputHash = md5.ComputeHash(outputStream); Assert.Equal(originalHash, outputHash); }
public void ChecksumHashLarge_block_Test() { using var srcStream = File.OpenRead($"patches{Path.DirectorySeparatorChar}a.test"); using var targetStream = File.OpenRead($"patches{Path.DirectorySeparatorChar}b.test"); using var md5 = MD5.Create(); var originalHash = md5.ComputeHash(targetStream); targetStream.Position = 0; using var deltaStream = new MemoryStream(); using var outputStream = new MemoryStream(); using VcEncoder coder = new VcEncoder(srcStream, targetStream, deltaStream, blockSize: 32); VCDiffResult result = coder.Encode(checksumFormat: ChecksumFormat.SDCH); //encodes with no checksum and not interleaved Assert.Equal(VCDiffResult.SUCCESS, result); srcStream.Position = 0; targetStream.Position = 0; deltaStream.Position = 0; using VcDecoder decoder = new VcDecoder(srcStream, deltaStream, outputStream); Assert.Equal(VCDiffResult.SUCCESS, decoder.Decode(out long bytesWritten)); outputStream.Position = 0; var outputHash = md5.ComputeHash(outputStream); Assert.Equal(originalHash, outputHash); }
public void Interleaved_Test() { using var srcStream = File.OpenRead($"patches{Path.DirectorySeparatorChar}a.test"); using var targetStream = File.OpenRead($"patches{Path.DirectorySeparatorChar}b.test"); using var deltaStream = new MemoryStream(); using var outputStream = new MemoryStream(); using var md5 = MD5.Create(); var originalHash = md5.ComputeHash(targetStream); targetStream.Position = 0; using VcEncoder coder = new VcEncoder(srcStream, targetStream, deltaStream); VCDiffResult result = coder.Encode(interleaved: true); //encodes with no checksum and not interleaved Assert.Equal(VCDiffResult.SUCCESS, result); srcStream.Position = 0; targetStream.Position = 0; deltaStream.Position = 0; using VcDecoder decoder = new VcDecoder(srcStream, deltaStream, outputStream); long bytesWritten = 0; while (bytesWritten < targetStream.Length) { Assert.Equal(VCDiffResult.SUCCESS, decoder.Decode(out long chunk)); bytesWritten += chunk; } outputStream.Position = 0; var outputHash = md5.ComputeHash(outputStream); Assert.Equal(originalHash, outputHash); }
public async Task ExternTest_ImplAsync(string patchfile) { using var srcStream = File.OpenRead($"patches{Path.DirectorySeparatorChar}a.test"); using var targetStream = File.OpenRead($"patches{Path.DirectorySeparatorChar}b.test"); using var deltaStream = File.OpenRead($"patches{Path.DirectorySeparatorChar}{patchfile}"); using var md5 = MD5.Create(); targetStream.Position = 0; var originalHash = md5.ComputeHash(targetStream); using var outputStream = new MemoryStream(); outputStream.Position = 0; srcStream.Position = 0; targetStream.Position = 0; deltaStream.Position = 0; using VcDecoder decoder = new VcDecoder(srcStream, deltaStream, outputStream); (VCDiffResult result, _) = await decoder.DecodeAsync(); Assert.Equal(VCDiffResult.SUCCESS, result); outputStream.Position = 0; var outputHash = md5.ComputeHash(outputStream); Assert.Equal(originalHash, outputHash); }
public void MaxFileSize_Test() { using var srcStream = File.OpenRead($"patches{Path.DirectorySeparatorChar}a.test"); using var targetStream = File.OpenRead($"patches{Path.DirectorySeparatorChar}b.test"); using var deltaStream = new MemoryStream(); using var outputStream = new MemoryStream(); using VcEncoder coder = new VcEncoder(srcStream, targetStream, deltaStream); VCDiffResult result = coder.Encode(); Assert.Equal(VCDiffResult.SUCCESS, result); srcStream.Position = 0; targetStream.Position = 0; deltaStream.Position = 0; long bytesWritten = 0; using VcDecoder decoder = new VcDecoder(srcStream, deltaStream, outputStream, -1); Assert.Throws <ArgumentException>(() => decoder.Decode(out bytesWritten)); srcStream.Position = 0; targetStream.Position = 0; deltaStream.Position = 0; using VcDecoder decoder1 = new VcDecoder(srcStream, deltaStream, outputStream, 2); Assert.Throws <InvalidOperationException>(() => decoder1.Decode(out bytesWritten)); }
public void TestEncodeAndDecodeShouldBeTheSame() { int size = 20 * 1024 * 1024; // 20 MB byte[] oldData = CreateRandomByteArray(size); byte[] newData = new byte[size]; oldData.CopyTo(newData, 0); AddRandomPiecesIn(oldData); var sOld = new MemoryStream(oldData); var sNew = new MemoryStream(newData); var sDelta = new MemoryStream(new byte[size], true); var coder = new VcEncoder(sOld, sNew, sDelta); Assert.Equal(VCDiffResult.SUCCESS, coder.Encode()); sDelta.SetLength(sDelta.Position); sDelta.Position = 0; sOld.Position = 0; sNew.Position = 0; var sPatched = new MemoryStream(new byte[size], true); var decoder = new VcDecoder(sOld, sDelta, sPatched); Assert.Equal(VCDiffResult.SUCCESS, decoder.Decode(out long bytesWritten)); Assert.Equal(sNew.ToArray(), sPatched.ToArray()); }
public void Interleaved_Test() { using var srcStream = new MemoryStream(ADiffData.ToArray()); using var targetStream = new MemoryStream(BDiffData.ToArray()); using var deltaStream = new MemoryStream(); using var outputStream = new MemoryStream(); VcEncoder coder = new VcEncoder(srcStream, targetStream, deltaStream); VCDiffResult result = coder.Encode(interleaved: true); //encodes with no checksum and not interleaved Assert.Equal(VCDiffResult.SUCCESS, result); srcStream.Position = 0; targetStream.Position = 0; deltaStream.Position = 0; VcDecoder decoder = new VcDecoder(srcStream, deltaStream, outputStream); long bytesWritten = 0; while (bytesWritten < BDiffData.Length) { Assert.Equal(VCDiffResult.SUCCESS, decoder.Decode(out long chunk)); bytesWritten += chunk; } Assert.Equal("Goodbye World", Encoding.UTF8.GetString(outputStream.ToArray())); }
public void DecodeHeavilyModified() { using var result = new MemoryStream((int)_sourceStream.Length); for (int x = 0; x < RepeatCount; x++) { _sourceStream.Seek(0, SeekOrigin.Begin); _patchHeavyModified.Seek(0, SeekOrigin.Begin); result.Position = 0; using var decoder = new VcDecoder(_sourceStream, _patchHeavyModified, result, int.MaxValue); decoder.Decode(out long written); } }
/// <summary> /// Perform VCDiff decode (apply a diff). /// </summary> /// <param name="original">Original file data.</param> /// <param name="patch">Diff data.</param> /// <returns>Modified file data.</returns> static byte[] VcDiffDecodeManaged(byte[] original, byte[] patch) { using var output = new MemoryStream(); using var dict = new MemoryStream(original); using var target = new MemoryStream(patch); // Decode using patch data. var decoder = new VcDecoder(dict, target, output); if (decoder.Decode(out var written) != VCDiffResult.SUCCESS) { throw new Exception("VCDiff decode failed."); } return(output.ToArray()); }
public void NoChecksumNoInterleaved_Test() { using var srcStream = File.OpenRead($"patches{Path.DirectorySeparatorChar}a.test"); using var targetStream = File.OpenRead($"patches{Path.DirectorySeparatorChar}b.test"); using var deltaStream = new MemoryStream(); using var outputStream = new MemoryStream(); using VcEncoder coder = new VcEncoder(srcStream, targetStream, deltaStream); VCDiffResult result = coder.Encode(); //encodes with no checksum and not interleaved Assert.Equal(VCDiffResult.SUCCESS, result); srcStream.Position = 0; targetStream.Position = 0; deltaStream.Position = 0; using VcDecoder decoder = new VcDecoder(srcStream, deltaStream, outputStream); Assert.Equal(VCDiffResult.SUCCESS, decoder.Decode(out long bytesWritten)); Assert.NotEqual(0, bytesWritten); }
public void WinIndicator_Zero() { var inputStream = File.OpenRead($"patches{Path.DirectorySeparatorChar}empty.test"); var targetStream = File.OpenRead($"patches{Path.DirectorySeparatorChar}win_indicator_zero.test"); var deltaStream = File.OpenRead($"patches{Path.DirectorySeparatorChar}win_indicator_zero.xdelta"); using var md5 = MD5.Create(); targetStream.Position = 0; var originalHash = md5.ComputeHash(targetStream); using var outputStream = new MemoryStream(); var decoder = new VcDecoder(inputStream, deltaStream, outputStream); Assert.Equal(VCDiffResult.SUCCESS, decoder.Decode(out long bytesWritten)); outputStream.Position = 0; var outputHash = md5.ComputeHash(outputStream); Assert.Equal(originalHash, outputHash); }
public void Checksum_Test() { using var srcStream = new MemoryStream(ADiffData.ToArray()); using var targetStream = new MemoryStream(BDiffData.ToArray()); using var deltaStream = new MemoryStream(); using var outputStream = new MemoryStream(); VcEncoder coder = new VcEncoder(srcStream, targetStream, deltaStream); VCDiffResult result = coder.Encode(checksumFormat: ChecksumFormat.SDCH); //encodes with no checksum and not interleaved Assert.Equal(VCDiffResult.SUCCESS, result); srcStream.Position = 0; targetStream.Position = 0; deltaStream.Position = 0; VcDecoder decoder = new VcDecoder(srcStream, deltaStream, outputStream); Assert.Equal(VCDiffResult.SUCCESS, decoder.Decode(out long bytesWritten)); Assert.Equal("Goodbye World", Encoding.UTF8.GetString(outputStream.ToArray())); }
private async Task CopyRecursiveDiffs(IDirectory outputDirectory) { var diffDir = this.DiffDir.OpenDirectory("diff"); // Do the parent directory foreach (var f in this.BaseDir.EnumerateFiles()) { if (!diffDir.ContainsFile(f.Name)) { continue; } using var baseStream = f.OpenReadStream(); using var diffStream = diffDir.OpenFile(f.Name).OpenReadStream(); using var outStream = outputDirectory.OpenFile(f.Name).OpenStream(); using var decoder = new VcDecoder(baseStream, diffStream, outStream); (VCDiffResult result, var _) = await decoder.DecodeAsync(); if (result != VCDiffResult.SUCCESS) { throw new IOException($"Failed to decode delta for {f.Name}"); } } var queuedDirs = (from baseDir in this.BaseDir.EnumerateDirectories() where diffDir.ContainsDirectory(baseDir.Name) select(outputDirectory, baseDir, diffDir.OpenDirectory(baseDir.Name))).ToList(); // BFS over all the children. Queue <(IDirectory parentDir, IDeletableDirectory baseDir, IDeletableDirectory diffDir)> dirsToProcess = new Queue <(IDirectory, IDeletableDirectory, IDeletableDirectory)>(queuedDirs); while (dirsToProcess.Count > 0) { var(parent, src, diff) = dirsToProcess.Dequeue(); var dst = parent.OpenDirectory(src.Name); foreach (var f in src.EnumerateFiles()) { if (!diff.ContainsFile(f.Name)) { continue; } using var baseStream = f.OpenReadStream(); using var diffStream = diff.OpenFile(f.Name).OpenReadStream(); using var outStream = dst.OpenFile(f.Name).OpenStream(); using var decoder = new VcDecoder(baseStream, diffStream, outStream); (VCDiffResult result, var _) = await decoder.DecodeAsync(); if (result != VCDiffResult.SUCCESS) { throw new IOException($"Failed to decode delta for {f.Name}"); } } var children = from baseDir in src.EnumerateDirectories() where diff.ContainsDirectory(baseDir.Name) select(dst, baseDir, diff.OpenDirectory(baseDir.Name)); foreach (var childDirectory in children) { dirsToProcess.Enqueue(childDirectory); } } }