System.Security.Cryptography.CryptoStream.WriteAsyncCore C# (CSharp) Method

WriteAsyncCore() private method

private WriteAsyncCore ( byte buffer, int offset, int count, CancellationToken cancellationToken, bool useAsync ) : Task
buffer byte
offset int
count int
cancellationToken CancellationToken
useAsync bool
return Task
        private async Task WriteAsyncCore(byte[] buffer, int offset, int count, CancellationToken cancellationToken, bool useAsync)
        {
            // write <= count bytes to the output stream, transforming as we go.
            // Basic idea: using bytes in the _InputBuffer first, make whole blocks,
            // transform them, and write them out.  Cache any remaining bytes in the _InputBuffer.
            int bytesToWrite = count;
            int currentInputIndex = offset;
            // if we have some bytes in the _InputBuffer, we have to deal with those first,
            // so let's try to make an entire block out of it
            if (_inputBufferIndex > 0)
            {
                if (count >= _inputBlockSize - _inputBufferIndex)
                {
                    // we have enough to transform at least a block, so fill the input block
                    Buffer.BlockCopy(buffer, offset, _inputBuffer, _inputBufferIndex, _inputBlockSize - _inputBufferIndex);
                    currentInputIndex += (_inputBlockSize - _inputBufferIndex);
                    bytesToWrite -= (_inputBlockSize - _inputBufferIndex);
                    _inputBufferIndex = _inputBlockSize;
                    // Transform the block and write it out
                }
                else
                {
                    // not enough to transform a block, so just copy the bytes into the _InputBuffer
                    // and return
                    Buffer.BlockCopy(buffer, offset, _inputBuffer, _inputBufferIndex, count);
                    _inputBufferIndex += count;
                    return;
                }
            }
            // If the OutputBuffer has anything in it, write it out
            if (_outputBufferIndex > 0)
            {
                if (useAsync)
                    await _stream.WriteAsync(_outputBuffer, 0, _outputBufferIndex, cancellationToken);
                else
                    _stream.Write(_outputBuffer, 0, _outputBufferIndex);
                _outputBufferIndex = 0;
            }
            // At this point, either the _InputBuffer is full, empty, or we've already returned.
            // If full, let's process it -- we now know the _OutputBuffer is empty
            int numOutputBytes;
            if (_inputBufferIndex == _inputBlockSize)
            {
                numOutputBytes = _transform.TransformBlock(_inputBuffer, 0, _inputBlockSize, _outputBuffer, 0);
                // write out the bytes we just got
                if (useAsync)
                    await _stream.WriteAsync(_outputBuffer, 0, numOutputBytes, cancellationToken);
                else
                    _stream.Write(_outputBuffer, 0, numOutputBytes);

                // reset the _InputBuffer
                _inputBufferIndex = 0;
            }
            while (bytesToWrite > 0)
            {
                if (bytesToWrite >= _inputBlockSize)
                {
                    // We have at least an entire block's worth to transform
                    // If the transform will handle multiple blocks at once, do that
                    if (_transform.CanTransformMultipleBlocks)
                    {
                        int numWholeBlocks = bytesToWrite / _inputBlockSize;
                        int numWholeBlocksInBytes = numWholeBlocks * _inputBlockSize;
                        byte[] _tempOutputBuffer = new byte[numWholeBlocks * _outputBlockSize];
                        numOutputBytes = _transform.TransformBlock(buffer, currentInputIndex, numWholeBlocksInBytes, _tempOutputBuffer, 0);

                        if (useAsync)
                            await _stream.WriteAsync(_tempOutputBuffer, 0, numOutputBytes, cancellationToken);
                        else
                            _stream.Write(_tempOutputBuffer, 0, numOutputBytes);

                        currentInputIndex += numWholeBlocksInBytes;
                        bytesToWrite -= numWholeBlocksInBytes;
                    }
                    else
                    {
                        // do it the slow way
                        numOutputBytes = _transform.TransformBlock(buffer, currentInputIndex, _inputBlockSize, _outputBuffer, 0);

                        if (useAsync)
                            await _stream.WriteAsync(_outputBuffer, 0, numOutputBytes, cancellationToken);
                        else
                            _stream.Write(_outputBuffer, 0, numOutputBytes);

                        currentInputIndex += _inputBlockSize;
                        bytesToWrite -= _inputBlockSize;
                    }
                }
                else
                {
                    // In this case, we don't have an entire block's worth left, so store it up in the 
                    // input buffer, which by now must be empty.
                    Buffer.BlockCopy(buffer, currentInputIndex, _inputBuffer, 0, bytesToWrite);
                    _inputBufferIndex += bytesToWrite;
                    return;
                }
            }
            return;
        }