private async Task <ChunkBytes> Compress(ChunkBytes data) { var result = await Pool.GetAsync(); using (MemoryStream memStream = new MemoryStream(result.Bytes)) { using (GZipStream gzipStream = new GZipStream(memStream, CompressionLevel.Optimal, leaveOpen: true)) await gzipStream.WriteAsync(data.Bytes, 0, data.Length); result.Length = (int)memStream.Position; } return(result); }
private async Task <ChunkBytes> Decompress(ChunkBytes data, int offset = 0) { var result = await Pool.GetAsync(); using (MemoryStream memStream = new MemoryStream(result.Bytes)) { using (MemoryStream input = new MemoryStream(data.Bytes, offset, data.Length - offset)) using (GZipStream gzipStream = new GZipStream(input, CompressionMode.Decompress)) await gzipStream.CopyToAsync(memStream); result.Length = (int)memStream.Position; } return(result); }
private async Task <ChunkBytes> CryptoTransform(ChunkBytes data, ICryptoTransform transform) { var result = await Pool.GetAsync(); using (var memoryStream = new MemoryStream(result.Bytes)) { using (var cryptoStream = new CryptoStream(memoryStream, transform, CryptoStreamMode.Write)) { await cryptoStream.WriteAsync(data.Bytes, 0, data.Length); cryptoStream.FlushFinalBlock(); result.Length = (int)memoryStream.Position; } } return(result); }
private Task <ChunkBytes> Decrypt(ChunkBytes data) { return(CryptoTransform(data, rijndaelAlgorithm.Value.CreateDecryptor())); }
private static string MD5FromBytes(ChunkBytes data) { using (var md5 = MD5.Create()) using (var stream = new MemoryStream(data.Bytes, 0, data.Length)) return(BitConverter.ToString(md5.ComputeHash(stream)).Replace("-", "").ToLower()); }
public async Task CompressAndEncrypt( Stream streamSource, Stream streamDestination, CancellationTokenSource cts = null) { cts = cts ?? new CancellationTokenSource(); var compressorOptions = new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = Environment.ProcessorCount, BoundedCapacity = _boundedCapacity, CancellationToken = cts.Token }; var inputBuffer = new BufferBlock <CompressingDetails>( new DataflowBlockOptions { CancellationToken = cts.Token, BoundedCapacity = _boundedCapacity }); var compressor = new TransformBlock <CompressingDetails, CompressedDetails>( async details => { ChunkBytes compressedData = await Compress(details.Bytes); await Pool.PutAsync(details.Bytes); return(new CompressedDetails { Bytes = compressedData, ChunkSize = details.ChunkSize, Sequence = details.Sequence, CompressedDataSize = new ChunkBytes(BitConverter.GetBytes(compressedData.Length)) }); }, compressorOptions); var encryptor = new TransformBlock <CompressedDetails, EncryptDetails>( async details => { var data = await CombineByteArrays(details.CompressedDataSize, details.ChunkSize, details.Bytes); await Pool.PutAsync(details.Bytes); var encryptedData = await Encrypt(data); await Pool.PutAsync(data); return(new EncryptDetails { Bytes = encryptedData, Sequence = details.Sequence, EncryptedDataSize = new ChunkBytes(BitConverter.GetBytes(encryptedData.Length)) }); }, compressorOptions); var asOrderedAgent = Agent.Start((new Dictionary <int, EncryptDetails>(), 0), async((Dictionary <int, EncryptDetails>, int)state, EncryptDetails msg) => { (Dictionary <int, EncryptDetails> details, int lastIndexProc) = state; details.Add(msg.Sequence, msg); while (details.ContainsKey(lastIndexProc + 1)) { msg = details[lastIndexProc + 1]; await streamDestination.WriteAsync(msg.EncryptedDataSize.Bytes, 0, msg.EncryptedDataSize.Length); await streamDestination.WriteAsync(msg.Bytes.Bytes, 0, msg.Bytes.Length); await Pool.PutAsync(msg.Bytes); lastIndexProc = msg.Sequence; details.Remove(lastIndexProc); } return(details, lastIndexProc); }, cts);