Inheritance: MemoryPoolTextWriter, IBinaryWriter
        public void CanEncodingSurrogatePairsCorrectly()
        {
            var bytes = new List<byte>();
            var writer = new BinaryMemoryPoolTextWriter(new MemoryPool());

            writer.Write("\U00024B62"[0]);
            writer.Write("\U00024B62"[1]);
            writer.Flush();

            var expected = new byte[] { 0xF0, 0xA4, 0xAD, 0xA2 };

            var buffer = writer.Buffer;
            Assert.Equal(4, buffer.Count);
            Assert.Equal(expected, new ArraySegment<byte>(buffer.Array, 0, buffer.Count));
        }
        private static Task PerformSend(object state)
        {
            var context = (SendContext)state;

            using (var writer = new BinaryMemoryPoolTextWriter(context.Transport.Pool))
            {
                writer.Write("data: ");
                context.Transport.JsonSerializer.Serialize(context.State, writer);
                writer.WriteLine();
                writer.WriteLine();
                writer.Flush();

                context.Transport.Context.Response.Write(writer.Buffer);
            }

            return context.Transport.Context.Response.Flush();
        }
        public void CanInterleaveStringsAndRawBinary()
        {
            var writer = new BinaryMemoryPoolTextWriter(new MemoryPool());

            var encoding = new UTF8Encoding();

            writer.Write('H');
            writer.Write('e');
            writer.Write("llo ");
            writer.Write(new ArraySegment<byte>(encoding.GetBytes("World")));
            writer.Flush();

            var buffer = writer.Buffer;
            Assert.Equal(11, buffer.Count);
            var s = encoding.GetString(buffer.Array, 0, buffer.Count);

            Assert.Equal("Hello World", s);
        }
        private static Task PerformPartialSend(object state)
        {
            var context = (LongPollingTransportContext)state;

            if (!context.Transport.IsAlive)
            {
                return TaskAsyncHelper.Empty;
            }

            using (var writer = new BinaryMemoryPoolTextWriter(context.Transport.Pool))
            {
                if (context.Transport.IsJsonp)
                {
                    writer.Write(context.Transport.JsonpCallback);
                    writer.Write("(");
                }

                context.Transport.JsonSerializer.Serialize(context.State, writer);

                if (context.Transport.IsJsonp)
                {
                    writer.Write(");");
                }

                writer.Flush();

                context.Transport.Context.Response.Write(writer.Buffer);
            }

            return context.Transport.Context.Response.Flush();
        }
        private static Task PerformSend(object state)
        {
            var context = (ForeverTransportContext)state;

            if (!context.Transport.IsAlive)
            {
                return TaskAsyncHelper.Empty;
            }

            context.Transport.Context.Response.ContentType = JsonUtility.JsonMimeType;

            using (var writer = new BinaryMemoryPoolTextWriter(context.Transport.Pool))
            {
                context.Transport.JsonSerializer.Serialize(context.State, writer);
                writer.Flush();

                context.Transport.Context.Response.Write(writer.Buffer);
            }

            return TaskAsyncHelper.Empty;
        }
        private static async Task PerformSend(object state)
        {
            var context = (WebSocketTransportContext)state;
            var socket = context.Transport._socket;

            using (var writer = new BinaryMemoryPoolTextWriter(context.Transport.Pool))
            {
                try
                {
                    context.Transport.JsonSerializer.Serialize(context.State, writer);
                    writer.Flush();

                    await socket.Send(writer.Buffer).PreserveCulture();
                }
                catch (Exception ex)
                {
                    // OnError will close the socket in the event of a JSON serialization or flush error.
                    // The client should then immediately reconnect instead of simply missing keep-alives.
                    context.Transport.OnError(ex);
                    throw;
                }
            }
        }