/// <summary> /// Creates the patch based on the difference between two streams. /// </summary> /// <param name="baseStream">The untouched stream.</param> /// <param name="modStream">The modified stream.</param> public override sealed void Create(Stream baseStream, Stream modStream) { using (HashStream <TPatchAlgorithm> patchHashStream = new HashStream <TPatchAlgorithm>(BaseStream, HashAlgorithm)) using (HashStream <TBaseAlgorithm> baseHashStream = new HashStream <TBaseAlgorithm>(baseStream)) using (HashStream <TModAlgorithm> modHashStream = new HashStream <TModAlgorithm>(modStream)) { BaseStream = patchHashStream; patchHashStream.Initialize(); Create(patchHashStream, baseHashStream, modHashStream); if (!baseHashStream.HasFlushedFinalBlock) { baseHashStream.Position = baseHashStream.Length; baseHashStream.FlushFinalBlock(); } if (!modHashStream.HasFlushedFinalBlock) { modHashStream.Position = modHashStream.Length; modHashStream.FlushFinalBlock(); } WriteVerificationFooter(patchHashStream, baseHashStream, modHashStream); BaseStream = patchHashStream.BaseStream; } }
/// <summary> /// Applies the patch. /// </summary> /// <param name="baseStream">The stream to read the data to patch from.</param> /// <param name="outputStream">The stream to write the patched data to.</param> public override sealed void Apply(Stream baseStream, Stream outputStream) { if (!ValidHash.SequenceEqual(Hash)) { throw new ChecksumException(Hash, ValidHash); } using (HashStream <TPatchAlgorithm> patchHashStream = new HashStream <TPatchAlgorithm>(BaseStream, HashAlgorithm)) using (HashStream <TBaseAlgorithm> baseHashStream = new HashStream <TBaseAlgorithm>(baseStream)) using (HashStream <TModAlgorithm> outputHashStream = new HashStream <TModAlgorithm>(outputStream)) { Apply(baseHashStream, outputHashStream); if (!baseHashStream.HasFlushedFinalBlock) { baseHashStream.Position = baseHashStream.Length; baseHashStream.FlushFinalBlock(); } if (!outputHashStream.HasFlushedFinalBlock) { outputHashStream.Position = outputHashStream.Length; outputHashStream.FlushFinalBlock(); } Verify(baseHashStream, outputHashStream); } }
/// <summary> /// Verifies the hashes of the streams. /// </summary> /// <param name="baseStream">The stream to read the data to patch from.</param> /// <param name="outputStream">The stream to write the patched data to.</param> protected override void Verify(HashStream <Crc32> baseStream, HashStream <Crc32> outputStream) { if (ValidBaseLength == ValidModLength && !baseStream.Hash.SequenceEqual(ValidBaseHash)) { byte[] hash = ValidBaseHash; ValidBaseHash = ValidModHash; ValidModHash = hash; } base.Verify(baseStream, outputStream); }
/// <summary> /// Analyzes the verification-footer. /// </summary> /// <param name="patchStream">The stream of the patch.</param> protected override void AnalyzeVerificationFooter(HashStream <Crc32> patchStream) { base.AnalyzeVerificationFooter(patchStream); patchStream.FlushFinalBlock(); using (BinaryReader reader = Reader) { ValidHash = reader.ReadBytes(4).Reverse().ToArray(); } }
/// <summary> /// Verifies the hashes of the streams. /// </summary> /// <param name="baseStream">The stream to read the data to patch from.</param> /// <param name="outputStream">The stream to write the patched data to.</param> protected virtual void Verify(HashStream <TBaseAlgorithm> baseStream, HashStream <TModAlgorithm> outputStream) { if (!ValidBaseHash.SequenceEqual(baseStream.Hash)) { throw new ChecksumException(baseStream.Hash, ValidBaseHash); } if (!ValidModHash.SequenceEqual(outputStream.Hash)) { throw new ChecksumException(outputStream.Hash, ValidModHash); } }
/// <summary> /// Writes a header that can be used for verifying the integrity of the streams. /// </summary> /// <param name="patchStream">The stream of the patch.</param> /// <param name="baseStream">The untouched stream.</param> /// <param name="modStream">The modified stream.</param> protected override void WriteVerificationFooter(HashStream <Crc32> patchStream, HashStream <Crc32> baseStream, HashStream <Crc32> modStream) { base.WriteVerificationFooter(patchStream, baseStream, modStream); using (BinaryWriter writer = Writer) { writer.Write(baseStream.Hash.Reverse().ToArray()); writer.Write(modStream.Hash.Reverse().ToArray()); patchStream.FlushFinalBlock(); writer.Write(patchStream.Hash.Reverse().ToArray()); } }
/// <summary> /// Applies the patch. /// </summary> /// <param name="baseStream">The stream to read the data to patch from.</param> /// <param name="outputStream">The stream to write the patched data to.</param> public override void Apply(HashStream <Crc32> baseStream, HashStream <Crc32> outputStream) { if (baseStream.Length != ValidBaseLength && baseStream.Length == ValidModLength) { long length = ValidBaseLength; ValidBaseLength = ValidModLength; ValidModLength = length; byte[] hash = ValidBaseHash; ValidBaseHash = ValidModHash; ValidModHash = hash; } outputStream.SetLength(ValidModLength); base.Apply(baseStream, outputStream); }
/// <summary> /// Analyzes the entire patch. /// </summary> protected override void Analyze() { using (HashStream <TPatchAlgorithm> patchHashStream = new HashStream <TPatchAlgorithm>(BaseStream, HashAlgorithm)) { BaseStream = patchHashStream; patchHashStream.Initialize(); base.Analyze(); AnalyzeVerificationFooter(patchHashStream); if (!patchHashStream.HasFlushedFinalBlock) { patchHashStream.FlushFinalBlock(); } BaseStream = patchHashStream.BaseStream; } }
/// <summary> /// Writes a header that can be used for verifying the integrity of the streams. /// </summary> /// <param name="patchStream">The stream of the patch.</param> /// <param name="baseStream">The untouched stream.</param> /// <param name="modStream">The modified stream.</param> protected virtual void WriteVerificationFooter(HashStream <TPatchAlgorithm> patchStream, HashStream <TBaseAlgorithm> baseStream, HashStream <TModAlgorithm> modStream) { }
/// <summary> /// Creates the patch based on the difference between two streams. /// </summary> /// <param name="patchStream">The stream of the patch.</param> /// <param name="baseStream">The untouched stream.</param> /// <param name="modStream">The modified stream.</param> protected virtual void Create(HashStream <TPatchAlgorithm> patchStream, HashStream <TBaseAlgorithm> baseStream, HashStream <TModAlgorithm> modStream) { base.Create(baseStream, modStream); }
/// <summary> /// Analyzes the verification-footer. /// </summary> /// <param name="patchStream">The stream of the patch.</param> protected virtual void AnalyzeVerificationFooter(HashStream <TPatchAlgorithm> patchStream) { }
/// <summary> /// Applies the patch. /// </summary> /// <param name="baseStream">The stream to read the data to patch from.</param> /// <param name="outputStream">The stream to write the patched data to.</param> public virtual void Apply(HashStream <TBaseAlgorithm> baseStream, HashStream <TModAlgorithm> outputStream) { base.Apply(baseStream, outputStream); }