/// <inheritdoc/> public async Task <UInt32> TransformChunkAsync( Stream input, UInt32 inputChunkSize, Stream output, NefsDataTransform transform, NefsProgress p) { using (var transformedStream = new MemoryStream()) { // Copy raw chunk to temp stream await input.CopyPartialAsync(transformedStream, inputChunkSize, p.CancellationToken); transformedStream.Seek(0, SeekOrigin.Begin); // Compress if (transform.IsZlibCompressed) { using (var tempStream = new MemoryStream()) { await DeflateHelper.DeflateAsync(transformedStream, (int)inputChunkSize, tempStream); tempStream.Seek(0, SeekOrigin.Begin); transformedStream.Seek(0, SeekOrigin.Begin); await tempStream.CopyPartialAsync(transformedStream, tempStream.Length, p.CancellationToken); transformedStream.Seek(0, SeekOrigin.Begin); transformedStream.SetLength(tempStream.Length); } } // Encrypt if (transform.IsAesEncrypted) { using (var aesManager = this.CreateAesManager(transform.Aes256Key)) using (var cryptoStream = new CryptoStream(transformedStream, aesManager.CreateEncryptor(), CryptoStreamMode.Read, leaveOpen: true)) using (var tempStream = new MemoryStream()) { await cryptoStream.CopyToAsync(tempStream, p.CancellationToken); tempStream.Seek(0, SeekOrigin.Begin); transformedStream.Seek(0, SeekOrigin.Begin); await tempStream.CopyPartialAsync(transformedStream, tempStream.Length, p.CancellationToken); transformedStream.Seek(0, SeekOrigin.Begin); transformedStream.SetLength(tempStream.Length); } } // Copy transformed chunk to output stream await transformedStream.CopyToAsync(output, p.CancellationToken); // Return size of transformed chunk return((uint)transformedStream.Length); } }
/// <inheritdoc/> public async Task <NefsItemSize> CompressAsync( Stream input, Int64 inputOffset, UInt32 inputLength, Stream output, Int64 outputOffset, UInt32 chunkSize, NefsProgress p) { var chunkSizes = new List <UInt32>(); input.Seek(inputOffset, SeekOrigin.Begin); output.Seek(outputOffset, SeekOrigin.Begin); // Split file into chunks and compress them using (var t = p.BeginTask(1.0f, $"Compressing stream")) { var lastChunkSize = 0; var totalChunkSize = 0; var lastBytesRead = 0; var bytesRemaining = (int)inputLength; // Determine how many chunks to split file into var numChunks = (int)Math.Ceiling(inputLength / (double)chunkSize); for (var i = 0; i < numChunks; ++i) { using (var st = p.BeginSubTask(1.0f / numChunks, $"Compressing chunk {i + 1}/{numChunks}")) { var nextBytes = Math.Min(chunkSize, bytesRemaining); // Compress this chunk and write it to the output file (lastBytesRead, lastChunkSize) = await DeflateHelper.DeflateAsync(input, (int)nextBytes, output, p.CancellationToken); totalChunkSize += lastChunkSize; bytesRemaining -= lastBytesRead; // Record the total compressed size after this chunk chunkSizes.Add((UInt32)totalChunkSize); } } } // Return item size return(new NefsItemSize(inputLength, chunkSizes)); }