public static byte[] CreatePatchFor(string filename1, string filename2) { // Compute hashes HashBlock[] hashBlocksFromReceiver; using (FileStream sourceStream = File.Open(filename1, FileMode.Open)) { hashBlocksFromReceiver = new HashBlockGenerator(new RollingChecksum(), new HashAlgorithmWrapper <MD5>(MD5.Create()), blockSize).ProcessStream(sourceStream).ToArray(); } // Compute deltas MemoryStream deltaStream = new MemoryStream(); using (FileStream fileStream = File.Open(filename2, FileMode.Open)) { DeltaGenerator deltaGen = new DeltaGenerator(new RollingChecksum(), new HashAlgorithmWrapper <MD5>(MD5.Create())); deltaGen.Initialize(blockSize, hashBlocksFromReceiver); IEnumerable <IDelta> deltas = deltaGen.GetDeltas(fileStream); deltaGen.Statistics.Dump(); fileStream.Seek(0, SeekOrigin.Begin); DeltaStreamer streamer = new DeltaStreamer(); streamer.Send(deltas, fileStream, deltaStream); } return(deltaStream.ToArray()); }
public void GetDeltas_returns_three_CopyDeltas_object_when_matching_hash_is_provided_for_triple_repeat() { var checksumMock = new Mock <IRollingChecksum>(); checksumMock.Setup(x => x.Value).Returns(0); var hashMock = new Mock <IHashAlgorithm>(); byte[] dummyBytes = InitializeDummyMD5Hash(hashMock); var gen = new DeltaGenerator(checksumMock.Object, hashMock.Object); int blockSize = 10; var magicHashBlock = new HashBlock { Checksum = 0, Hash = dummyBytes, Offset = 42, Length = 43 }; gen.Initialize(blockSize, new[] { magicHashBlock }); var bytes = new byte[blockSize * 3]; for (int i = 0; i < bytes.Length; ++i) { bytes[i] = 0; } IEnumerable <IDelta> deltas = gen.GetDeltas(new MemoryStream(bytes)); Assert.AreEqual(3, deltas.Count()); Assert.IsTrue(deltas.All(d => d is CopyDelta)); Assert.IsTrue(deltas.All(d => (d as CopyDelta).Offset == magicHashBlock.Offset)); }
static void Main(string[] args) { int blockSize = 512; // Compute hashes IEnumerable <HashBlock> hashBlocksFromReceiver; using (FileStream sourceStream = File.Open("../../dest.bmp", FileMode.Open)) { hashBlocksFromReceiver = new HashBlockGenerator(new RollingChecksum(), new HashAlgorithmWrapper <MD5>(MD5.Create()), blockSize).ProcessStream(sourceStream).ToArray(); } // Stream the hash blocks var hashBlockStream = new MemoryStream(); HashBlockStreamer.Stream(hashBlocksFromReceiver, hashBlockStream); // Receive the hash block stream hashBlockStream.Seek(0, SeekOrigin.Begin); Console.Out.WriteLine("Hash block stream length: {0}", hashBlockStream.Length); hashBlocksFromReceiver = HashBlockStreamer.Destream(hashBlockStream); // Compute deltas var deltaStream = new MemoryStream(); using (FileStream fileStream = File.Open("../../source.bmp", FileMode.Open)) { var deltaGen = new DeltaGenerator(new RollingChecksum(), new HashAlgorithmWrapper <MD5>(MD5.Create())); deltaGen.Initialize(blockSize, hashBlocksFromReceiver); IEnumerable <IDelta> deltas = deltaGen.GetDeltas(fileStream); deltaGen.Statistics.Dump(); fileStream.Seek(0, SeekOrigin.Begin); var streamer = new DeltaStreamer(); streamer.Send(deltas, fileStream, deltaStream); Console.Out.WriteLine("Delta stream length: {0}", deltaStream.Length); } // Rewind the delta stream (obviously wouldn't apply from a network pipe) deltaStream.Seek(0, SeekOrigin.Begin); // Reconstruct file using (FileStream sourceStream = File.Open("../../dest.bmp", FileMode.Open)) { using (FileStream outStream = File.Open("../../reconstructed.bmp", FileMode.Create)) { var streamer = new DeltaStreamer(); streamer.Receive(deltaStream, sourceStream, outStream); outStream.Close(); } } }
public void GetDeltas_throws_for_null_stream() { var dummyBlock = new HashBlock { Checksum = 0, Length = 0, Offset = 0, Hash = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8 } }; DeltaGenerator gen = GetValidDeltaGenerator(); gen.Initialize(10, new[] { dummyBlock }); gen.GetDeltas(null).Count(); }
public void GetDeltas_returns_one_ByteDelta_object_when_no_hashes_are_provided() { DeltaGenerator gen = GetValidDeltaGenerator(); int blockSize = 10; gen.Initialize(blockSize, null); var bytes = new byte[blockSize * 3]; for (int i = 0; i < bytes.Length; ++i) { bytes[i] = (byte)(bytes.Length - i); } IEnumerable <IDelta> deltas = gen.GetDeltas(new MemoryStream(bytes)); Assert.AreEqual(1, deltas.Count()); Assert.IsInstanceOfType(deltas.First(), typeof(ByteDelta)); var byteDelta = deltas.First() as ByteDelta; Assert.AreEqual(0, byteDelta.Offset); Assert.AreEqual(bytes.Length, byteDelta.Length); }
public void GetDeltas_returns_two_CopyDelta_objects_and_a_middle_ByteDelta_for_interspaced_new_data() { var checksumMock = new Mock <IRollingChecksum>(); int checksumCallNumber = 0; // Returns "1" for calls number 2 through 11 inclusive. checksumMock.Setup(x => x.Value) .Returns(() => (uint)(++checksumCallNumber > 1 && checksumCallNumber <= 11 ? 1 : 0)); var hashMock = new Mock <IHashAlgorithm>(); byte[] dummyBytes = InitializeDummyMD5Hash(hashMock); var gen = new DeltaGenerator(checksumMock.Object, hashMock.Object); int blockSize = 10; var magicHashBlock = new HashBlock { Checksum = 0, Hash = dummyBytes, Offset = 42, Length = 43 }; gen.Initialize(blockSize, new[] { magicHashBlock }); var bytes = new byte[blockSize * 3]; for (int i = 0; i < bytes.Length; ++i) { bytes[i] = 0; } // Should immediately get a match for an entire block. // Then upon trying to match a new one get a mismatch for the next // 10 bytes IEnumerable <IDelta> deltas = gen.GetDeltas(new MemoryStream(bytes)); Assert.AreEqual(3, deltas.Count()); Assert.IsTrue( deltas.ElementAt(0) is CopyDelta && deltas.ElementAt(1) is ByteDelta && deltas.ElementAt(2) is CopyDelta); Assert.AreEqual(10, (deltas.ElementAt(1) as ByteDelta).Offset); Assert.AreEqual(10, (deltas.ElementAt(1) as ByteDelta).Length); }
public void Initialize_throws_for_zero_blocksize() { DeltaGenerator gen = GetValidDeltaGenerator(); gen.Initialize(0, new HashBlock[10]); }
public void Initialize_throws_for_negative_blocksize() { DeltaGenerator gen = GetValidDeltaGenerator(); gen.Initialize(-1, new HashBlock[10]); }
public void Initialize_accepts_null_hashblock_array() { DeltaGenerator gen = GetValidDeltaGenerator(); gen.Initialize(10, null); }
public void GetDeltas_throws_if_not_initialized() { DeltaGenerator gen = GetValidDeltaGenerator(); gen.GetDeltas(new MemoryStream()); }