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();
        }
예제 #2
0
        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();
                }
            }
        }
예제 #3
0
 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();
 }
예제 #4
0
 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());
 }
예제 #5
0
 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);
 }
예제 #6
0
 public void Send_throws_for_null_deltas()
 {
     var streamer = new DeltaStreamer();
     streamer.Send(null, new MemoryStream(), new MemoryStream());
 }
예제 #7
0
 public void Send_throws_for_null_output_stream()
 {
     var streamer = new DeltaStreamer();
     streamer.Send(new ByteDelta[10], new MemoryStream(), null);
 }
예제 #8
0
 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());
 }
예제 #9
0
 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());
 }
예제 #10
0
 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());
 }
예제 #11
0
 public void Send_throws_for_empty_delta_array()
 {
     var deltas = new List<IDelta>();
     var streamer = new DeltaStreamer();
     streamer.Send(deltas, new MemoryStream(), new MemoryStream());
 }
예제 #12
0
 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]);
 }
예제 #13
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]);
 }
예제 #14
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));
 }
예제 #15
0
 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));
 }
예제 #16
0
 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)));
 }