private void UnpackRegularFile(Pack1Meta.FileEntry file, Action <double> onProgress, CancellationToken cancellationToken, string destinationDirPath = null) { string destPath = Path.Combine(destinationDirPath == null ? _destinationDirPath : destinationDirPath, file.Name + _suffix); DebugLogger.LogFormat("Unpacking regular file {0} to {1}", file, destPath); if (file.Size == null) { throw new NullReferenceException("File size cannot be null for regular file."); } if (file.Offset == null) { throw new NullReferenceException("File offset cannot be null for regular file."); } Files.CreateParents(destPath); var rijn = new RijndaelManaged { Mode = CipherMode.CBC, Padding = PaddingMode.None, KeySize = 256 }; var aesAlg = new AesCryptoServiceProvider { IV = _iv, Key = _key }; ICryptoTransform decryptor = aesAlg.CreateDecryptor( aesAlg.Key, aesAlg.IV); DecompressorCreator decompressorCreator = ResolveDecompressor(_metaData); using (var fs = new FileStream(_packagePath, FileMode.Open)) { fs.Seek(file.Offset.Value - _range.Start, SeekOrigin.Begin); using (var limitedStream = new BufferedStream(new LimitedStream(fs, file.Size.Value), 2 * 1024 * 1024)) { //using (var bufferedLimitedStream = new ThreadBufferedStream(limitedStream, 8 * 1024 * 1024)) { using (var target = new FileStream(destPath, FileMode.Create)) { ExtractFileFromStream(limitedStream, target, file.Size.Value, decryptor, decompressorCreator, onProgress, cancellationToken); } } if (Platform.IsPosix()) { Chmod.SetMode(file.Mode.Substring(3), destPath); } } } DebugLogger.Log("File " + file.Name + " unpacked successfully!"); }
private void ExtractFileFromStream( Stream sourceStream, Stream targetStream, long fileSize, ICryptoTransform decryptor, DecompressorCreator createDecompressor, Action <double> onProgress, CancellationToken cancellationToken) { using (var cryptoStream = new CryptoStream(sourceStream, decryptor, CryptoStreamMode.Read)) { using (var bufferedCryptoStream = new BufferedStream(new ThreadBufferedStream(cryptoStream, 2 * 1024 * 1024), 2 * 1024 * 1024)) { //using (var wrapperStream = new GZipReadWrapperStream(bufferedCryptoStream)) { using (Stream decompressionStream = createDecompressor(bufferedCryptoStream)) { using (var bufferedDecompressionStream = new ThreadBufferedStream(decompressionStream, 4 * 1024 * 1024)) { try { const int bufferSize = 2 * 1024 * 1024; var buffer = new byte[bufferSize]; int count; while ((count = bufferedDecompressionStream.Read(buffer, 0, buffer.Length)) > 0) { cancellationToken.ThrowIfCancellationRequested(); targetStream.Write(buffer, 0, count); long bytesProcessed = sourceStream.Position; onProgress(bytesProcessed / (double)fileSize); } } catch (OperationCanceledException) { throw; } catch (Exception e) { DebugLogger.LogException(e); PatcherLogManager logManager = PatcherLogManager.Instance; PatcherLogSentryRegistry sentryRegistry = logManager.SentryRegistry; RavenClient ravenClient = sentryRegistry.RavenClient; var sentryEvent = new SentryEvent(e); PatcherLogSentryRegistry.AddDataToSentryEvent(sentryEvent, logManager.Storage.Guid.ToString()); ravenClient.Capture(sentryEvent); throw; } } } } } } }