public void Receive_copies_data_from_inputStream() { var deltaStream = new MemoryStream(); deltaStream.WriteByte(DeltaStreamer.DeltaStreamConstants.COPY_BLOCK_START_MARKER); deltaStream.WriteLong(4); // Start the copy from byte four deltaStream.WriteInt(10); // Copy 10 bytes deltaStream.Seek(0, SeekOrigin.Begin); var inputStream = new MemoryStream(); // Must have 4 + 10 bytes for (int i = 0; i < 20; ++i) { inputStream.WriteByte((byte)(255 - i)); } inputStream.Seek(0, SeekOrigin.Begin); var outputStream = new MemoryStream(); var streamer = new DeltaStreamer(); streamer.Receive(deltaStream, inputStream, outputStream); Assert.AreEqual(10, outputStream.Length); outputStream.GetBuffer().Take(14).SequenceEqual(inputStream.GetBuffer().Skip(3).Take(14)); }
public void Receive_throws_for_unseekable_inputStream() { var inputStreamMock = new Mock <MemoryStream>(MockBehavior.Strict); inputStreamMock.SetupGet(x => x.CanSeek).Returns(false); var streamer = new DeltaStreamer(); streamer.Receive(new MemoryStream(), inputStreamMock.Object, new MemoryStream()); }
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 Receive_writes_new_bytes_from_deltaStream() { var deltaStream = new MemoryStream(); deltaStream.WriteByte(DeltaStreamer.DeltaStreamConstants.NEW_BLOCK_START_MARKER); deltaStream.WriteInt(10); // Write 10 bytes for (int i = 0; i < 10; ++i) { deltaStream.WriteByte((byte)(200 - i)); } deltaStream.Seek(0, SeekOrigin.Begin); var inputStream = new MemoryStream(); // empty var outputStream = new MemoryStream(); var streamer = new DeltaStreamer(); streamer.Receive(deltaStream, inputStream, outputStream); Assert.AreEqual(10, outputStream.Length); outputStream.GetBuffer().Take(10).SequenceEqual(deltaStream.GetBuffer().Skip(5).Take(10)); }
public static void ApplyPatch(string filename, Action <string, int> progressCallback) { using (FileStream fs = File.OpenRead(filename)) { using (ZipFile zf = new ZipFile(fs)) { progressCallback(App.resourceManager.GetString("unpacking_patch_info"), 0); List <FileEntry> entries = ParsePatchInfo(ExtractData(zf, "patch_info.txt")); for (int i = 0; i < entries.Count; i++) { int percent = (int)(((float)i / entries.Count) * 100); FileEntry entry = entries[i]; string entryFilename = Path.Combine(App.targetDirectory, entry.filename); Debug.WriteLine(entryFilename); // these files are skipped, maybe skip these in the patch builder instead? if (entryFilename.Contains("Launcher") || entryFilename.Contains("version.txt")) { continue; } if (entry.type == FileEntry.EntryType.Removed) { progressCallback(String.Format(App.resourceManager.GetString("deleting_file"), entry.filename), percent); if (File.Exists(entryFilename)) { File.Delete(entryFilename); } } if (entry.type == FileEntry.EntryType.Added) { progressCallback(String.Format(App.resourceManager.GetString("adding_file"), entry.filename), percent); ExtractFile(zf, entry.filename, entryFilename); } if (entry.type == FileEntry.EntryType.Modified) { progressCallback(String.Format(App.resourceManager.GetString("checking_file"), entry.filename), percent); if (checkMD5s) { string md5_old = GetMD5HashFromFile(entryFilename); if (entry.md5Old != md5_old) { throw new PatcherException(String.Format(App.resourceManager.GetString("invalid_patch"), entryFilename)); } } string patched_file = Path.GetTempFileName(); progressCallback(String.Format(App.resourceManager.GetString("patching_file"), entry.filename), percent); try { using (FileStream sourceStream = File.Open(entryFilename, FileMode.Open)) { using (FileStream outStream = File.Open(patched_file, FileMode.Create)) { DeltaStreamer streamer = new DeltaStreamer(); streamer.Receive(ExtractStream(zf, entry.filename), sourceStream, outStream); outStream.Close(); } } } catch (DirectoryNotFoundException ex) { throw new PatcherException(ex.Message); } progressCallback(string.Format(App.resourceManager.GetString("copying_file"), entry.filename), percent); File.Copy(patched_file, entryFilename, true); File.Delete(patched_file); } if (entry.type == FileEntry.EntryType.Added || entry.type == FileEntry.EntryType.Modified) { progressCallback(string.Format(App.resourceManager.GetString("checking_file"), entry.filename), percent); if (checkMD5s) { string md5New = GetMD5HashFromFile(entryFilename); if (entry.md5New != md5New) { throw new PatcherException(string.Format(App.resourceManager.GetString("patch_broke_client"), entryFilename)); } } } } } } }
public static void ApplyPatch(string filename, Action <string, int> progressCallback) { using (FileStream fs = File.OpenRead(filename)) { using (ZipFile zf = new ZipFile(fs)) { progressCallback(Program.resourceManager.GetString("unpacking_patch_info"), 0); List <FileEntry> entryes = ParsePatchInfo(ExtractData(zf, "patch_info.txt")); for (int i = 0; i < entryes.Count; i++) { int percent = (int)(((float)i / entryes.Count) * 100); FileEntry entry = entryes[i]; string entryFilename = Path.Combine(Program.targetDirectory, entry.filename); if (entry.type == FileEntry.EntryType.Removed) { progressCallback(string.Format(Program.resourceManager.GetString("deleting_file"), entry.filename), percent); if (File.Exists(entryFilename)) { File.Delete(entryFilename); } } if (entry.type == FileEntry.EntryType.Added) { progressCallback(string.Format(Program.resourceManager.GetString("adding_file"), entry.filename), percent); ExtractFile(zf, entry.filename, entryFilename); } if (entry.type == FileEntry.EntryType.Modified) { progressCallback(string.Format(Program.resourceManager.GetString("checking_file"), entry.filename), percent); string md5_old = GetMD5HashFromFile(entryFilename); if (entry.md5Old != md5_old) { throw new PatcherException(string.Format(Program.resourceManager.GetString("invalid_patch"), entryFilename)); } string patched_file = Path.GetTempFileName(); progressCallback(string.Format(Program.resourceManager.GetString("patching_file"), entry.filename), percent); using (FileStream sourceStream = File.Open(entryFilename, FileMode.Open)) { using (FileStream outStream = File.Open(patched_file, FileMode.Create)) { DeltaStreamer streamer = new DeltaStreamer(); streamer.Receive(ExtractStream(zf, entry.filename), sourceStream, outStream); outStream.Close(); } } progressCallback(string.Format(Program.resourceManager.GetString("copying_file"), entry.filename), percent); File.Copy(patched_file, entryFilename, true); File.Delete(patched_file); } if (entry.type == FileEntry.EntryType.Added || entry.type == FileEntry.EntryType.Modified) { progressCallback(string.Format(Program.resourceManager.GetString("checking_file"), entry.filename), percent); string md5New = GetMD5HashFromFile(entryFilename); if (entry.md5New != md5New) { throw new PatcherException(string.Format(Program.resourceManager.GetString("patch_broke_client"), entryFilename)); } } } } } }
public void Receive_throws_for_illegal_command_byte() { var streamer = new DeltaStreamer(); streamer.Receive(new MemoryStream(new[] { (byte)'G' }), new MemoryStream(), new MemoryStream()); }
public void Receive_throws_for_null_outputStream() { var streamer = new DeltaStreamer(); streamer.Receive(null, new MemoryStream(), new MemoryStream()); }