public HttpResponseStreamWriter(Stream stream, Encoding encoding, LeasedArraySegment<char> leasedCharBuffer, LeasedArraySegment<byte> leasedByteBuffer)
 {
     _stream = stream;
     Encoding = encoding;
     _encoder = encoding.GetEncoder();
     _charBufferSize = leasedCharBuffer.Data.Count;
     _charBuffer = leasedCharBuffer.Data;
     _byteBuffer = leasedByteBuffer.Data;
     _leasedCharBuffer = leasedCharBuffer;
     _leasedByteBuffer = leasedByteBuffer;
 }
        public HttpResponseStreamWriter(
            Stream stream,
            Encoding encoding,
            int bufferSize,
            LeasedArraySegment <byte> leasedByteBuffer,
            LeasedArraySegment <char> leasedCharBuffer)
        {
            if (stream == null)
            {
                throw new ArgumentNullException(nameof(stream));
            }

            if (encoding == null)
            {
                throw new ArgumentNullException(nameof(encoding));
            }

            if (leasedByteBuffer == null)
            {
                throw new ArgumentNullException(nameof(leasedByteBuffer));
            }

            if (leasedCharBuffer == null)
            {
                throw new ArgumentNullException(nameof(leasedCharBuffer));
            }

            var requiredLength = encoding.GetMaxByteCount(bufferSize);

            if (requiredLength > leasedByteBuffer.Data.Count)
            {
                var message = Resources.FormatHttpResponseStreamWriter_InvalidBufferSize(
                    requiredLength,
                    bufferSize,
                    encoding.EncodingName,
                    typeof(Encoding).FullName,
                    nameof(Encoding.GetMaxByteCount));
                throw new ArgumentException(message, nameof(leasedByteBuffer));
            }

            _stream           = stream;
            Encoding          = encoding;
            _charBufferSize   = bufferSize;
            _leasedByteBuffer = leasedByteBuffer;
            _leasedCharBuffer = leasedCharBuffer;

            _encoder    = encoding.GetEncoder();
            _byteBuffer = leasedByteBuffer.Data;
            _charBuffer = leasedCharBuffer.Data;
        }
        public HttpResponseStreamWriter(
            Stream stream,
            Encoding encoding,
            int bufferSize,
            LeasedArraySegment<byte> leasedByteBuffer,
            LeasedArraySegment<char> leasedCharBuffer)
        {
            if (stream == null)
            {
                throw new ArgumentNullException(nameof(stream));
            }

            if (encoding == null)
            {
                throw new ArgumentNullException(nameof(encoding));
            }

            if (leasedByteBuffer == null)
            {
                throw new ArgumentNullException(nameof(leasedByteBuffer));
            }

            if (leasedCharBuffer == null)
            {
                throw new ArgumentNullException(nameof(leasedCharBuffer));
            }

            var requiredLength = encoding.GetMaxByteCount(bufferSize);
            if (requiredLength > leasedByteBuffer.Data.Count)
            {
                var message = Resources.FormatHttpResponseStreamWriter_InvalidBufferSize(
                    requiredLength,
                    bufferSize,
                    encoding.EncodingName,
                    typeof(Encoding).FullName,
                    nameof(Encoding.GetMaxByteCount));
                throw new ArgumentException(message, nameof(leasedByteBuffer));
            }

            _stream = stream;
            Encoding = encoding;
            _charBufferSize = bufferSize;
            _leasedByteBuffer = leasedByteBuffer;
            _leasedCharBuffer = leasedCharBuffer;

            _encoder = encoding.GetEncoder();
            _byteBuffer = leasedByteBuffer.Data;
            _charBuffer = leasedCharBuffer.Data;
        }
        public void HttpResponseStreamWriter_UsingPooledBuffers()
        {
            // Arrange
            var encoding = Encoding.UTF8;
            var stream   = new MemoryStream();

            var expectedBytes = encoding.GetBytes("Hello, World!");

            using (var bytePool = new DefaultArraySegmentPool <byte>())
            {
                using (var charPool = new DefaultArraySegmentPool <char>())
                {
                    LeasedArraySegment <byte> bytes = null;
                    LeasedArraySegment <char> chars = null;
                    HttpResponseStreamWriter  writer;

                    try
                    {
                        bytes = bytePool.Lease(4096);
                        chars = charPool.Lease(1024);

                        writer = new HttpResponseStreamWriter(stream, encoding, 1024, bytes, chars);
                    }
                    catch
                    {
                        if (bytes != null)
                        {
                            bytes.Owner.Return(bytes);
                        }

                        if (chars != null)
                        {
                            chars.Owner.Return(chars);
                        }

                        throw;
                    }

                    // Act
                    using (writer)
                    {
                        writer.Write("Hello, World!");
                    }
                }
            }

            // Assert
            Assert.Equal(expectedBytes, stream.ToArray());
        }
        public void HttpResponseStreamWriter_UsingPooledBuffers_SmallByteBuffer()
        {
            // Arrange
            var encoding = Encoding.UTF8;
            var stream   = new MemoryStream();

            var message =
                "The byte buffer must have a length of at least '12291' to be used with a char buffer of " +
                "size '4096' and encoding 'Unicode (UTF-8)'. Use 'System.Text.Encoding.GetMaxByteCount' " +
                "to compute the correct size for the byte buffer.";

            using (var bytePool = new DefaultArraySegmentPool <byte>())
            {
                using (var charPool = new DefaultArraySegmentPool <char>())
                {
                    LeasedArraySegment <byte> bytes  = null;
                    LeasedArraySegment <char> chars  = null;
                    HttpResponseStreamWriter  writer = null;

                    try
                    {
                        bytes = bytePool.Lease(1024);
                        chars = charPool.Lease(4096);

                        // Act & Assert
                        ExceptionAssert.ThrowsArgument(
                            () => writer = new HttpResponseStreamWriter(stream, encoding, chars.Data.Count, bytes, chars),
                            "byteBuffer",
                            message);
                        writer.Dispose();
                    }
                    catch
                    {
                        if (bytes != null)
                        {
                            bytes.Owner.Return(bytes);
                        }

                        if (chars != null)
                        {
                            chars.Owner.Return(chars);
                        }
                    }
                }
            }
        }
        /// <inheritdoc />
        public TextWriter CreateWriter(Stream stream, Encoding encoding)
        {
            if (stream == null)
            {
                throw new ArgumentNullException(nameof(stream));
            }

            if (encoding == null)
            {
                throw new ArgumentNullException(nameof(encoding));
            }

            LeasedArraySegment <byte> bytes = null;
            LeasedArraySegment <char> chars = null;

            try
            {
                chars = _charPool.Lease(DefaultBufferSize);

                // We need to compute the minimum size of the byte buffer based on the size of the char buffer,
                // so that we have enough room to encode the buffer in one shot.
                var minimumSize = encoding.GetMaxByteCount(DefaultBufferSize);
                bytes = _bytePool.Lease(minimumSize);

                return(new HttpResponseStreamWriter(stream, encoding, DefaultBufferSize, bytes, chars));
            }
            catch
            {
                if (bytes != null)
                {
                    bytes.Owner.Return(bytes);
                }

                if (chars != null)
                {
                    chars.Owner.Return(chars);
                }

                throw;
            }
        }