예제 #1
0
        private void ConvertFromBase64(Span <byte> tmpBuffer, Span <byte> outputBuffer, out int consumed, out int written)
        {
            int bytesToTransform = _inputIndex + tmpBuffer.Length;

            Debug.Assert(bytesToTransform >= 4);

            byte[]? transformBufferArray = null;
            Span <byte> transformBuffer = stackalloc byte[StackAllocSize];

            if (bytesToTransform > StackAllocSize)
            {
                transformBuffer = transformBufferArray = CryptoPool.Rent(bytesToTransform);
            }

            // Copy _inputBuffer to transformBuffer and append tmpBuffer
            Debug.Assert(_inputIndex < _inputBuffer.Length);
            _inputBuffer.AsSpan(0, _inputIndex).CopyTo(transformBuffer);
            tmpBuffer.CopyTo(transformBuffer.Slice(_inputIndex));

            // Save data that won't be transformed to _inputBuffer, so it can be transformed later
            _inputIndex       = bytesToTransform & 3; // bit hack for % 4
            bytesToTransform -= _inputIndex;          // only transform up to the next multiple of 4
            Debug.Assert(_inputIndex < _inputBuffer.Length);
            tmpBuffer.Slice(tmpBuffer.Length - _inputIndex).CopyTo(_inputBuffer);

            transformBuffer = transformBuffer.Slice(0, bytesToTransform);
            OperationStatus status = Base64.DecodeFromUtf8(transformBuffer, outputBuffer, out consumed, out written);

            if (status == OperationStatus.Done)
            {
                Debug.Assert(consumed == bytesToTransform);
            }
            else
            {
                Debug.Assert(status == OperationStatus.InvalidData);
                ThrowHelper.ThrowBase64FormatException();
            }

            ReturnToCryptoPool(transformBufferArray, transformBuffer.Length);
        }
예제 #2
0
        public int TransformBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset)
        {
            ThrowHelper.ValidateTransformBlock(inputBuffer, inputOffset, inputCount);

            int inputBlocks = Math.DivRem(inputCount, InputBlockSize, out int inputRemainder);

            if (inputBlocks == 0)
            {
                ThrowHelper.ThrowArgumentOutOfRange(ThrowHelper.ExceptionArgument.inputCount);
            }

            if (outputBuffer == null)
            {
                ThrowHelper.ThrowArgumentNull(ThrowHelper.ExceptionArgument.outputBuffer);
            }

            if (inputRemainder != 0)
            {
                ThrowHelper.ThrowArgumentOutOfRange(ThrowHelper.ExceptionArgument.inputCount);
            }

            int requiredOutputLength = checked (inputBlocks * OutputBlockSize);

            if (requiredOutputLength > outputBuffer.Length - outputOffset)
            {
                ThrowHelper.ThrowArgumentOutOfRange(ThrowHelper.ExceptionArgument.outputBuffer);
            }

            Span <byte> input  = inputBuffer.AsSpan(inputOffset, inputCount);
            Span <byte> output = outputBuffer.AsSpan(outputOffset, requiredOutputLength);

            OperationStatus status = Base64.EncodeToUtf8(input, output, out int consumed, out int written, isFinalBlock: false);

            Debug.Assert(status == OperationStatus.Done);
            Debug.Assert(consumed == input.Length);
            Debug.Assert(written == output.Length);

            return(written);
        }