Base64Encoder
                    class Base64Encoder
                
                using System;
using System.IO;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
namespace Newtonsoft.Json.Utilities
{
    [System.Runtime.CompilerServices.NullableContext(1)]
    [System.Runtime.CompilerServices.Nullable(0)]
    internal class Base64Encoder
    {
        private const int Base64LineSize = 76;
        private const int LineSizeInBytes = 57;
        private readonly char[] _charsLine = new char[76];
        private readonly TextWriter _writer;
        [System.Runtime.CompilerServices.Nullable(2)]
        private byte[] _leftOverBytes;
        private int _leftOverBytesCount;
        public Base64Encoder(TextWriter writer)
        {
            ValidationUtils.ArgumentNotNull(writer, "writer");
            _writer = writer;
        }
        private void ValidateEncode(byte[] buffer, int index, int count)
        {
            if (buffer == null)
                throw new ArgumentNullException("buffer");
            if (index < 0)
                throw new ArgumentOutOfRangeException("index");
            if (count < 0)
                throw new ArgumentOutOfRangeException("count");
            if (count > buffer.Length - index)
                throw new ArgumentOutOfRangeException("count");
        }
        public void Encode(byte[] buffer, int index, int count)
        {
            ValidateEncode(buffer, index, count);
            if (_leftOverBytesCount > 0) {
                if (FulfillFromLeftover(buffer, index, ref count))
                    return;
                int count2 = Convert.ToBase64CharArray(_leftOverBytes, 0, 3, _charsLine, 0);
                WriteChars(_charsLine, 0, count2);
            }
            StoreLeftOverBytes(buffer, index, ref count);
            int num = index + count;
            int num2 = 57;
            while (index < num) {
                if (index + num2 > num)
                    num2 = num - index;
                int count3 = Convert.ToBase64CharArray(buffer, index, num2, _charsLine, 0);
                WriteChars(_charsLine, 0, count3);
                index += num2;
            }
        }
        private void StoreLeftOverBytes(byte[] buffer, int index, ref int count)
        {
            int num = count % 3;
            if (num > 0) {
                count -= num;
                if (_leftOverBytes == null)
                    _leftOverBytes = new byte[3];
                for (int i = 0; i < num; i++) {
                    _leftOverBytes[i] = buffer[index + count + i];
                }
            }
            _leftOverBytesCount = num;
        }
        private bool FulfillFromLeftover(byte[] buffer, int index, ref int count)
        {
            int num = _leftOverBytesCount;
            while (num < 3 && count > 0) {
                _leftOverBytes[num++] = buffer[index++];
                count--;
            }
            if (count == 0 && num < 3) {
                _leftOverBytesCount = num;
                return true;
            }
            return false;
        }
        public void Flush()
        {
            if (_leftOverBytesCount > 0) {
                int count = Convert.ToBase64CharArray(_leftOverBytes, 0, _leftOverBytesCount, _charsLine, 0);
                WriteChars(_charsLine, 0, count);
                _leftOverBytesCount = 0;
            }
        }
        private void WriteChars(char[] chars, int index, int count)
        {
            _writer.Write(chars, index, count);
        }
        [AsyncStateMachine(typeof(<EncodeAsync>d__13))]
        public Task EncodeAsync(byte[] buffer, int index, int count, CancellationToken cancellationToken)
        {
            <EncodeAsync>d__13 stateMachine = default(<EncodeAsync>d__13);
            stateMachine.<>t__builder = AsyncTaskMethodBuilder.Create();
            stateMachine.<>4__this = this;
            stateMachine.buffer = buffer;
            stateMachine.index = index;
            stateMachine.count = count;
            stateMachine.cancellationToken = cancellationToken;
            stateMachine.<>1__state = -1;
            stateMachine.<>t__builder.Start(ref stateMachine);
            return stateMachine.<>t__builder.Task;
        }
        private Task WriteCharsAsync(char[] chars, int index, int count, CancellationToken cancellationToken)
        {
            return _writer.WriteAsync(chars, index, count, cancellationToken);
        }
        public Task FlushAsync(CancellationToken cancellationToken)
        {
            if (cancellationToken.IsCancellationRequested)
                return cancellationToken.FromCanceled();
            if (_leftOverBytesCount > 0) {
                int count = Convert.ToBase64CharArray(_leftOverBytes, 0, _leftOverBytesCount, _charsLine, 0);
                _leftOverBytesCount = 0;
                return WriteCharsAsync(_charsLine, 0, count, cancellationToken);
            }
            return AsyncUtils.CompletedTask;
        }
    }
}