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(); }
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 Send_will_seek_past_input_data_for_copy_delta() { var deltas = new[] {new CopyDelta {Offset = 0, Length = 1234}}; var dataStreamMock = new Mock<MemoryStream>(MockBehavior.Strict); dataStreamMock.Setup(x => x.Seek( It.Is<long>(o => o == 1234), It.Is<SeekOrigin>(o => o == SeekOrigin.Current))) .Returns(1234); dataStreamMock.SetupGet(x => x.CanSeek).Returns(true); var streamer = new DeltaStreamer(); streamer.Send(deltas, dataStreamMock.Object, new MemoryStream()); dataStreamMock.VerifyAll(); }
public void Send_will_chunk_data_reads_into_provided_sizes_for_byte_delta() { var streamer = new DeltaStreamer(); int chunkSize = 10; streamer.StreamChunkSize = chunkSize; var deltas = new[] {new ByteDelta {Offset = 0, Length = 100}}; var dataStreamMock = new Mock<MemoryStream>(); dataStreamMock.Setup(x => x.Read(It.IsAny<byte[]>(), It.IsAny<int>(), It.IsAny<int>())) .Returns((byte[] buf, int offset, int length) => { if (length > chunkSize) Assert.Fail("Invalid read size"); return length; }); streamer.Send(deltas, dataStreamMock.Object, new MemoryStream()); }
public void Send_will_read_all_chunks_from_stream_for_byte_delta() { var streamer = new DeltaStreamer(); int chunkSize = 10; streamer.StreamChunkSize = chunkSize; var deltas = new[] {new ByteDelta {Offset = 0, Length = 100}}; var dataStreamMock = new Mock<MemoryStream>(); int totalLengthRead = 0; dataStreamMock.Setup(x => x.Read(It.IsAny<byte[]>(), It.IsAny<int>(), It.IsAny<int>())) .Returns((byte[] buf, int offset, int length) => { totalLengthRead += length; return length; }); streamer.Send(deltas, dataStreamMock.Object, new MemoryStream()); Assert.AreEqual(100, totalLengthRead); }
public void Send_throws_for_null_deltas() { var streamer = new DeltaStreamer(); streamer.Send(null, new MemoryStream(), new MemoryStream()); }
public void Send_throws_for_null_output_stream() { var streamer = new DeltaStreamer(); streamer.Send(new ByteDelta[10], new MemoryStream(), null); }
public void Send_throws_for_inputStream_without_forward_seekability_for_copy_delta() { var deltas = new[] {new CopyDelta {Offset = 0, Length = 1234}}; var dataStreamMock = new Mock<MemoryStream>(MockBehavior.Strict); dataStreamMock.SetupGet(x => x.CanSeek).Returns(false); var streamer = new DeltaStreamer(); streamer.Send(deltas, dataStreamMock.Object, new MemoryStream()); }
public void Send_throws_for_inputStream_with_insufficient_data_for_byte_delta() { var deltas = new[] {new ByteDelta {Offset = 0, Length = 3}}; var dataStream = new MemoryStream(new byte[2]); var streamer = new DeltaStreamer(); streamer.Send(deltas, dataStream, new MemoryStream()); }
public void Send_throws_for_delta_out_of_inputStream_bounds_for_byte_delta() { var deltas = new[] {new ByteDelta {Offset = 3, Length = 3}}; var dataStream = new MemoryStream(new byte[2]); var streamer = new DeltaStreamer(); streamer.Send(deltas, dataStream, new MemoryStream()); }
public void Send_throws_for_empty_delta_array() { var deltas = new List<IDelta>(); var streamer = new DeltaStreamer(); streamer.Send(deltas, new MemoryStream(), new MemoryStream()); }
public void Send_starts_with_new_command_for_byte_delta() { var streamer = new DeltaStreamer(); var deltas = new[] {new ByteDelta {Offset = 0, Length = 4}}; var dataStream = new MemoryStream(Encoding.ASCII.GetBytes("TEST")); var outStream = new MemoryStream(); streamer.Send(deltas, dataStream, outStream); Assert.AreEqual(DeltaStreamer.DeltaStreamConstants.NEW_BLOCK_START_MARKER, outStream.GetBuffer()[0]); }
public void Send_starts_with_copy_command_for_copy_delta() { var streamer = new DeltaStreamer(); var deltas = new[] {new CopyDelta {Offset = 42, Length = 24}}; var outStream = new MemoryStream(); streamer.Send(deltas, new MemoryStream(), outStream); Assert.AreEqual(DeltaStreamer.DeltaStreamConstants.COPY_BLOCK_START_MARKER, outStream.GetBuffer()[0]); }
public void Send_has_correct_offset_for_copy_delta() { var streamer = new DeltaStreamer(); var deltas = new[] {new CopyDelta {Offset = 42, Length = 24}}; var outStream = new MemoryStream(); streamer.Send(deltas, new MemoryStream(), outStream); Assert.AreEqual(42, BitConverter.ToInt64(outStream.GetBuffer(), 1)); }
public void Send_has_correct_length_for_byte_delta() { var streamer = new DeltaStreamer(); var deltas = new[] {new ByteDelta {Offset = 0, Length = 4}}; var dataStream = new MemoryStream(Encoding.ASCII.GetBytes("TEST")); var outStream = new MemoryStream(); streamer.Send(deltas, dataStream, outStream); Assert.AreEqual(4, BitConverter.ToInt32(outStream.GetBuffer(), 1)); }
public void Send_has_correct_data_for_byte_delta() { var streamer = new DeltaStreamer(); streamer.StreamChunkSize = 2; var deltas = new[] {new ByteDelta {Offset = 0, Length = 4}}; var dataStream = new MemoryStream(Encoding.ASCII.GetBytes("TEST")); var outStream = new MemoryStream(); streamer.Send(deltas, dataStream, outStream); Assert.IsTrue(Encoding.ASCII.GetBytes("TEST").SequenceEqual(outStream.GetBuffer().Skip(5).Take(4))); }