private static async Task TransformAsync(this byte[] input, ICryptoTransform transform, Stream streamToWrite, CancellationToken token, bool disposeOutput, int byteOffset, int byteCount) { using (var outputWrapper = new WrappedStream(streamToWrite, disposeOutput)) { using (var transformer = new CryptoStream(outputWrapper, transform, CryptoStreamMode.Write)) { await transformer.WriteAsync(input, byteOffset, byteCount, token).ConfigureAwait(false); await transformer.FlushAsync(token).ConfigureAwait(false); await outputWrapper.FlushAsync(token).ConfigureAwait(false); await streamToWrite.FlushAsync(token).ConfigureAwait(false); } } }
/// <summary> /// Reads from <paramref name="streamToRead"/> and writes transformed data on <paramref name="streamToWrite"/>, /// using <paramref name="transform"/>, while observing <paramref name="token"/>. /// </summary> /// <param name="streamToRead">Stream to read from</param> /// <param name="transform">transform to use</param> /// <param name="streamToWrite">Stream to write transformed data to.</param> /// <param name="token">Cancellation token</param> /// <param name="disposeInput">If true, disposes <paramref name="streamToRead"/> upon operation completion, else leaves it open</param> /// <param name="disposeOutput">If true, disposes <paramref name="streamToWrite"/> upon operation completion, else leaves it open</param> /// <param name="bufferSize">Buffer size</param> public static async Task TransformAsync(this Stream streamToRead, ICryptoTransform transform, Stream streamToWrite, CancellationToken token, bool disposeInput = false, bool disposeOutput = false, int bufferSize = StdLookUps.DefaultBufferSize) { using (var outputWrapper = new WrappedStream(streamToWrite, disposeOutput)) { using (var transformer = new CryptoStream(outputWrapper, transform, CryptoStreamMode.Write)) { using (var inputWrapper = new WrappedStream(streamToRead, disposeInput)) { await inputWrapper.CopyToAsync(transformer, bufferSize, token).ConfigureAwait(false); await transformer.FlushAsync(token).ConfigureAwait(false); await outputWrapper.FlushAsync(token).ConfigureAwait(false); await streamToWrite.FlushAsync(token).ConfigureAwait(false); } } } }
/// <summary> /// Reads from <paramref name="streamToRead"/> and prepares decoded byte array, (return as segment, /// idea is to save on array copy to remain low on latency n memory as perhaps segment can serve the purpose), /// using <paramref name="transform"/>, while observing <paramref name="token"/>. /// </summary> /// <param name="streamToRead">Stream to read from</param> /// <param name="transform">transform to use</param> /// <param name="token">Cancellation token</param> /// <param name="disposeInput">If true, disposes <paramref name="streamToRead"/> upon operation completion, else leaves it open</param> /// <param name="bufferSize">Buffer size</param> public static async Task <ArraySegment <byte> > TransformAsSegmentAsync(this Stream streamToRead, ICryptoTransform transform, CancellationToken token, bool disposeInput = false, int bufferSize = StdLookUps.DefaultBufferSize) { using (var inputWrapper = new WrappedStream(streamToRead, disposeInput)) { using (var transformer = new CryptoStream(inputWrapper, transform, CryptoStreamMode.Read)) { using (var localBuffer = new MemoryStream()) { await transformer.CopyToAsync(localBuffer, bufferSize, token).ConfigureAwait(false); return(localBuffer.TryGetBuffer(out ArraySegment <byte> buffer) .ThrowIfNot(DdnDfErrorCode.NullObject, "Something horribly went wrong with" + $" {nameof(MemoryStream)} implementation", buffer)); } } } }
private static async Task TransformChunksAsync(Stream writable, ICryptoTransform transform, int length, Encoding enc, CancellationToken token, bool disposeOutput, int chunkSize, Action <int, char[], int, int> copyToAction) { using (var outputWrapper = new WrappedStream(writable, disposeOutput)) { using (var transformer = new CryptoStream(outputWrapper, transform, CryptoStreamMode.Write)) { var bytes = enc.GetPreamble(); if (bytes.Length > 0) { await transformer.WriteAsync(bytes, 0, bytes.Length, token) .ConfigureAwait(false); } var charArr = new char[chunkSize]; bytes = new byte[enc.GetMaxByteCount(chunkSize)]; var charCnt = length; var position = 0; while (charCnt > 0) { if (charCnt > chunkSize) { charCnt = chunkSize; } copyToAction(position, charArr, 0, charCnt); var byteCnt = enc.GetBytes(charArr, 0, charCnt, bytes, 0); await transformer.WriteAsync(bytes, 0, byteCnt, token).ConfigureAwait(false); position += charCnt; charCnt = length - position; } await transformer.FlushAsync(token).ConfigureAwait(false); await outputWrapper.FlushAsync(token).ConfigureAwait(false); await writable.FlushAsync(token).ConfigureAwait(false); } } }
/// <summary> /// Reads from <paramref name="streamToRead"/> and appends transformed string to <paramref name="appendTo"/>, /// using <paramref name="transform"/> and <paramref name="encoding"/>, while observing <paramref name="token"/>. /// </summary> /// <param name="streamToRead">Stream to read from</param> /// <param name="transform">transform to use</param> /// <param name="appendTo">StringBuilder to write transformed data to.</param> /// <param name="token">Cancellation token</param> /// <param name="disposeInput">If true, disposes <paramref name="streamToRead"/> upon operation completion, else leaves it open</param> /// <param name="encoding">Encoding to use to compose string characters, if not supplied UTF8 is used</param> /// <param name="bufferSize">Buffer size</param> public static async Task TransformAsync(this Stream streamToRead, ICryptoTransform transform, StringBuilder appendTo, CancellationToken token, bool disposeInput = false, Encoding encoding = null, int bufferSize = StdLookUps.DefaultBufferSize) { using (var inputWrapper = new WrappedStream(streamToRead, disposeInput)) { using (var transformer = new CryptoStream(inputWrapper, transform, CryptoStreamMode.Read)) { using (var streamReader = new StreamReader(transformer, encoding ?? Encoding.UTF8, true, bufferSize, true)) { var charBuffer = new char[bufferSize]; int charCnt; while ((charCnt = await streamReader.ReadAsync(charBuffer, 0, bufferSize) .ConfigureAwait(false)) != 0) { appendTo.Append(charBuffer, 0, charCnt); token.ThrowIfCancellationRequested(); } } } } }