public async Task ReadAsync_ReadLargeData_Success()
        {
            // Arrange
            var headerData = new byte[] { 0, 0, 1, 0, 4 };
            var length     = 65540;
            var content    = CreateTestData(length);

            var messageContent = Encoding.UTF8.GetBytes(Convert.ToBase64String(headerData.Concat(content).ToArray()));
            var messageCount   = 3;

            var streamContent = new List <byte>();

            for (int i = 0; i < messageCount; i++)
            {
                streamContent.AddRange(messageContent);
            }

            var ms           = new LimitedReadMemoryStream(streamContent.ToArray(), 3);
            var base64Stream = new Base64ResponseStream(ms);

            for (int i = 0; i < messageCount; i++)
            {
                // Assert 1
                var resolvedHeaderData = await ReadContent(base64Stream, 5, CancellationToken.None);

                // Act 1
                CollectionAssert.AreEqual(headerData, resolvedHeaderData);

                // Assert 2
                var resolvedContentData = await ReadContent(base64Stream, (uint)length, CancellationToken.None);

                // Act 2
                CollectionAssert.AreEqual(content, resolvedContentData);
            }
        }
        public async Task ReadAsync_MultipleReadsWithLimitedData_Success(int readSize)
        {
            // Arrange
            var base64Data = Encoding.UTF8.GetBytes("AAAAAAYKBHRlc3Q=gAAAABANCmdycGMtc3RhdHVzOiAw");

            var ms           = new LimitedReadMemoryStream(base64Data, readSize);
            var base64Stream = new Base64ResponseStream(ms);

            // Act 1
            var messageHeadData = await ReadContent(base64Stream, 5);

            // Assert 1
            Assert.AreEqual(0, messageHeadData[0]);
            Assert.AreEqual(0, messageHeadData[1]);
            Assert.AreEqual(0, messageHeadData[2]);
            Assert.AreEqual(0, messageHeadData[3]);
            Assert.AreEqual(6, messageHeadData[4]);

            // Act 2
            var messageData = await ReadContent(base64Stream, 6);

            // Assert 2
            var s = Encoding.UTF8.GetString(messageData.AsSpan(2));

            Assert.AreEqual("test", s);

            // Act 3
            var footerHeadData = await ReadContent(base64Stream, 5);

            // Assert 3
            Assert.AreEqual(128, footerHeadData[0]);
            Assert.AreEqual(0, footerHeadData[1]);
            Assert.AreEqual(0, footerHeadData[2]);
            Assert.AreEqual(0, footerHeadData[3]);
            Assert.AreEqual(16, footerHeadData[4]);

            // Act 3
            var footerContentData = await ReadContent(base64Stream, 16);

            var expected = Convert.FromBase64String("AAAAAAYKBHRlc3Q=")
                           .Concat(Convert.FromBase64String("gAAAABANCmdycGMtc3RhdHVzOiAw"))
                           .ToArray();
            var actual = messageHeadData
                         .Concat(messageData)
                         .Concat(footerHeadData)
                         .Concat(footerContentData)
                         .ToArray();

            Assert.AreEqual(expected, actual);
        }
        public async Task ReadAsync_SmallDataSingleRead_Success()
        {
            // Arrange
            var data = Encoding.UTF8.GetBytes("Hello world");

            var ms           = new MemoryStream(Encoding.UTF8.GetBytes(Convert.ToBase64String(data)));
            var base64Stream = new Base64ResponseStream(ms);

            // Act
            var buffer = new byte[1024];
            var read   = await base64Stream.ReadAsync(buffer);

            // Assert
            Assert.AreEqual(read, data.Length);
            CollectionAssert.AreEqual(data, data.AsSpan(0, read).ToArray());
        }
        public void DecodeBase64DataFragments_MultipleFragments_Success()
        {
            // Arrange
            var data = Encoding.UTF8.GetBytes("AAAAAAYKBHRlc3Q=gAAAABANCmdycGMtc3RhdHVzOiAw");

            // Act
            var bytesWritten = Base64ResponseStream.DecodeBase64DataFragments(data);

            // Assert
            Assert.AreEqual(32, bytesWritten);

            var expected = Convert.FromBase64String("AAAAAAYKBHRlc3Q=")
                           .Concat(Convert.FromBase64String("gAAAABANCmdycGMtc3RhdHVzOiAw"))
                           .ToArray();
            var resolvedData = data.AsSpan(0, bytesWritten).ToArray();

            CollectionAssert.AreEqual(expected, resolvedData);
        }
        public async Task ReadAsync_MultipleReads_SmallDataSingleRead_Success()
        {
            // Arrange
            var data = Encoding.UTF8.GetBytes("AAAAAAYKBHRlc3Q=gAAAABANCmdycGMtc3RhdHVzOiAw");

            var ms           = new LimitedReadMemoryStream(data, 3);
            var base64Stream = new Base64ResponseStream(ms);

            // Act 1
            var messageHeadData = await ReadContent(base64Stream, 5);

            // Assert 1
            Assert.AreEqual(0, messageHeadData[0]);
            Assert.AreEqual(0, messageHeadData[1]);
            Assert.AreEqual(0, messageHeadData[2]);
            Assert.AreEqual(0, messageHeadData[3]);
            Assert.AreEqual(6, messageHeadData[4]);

            // Act 2
            var messageData = await ReadContent(base64Stream, 6);

            // Assert 2
            var s = Encoding.UTF8.GetString(messageData.AsSpan(2));

            Assert.AreEqual("test", s);

            // Act 3
            var footerHeadData = await ReadContent(base64Stream, 5);

            // Assert 3
            Assert.AreEqual(128, footerHeadData[0]);
            Assert.AreEqual(0, footerHeadData[1]);
            Assert.AreEqual(0, footerHeadData[2]);
            Assert.AreEqual(0, footerHeadData[3]);
            Assert.AreEqual(16, footerHeadData[4]);

            // Act 3
            StreamReader r          = new StreamReader(base64Stream, Encoding.UTF8);
            var          footerText = await r.ReadToEndAsync();

            Assert.AreEqual("\r\ngrpc-status: 0", footerText);
        }
        public async Task ReadAsync_VariableReadSize_Success(string message, int readSize)
        {
            // Arrange
            var data = Encoding.UTF8.GetBytes(message);

            var ms           = new MemoryStream(Encoding.UTF8.GetBytes(Convert.ToBase64String(data)));
            var base64Stream = new Base64ResponseStream(ms);

            // Act
            var allData = new List <byte>();
            var buffer  = new byte[readSize];

            int read;

            while ((read = await base64Stream.ReadAsync(buffer)) > 0)
            {
                allData.AddRange(buffer.AsSpan(0, read).ToArray());
            }
            var readData = allData.ToArray();

            // Assert
            CollectionAssert.AreEqual(data, readData);
        }
        public async Task ReadAsync_TwoByteReads_Success()
        {
            // Arrange
            var data = Encoding.UTF8.GetBytes("Hello world");

            var ms           = new MemoryStream(Encoding.UTF8.GetBytes(Convert.ToBase64String(data)));
            var base64Stream = new Base64ResponseStream(ms);

            // Act
            var allData = new List <byte>();
            var buffer  = new byte[2];

            int read;

            while ((read = await ReadAsync(base64Stream, buffer)) > 0)
            {
                allData.AddRange(buffer.AsSpan(0, read).ToArray());
            }
            var readData = allData.ToArray();

            // Assert
            CollectionAssert.AreEqual(data, readData);
        }