Ejemplo n.º 1
0
        private static ValueTask <int> WritePacketAsync(IByteHandler byteHandler, int sequenceNumber, ArraySegment <byte> contents, IOBehavior ioBehavior)
        {
            var bufferLength = contents.Count + 4;
            var buffer       = ArrayPool <byte> .Shared.Rent(bufferLength);

            SerializationUtility.WriteUInt32((uint)contents.Count, buffer, 0, 3);
            buffer[3] = (byte)sequenceNumber;
            Buffer.BlockCopy(contents.Array, contents.Offset, buffer, 4, contents.Count);
            var task = byteHandler.WriteBytesAsync(new ArraySegment <byte>(buffer, 0, bufferLength), ioBehavior);

            if (task.IsCompletedSuccessfully)
            {
                ArrayPool <byte> .Shared.Return(buffer);

                return(default(ValueTask <int>));
            }
            return(AddContinuation(task, buffer));

            // NOTE: use a local function (with no captures) to defer creation of lambda objects
            ValueTask <int> AddContinuation(ValueTask <int> task_, byte[] buffer_)
            {
                return(task_.ContinueWith(x =>
                {
                    ArrayPool <byte> .Shared.Return(buffer_);
                    return default(ValueTask <int>);
                }));
            }
        }
 public CompressedPayloadHandler(IByteHandler byteHandler)
 {
     m_uncompressedStream            = new MemoryStream();
     m_uncompressedStreamByteHandler = new StreamByteHandler(m_uncompressedStream);
     m_byteHandler        = byteHandler;
     m_bufferedByteReader = new BufferedByteReader();
 }
Ejemplo n.º 3
0
        public static ValueTask <int> WritePacketAsync(IByteHandler byteHandler, int sequenceNumber, ArraySegment <byte> contents, IOBehavior ioBehavior)
        {
            var bufferLength = contents.Count + 4;
            var buffer       = ArrayPool <byte> .Shared.Rent(bufferLength);

            SerializationUtility.WriteUInt32((uint)contents.Count, buffer, 0, 3);
            buffer[3] = (byte)sequenceNumber;
            Buffer.BlockCopy(contents.Array, contents.Offset, buffer, 4, contents.Count);
            return(byteHandler.WriteBytesAsync(new ArraySegment <byte>(buffer, 0, bufferLength), ioBehavior)
                   .ContinueWith(x =>
            {
                ArrayPool <byte> .Shared.Return(buffer);
                return default(ValueTask <int>);
            }));
        }
Ejemplo n.º 4
0
        private static ValueTask <int> WritePacketAsync(IByteHandler byteHandler, int sequenceNumber, ArraySegment <byte> contents, IOBehavior ioBehavior)
        {
            var bufferLength = contents.Count + 4;
            var buffer       = ArrayPool <byte> .Shared.Rent(bufferLength);

            SerializationUtility.WriteUInt32((uint)contents.Count, buffer, 0, 3);
            buffer[3] = (byte)sequenceNumber;
            Buffer.BlockCopy(contents.Array, contents.Offset, buffer, 4, contents.Count);
            var task = byteHandler.WriteBytesAsync(new ArraySegment <byte>(buffer, 0, bufferLength), ioBehavior);

            if (task.IsCompletedSuccessfully)
            {
                ArrayPool <byte> .Shared.Return(buffer);

                return(default);
Ejemplo n.º 5
0
        public static ValueTask <int> WritePayloadAsync(IByteHandler byteHandler, Func <int> getNextSequenceNumber, ArraySegment <byte> payload, IOBehavior ioBehavior)
        {
            if (payload.Count <= MaxPacketSize)
            {
                return(WritePacketAsync(byteHandler, getNextSequenceNumber(), payload, ioBehavior));
            }

            var writeTask = default(ValueTask <int>);

            for (var bytesSent = 0; bytesSent < payload.Count; bytesSent += MaxPacketSize)
            {
                var contents = new ArraySegment <byte>(payload.Array, payload.Offset + bytesSent, Math.Min(MaxPacketSize, payload.Count - bytesSent));
                writeTask = writeTask.ContinueWith(x => WritePacketAsync(byteHandler, getNextSequenceNumber(), contents, ioBehavior));
            }
            return(writeTask);
        }
Ejemplo n.º 6
0
        public static ValueTask <int> WritePayloadAsync(IByteHandler byteHandler, Func <int> getNextSequenceNumber, ArraySegment <byte> payload, IOBehavior ioBehavior)
        {
            return(payload.Count <= MaxPacketSize?WritePacketAsync(byteHandler, getNextSequenceNumber(), payload, ioBehavior) :
                       CreateTask(byteHandler, getNextSequenceNumber, payload, ioBehavior));

            // NOTE: use a local function (with no captures) to defer creation of lambda objects
            ValueTask <int> CreateTask(IByteHandler byteHandler_, Func <int> getNextSequenceNumber_, ArraySegment <byte> payload_, IOBehavior ioBehavior_)
            {
                var writeTask = default(ValueTask <int>);

                for (var bytesSent = 0; bytesSent < payload_.Count; bytesSent += MaxPacketSize)
                {
                    var contents = new ArraySegment <byte>(payload_.Array, payload_.Offset + bytesSent, Math.Min(MaxPacketSize, payload_.Count - bytesSent));
                    writeTask = writeTask.ContinueWith(x => WritePacketAsync(byteHandler_, getNextSequenceNumber_(), contents, ioBehavior_));
                }
                return(writeTask);
            }
        }
        public ValueTask <ArraySegment <byte> > ReadBytesAsync(IByteHandler byteHandler, int count, IOBehavior ioBehavior)
        {
            if (m_remainingData.Count >= count)
            {
                var readBytes = m_remainingData.Slice(0, count);
                m_remainingData = m_remainingData.Slice(count);
                return(new ValueTask <ArraySegment <byte> >(readBytes));
            }

            var buffer = count > m_buffer.Length ? new byte[count] : m_buffer;

            if (m_remainingData.Count > 0)
            {
                Buffer.BlockCopy(m_remainingData.Array, m_remainingData.Offset, buffer, 0, m_remainingData.Count);
                m_remainingData = new ArraySegment <byte>(buffer, 0, m_remainingData.Count);
            }

            return(ReadBytesAsync(byteHandler, new ArraySegment <byte>(buffer, m_remainingData.Count, buffer.Length - m_remainingData.Count), count, ioBehavior));
        }
Ejemplo n.º 8
0
        public ValueTask <ArraySegment <byte> > ReadBytesAsync(IByteHandler byteHandler, int count, IOBehavior ioBehavior)
        {
            // check if read can be satisfied from the buffer
            if (m_remainingData.Count >= count)
            {
                var readBytes = m_remainingData.Slice(0, count);
                m_remainingData = m_remainingData.Slice(count);
                return(new ValueTask <ArraySegment <byte> >(readBytes));
            }

            // get a buffer big enough to hold all the data, and move any buffered data to the beginning
            var buffer = count > m_buffer.Length ? new byte[count] : m_buffer;

            if (m_remainingData.Count > 0)
            {
                Buffer.BlockCopy(m_remainingData.Array, m_remainingData.Offset, buffer, 0, m_remainingData.Count);
                m_remainingData = new ArraySegment <byte>(buffer, 0, m_remainingData.Count);
            }

            return(ReadBytesAsync(byteHandler, new ArraySegment <byte>(buffer, m_remainingData.Count, buffer.Length - m_remainingData.Count), count, ioBehavior));
        }
Ejemplo n.º 9
0
        public ValueTask <ArraySegment <byte> > ReadBytesAsync(IByteHandler byteHandler, int count, IOBehavior ioBehavior)
        {
            if (m_remainingData.Count >= count)
            {
                var readBytes = m_remainingData.Slice(0, count);
                m_remainingData = m_remainingData.Slice(count);
                return(new ValueTask <ArraySegment <byte> >(readBytes));
            }

            if (m_remainingData.Count == 0)
            {
                return(ReadBytesAsync(byteHandler, default(ArraySegment <byte>), count, ioBehavior));
            }

            // save data from m_remainingData.Array because calling ReadAsync may invalidate it
            var buffer = new byte[Math.Max(count, 16384)];

            Buffer.BlockCopy(m_remainingData.Array, m_remainingData.Offset, buffer, 0, m_remainingData.Count);
            var previousReadBytes = new ArraySegment <byte>(buffer, 0, m_remainingData.Count);

            return(ReadBytesAsync(byteHandler, previousReadBytes, count, ioBehavior));
        }
Ejemplo n.º 10
0
        private ValueTask <ArraySegment <byte> > ReadBytesAsync(IByteHandler byteHandler, ArraySegment <byte> buffer, int totalBytesToRead, IOBehavior ioBehavior)
        {
            // keep reading data synchronously while it is available
            var readBytesTask = byteHandler.ReadBytesAsync(buffer, ioBehavior);

            while (readBytesTask.IsCompleted)
            {
                ValueTask <ArraySegment <byte> > result;
                if (HasReadAllData(readBytesTask.Result, ref buffer, totalBytesToRead, out result))
                {
                    return(result);
                }

                readBytesTask = byteHandler.ReadBytesAsync(buffer, ioBehavior);
            }

            // call .ContinueWith (as a separate method, so that the temporary class for the lambda is only allocated if necessary)
            return(AddContinuation(readBytesTask, byteHandler, buffer, totalBytesToRead, ioBehavior));

            ValueTask <ArraySegment <byte> > AddContinuation(ValueTask <int> readBytesTask_, IByteHandler byteHandler_, ArraySegment <byte> buffer_, int totalBytesToRead_, IOBehavior ioBehavior_) =>
            readBytesTask_.ContinueWith(x => HasReadAllData(x, ref buffer_, totalBytesToRead_, out var result_) ? result_ : ReadBytesAsync(byteHandler_, buffer_, totalBytesToRead_, ioBehavior_));
        }
Ejemplo n.º 11
0
        private ValueTask <ArraySegment <byte> > ReadBytesAsync(IByteHandler byteHandler, ArraySegment <byte> previousReadBytes, int count, IOBehavior ioBehavior)
        {
            return(byteHandler.ReadBytesAsync(count - previousReadBytes.Count, ioBehavior)
                   .ContinueWith(readBytes =>
            {
                if (readBytes.Count == 0)
                {
                    return new ValueTask <ArraySegment <byte> >(previousReadBytes);
                }

                if (previousReadBytes.Array == null && readBytes.Count >= count)
                {
                    m_remainingData = readBytes.Slice(count);
                    return new ValueTask <ArraySegment <byte> >(readBytes.Slice(0, count));
                }

                var previousReadBytesArray = previousReadBytes.Array;
                if (previousReadBytesArray == null)
                {
                    previousReadBytesArray = new byte[Math.Max(count, 16384)];
                }
                else if (previousReadBytesArray.Length < previousReadBytes.Count + readBytes.Count)
                {
                    Array.Resize(ref previousReadBytesArray, Math.Max(previousReadBytesArray.Length * 2, previousReadBytes.Count + readBytes.Count));
                }

                Buffer.BlockCopy(readBytes.Array, readBytes.Offset, previousReadBytesArray, previousReadBytes.Offset + previousReadBytes.Count, readBytes.Count);
                previousReadBytes = new ArraySegment <byte>(previousReadBytesArray, previousReadBytes.Offset, previousReadBytes.Count + readBytes.Count);

                if (previousReadBytes.Count >= count)
                {
                    m_remainingData = previousReadBytes.Slice(count);
                    return new ValueTask <ArraySegment <byte> >(previousReadBytes.Slice(0, count));
                }

                return ReadBytesAsync(byteHandler, previousReadBytes, count, ioBehavior);
            }));
        }
        private ValueTask <ArraySegment <byte> > ReadBytesAsync(IByteHandler byteHandler, ArraySegment <byte> buffer, int count, IOBehavior ioBehavior)
        {
            return(byteHandler.ReadBytesAsync(buffer, ioBehavior)
                   .ContinueWith(readBytesCount =>
            {
                if (readBytesCount == 0)
                {
                    var data = m_remainingData;
                    m_remainingData = default(ArraySegment <byte>);
                    return new ValueTask <ArraySegment <byte> >(data);
                }

                var bufferSize = buffer.Offset + readBytesCount;
                if (bufferSize >= count)
                {
                    var bufferBytes = new ArraySegment <byte>(buffer.Array, 0, bufferSize);
                    var requestedBytes = bufferBytes.Slice(0, count);
                    m_remainingData = bufferBytes.Slice(count);
                    return new ValueTask <ArraySegment <byte> >(requestedBytes);
                }

                return ReadBytesAsync(byteHandler, new ArraySegment <byte>(buffer.Array, bufferSize, buffer.Array.Length - bufferSize), count, ioBehavior);
            }));
        }
Ejemplo n.º 13
0
 public StandardPayloadHandler(IByteHandler byteHandler)
 {
     ByteHandler = byteHandler;
 }
Ejemplo n.º 14
0
 static ValueTask <Packet> AddContinuation(ValueTask <ArraySegment <byte> > headerBytes_, BufferedByteReader bufferedByteReader_, IByteHandler byteHandler_, Func <int> getNextSequenceNumber_, ProtocolErrorBehavior protocolErrorBehavior_, IOBehavior ioBehavior_) =>
 headerBytes_.ContinueWith(x => ReadPacketAfterHeader(x, bufferedByteReader_, byteHandler_, getNextSequenceNumber_, protocolErrorBehavior_, ioBehavior_));
Ejemplo n.º 15
0
        public static ValueTask <Packet> ReadPacketAsync(BufferedByteReader bufferedByteReader, IByteHandler byteHandler, Func <int?> getNextSequenceNumber, ProtocolErrorBehavior protocolErrorBehavior, IOBehavior ioBehavior)
        {
            return(bufferedByteReader.ReadBytesAsync(byteHandler, 4, ioBehavior)
                   .ContinueWith(headerBytes =>
            {
                if (headerBytes.Count < 4)
                {
                    return protocolErrorBehavior == ProtocolErrorBehavior.Throw ?
                    ValueTaskExtensions.FromException <Packet>(new EndOfStreamException()) :
                    default(ValueTask <Packet>);
                }

                var payloadLength = (int)SerializationUtility.ReadUInt32(headerBytes.Array, headerBytes.Offset, 3);
                int packetSequenceNumber = headerBytes.Array[headerBytes.Offset + 3];

                var expectedSequenceNumber = getNextSequenceNumber() % 256;
                if (expectedSequenceNumber.HasValue && packetSequenceNumber != expectedSequenceNumber.Value)
                {
                    if (protocolErrorBehavior == ProtocolErrorBehavior.Ignore)
                    {
                        return default(ValueTask <Packet>);
                    }

                    var exception = new InvalidOperationException("Packet received out-of-order. Expected {0}; got {1}.".FormatInvariant(expectedSequenceNumber.Value, packetSequenceNumber));
                    return ValueTaskExtensions.FromException <Packet>(exception);
                }

                return bufferedByteReader.ReadBytesAsync(byteHandler, payloadLength, ioBehavior)
                .ContinueWith(payloadBytes =>
                {
                    if (payloadBytes.Count < payloadLength)
                    {
                        return protocolErrorBehavior == ProtocolErrorBehavior.Throw ?
                        ValueTaskExtensions.FromException <Packet>(new EndOfStreamException()) :
                        default(ValueTask <Packet>);
                    }

                    return new ValueTask <Packet>(new Packet(packetSequenceNumber, payloadBytes));
                });
            }));
        }
Ejemplo n.º 16
0
        private static ValueTask <ArraySegment <byte> > DoReadPayloadAsync(BufferedByteReader bufferedByteReader, IByteHandler byteHandler, Func <int> getNextSequenceNumber, ArraySegmentHolder <byte> previousPayloads, ProtocolErrorBehavior protocolErrorBehavior, IOBehavior ioBehavior)
        {
            var readPacketTask = ReadPacketAsync(bufferedByteReader, byteHandler, getNextSequenceNumber, protocolErrorBehavior, ioBehavior);

            while (readPacketTask.IsCompleted)
            {
                if (HasReadPayload(previousPayloads, readPacketTask.Result, protocolErrorBehavior, out var result))
                {
                    return(result);
                }

                readPacketTask = ReadPacketAsync(bufferedByteReader, byteHandler, getNextSequenceNumber, protocolErrorBehavior, ioBehavior);
            }

            return(AddContinuation(readPacketTask, bufferedByteReader, byteHandler, getNextSequenceNumber, previousPayloads, protocolErrorBehavior, ioBehavior));

            // NOTE: use a local function (with no captures) to defer creation of lambda objects
            ValueTask <ArraySegment <byte> > AddContinuation(ValueTask <Packet> readPacketTask_, BufferedByteReader bufferedByteReader_, IByteHandler byteHandler_, Func <int> getNextSequenceNumber_, ArraySegmentHolder <byte> previousPayloads_, ProtocolErrorBehavior protocolErrorBehavior_, IOBehavior ioBehavior_)
            {
                return(readPacketTask_.ContinueWith(packet =>
                                                    HasReadPayload(previousPayloads_, packet, protocolErrorBehavior_, out var result_) ? result_ :
                                                    DoReadPayloadAsync(bufferedByteReader_, byteHandler_, getNextSequenceNumber_, previousPayloads_, protocolErrorBehavior_, ioBehavior_)));
            }
        }
Ejemplo n.º 17
0
 public static ValueTask <ArraySegment <byte> > ReadPayloadAsync(BufferedByteReader bufferedByteReader, IByteHandler byteHandler, Func <int> getNextSequenceNumber, ArraySegmentHolder <byte> cache, ProtocolErrorBehavior protocolErrorBehavior, IOBehavior ioBehavior)
 {
     cache.Clear();
     return(DoReadPayloadAsync(bufferedByteReader, byteHandler, getNextSequenceNumber, cache, protocolErrorBehavior, ioBehavior));
 }
Ejemplo n.º 18
0
        private static ValueTask <Packet> ReadPacketAfterHeader(ArraySegment <byte> headerBytes, BufferedByteReader bufferedByteReader, IByteHandler byteHandler, Func <int> getNextSequenceNumber, ProtocolErrorBehavior protocolErrorBehavior, IOBehavior ioBehavior)
        {
            if (headerBytes.Count < 4)
            {
                return(protocolErrorBehavior == ProtocolErrorBehavior.Throw ?
                       ValueTaskExtensions.FromException <Packet>(new EndOfStreamException("Expected to read 4 header bytes but only received {0}.".FormatInvariant(headerBytes.Count))) :
                       default(ValueTask <Packet>));
            }

            var payloadLength        = (int)SerializationUtility.ReadUInt32(headerBytes.Array, headerBytes.Offset, 3);
            int packetSequenceNumber = headerBytes.Array[headerBytes.Offset + 3];

            var expectedSequenceNumber = getNextSequenceNumber() % 256;

            if (expectedSequenceNumber != -1 && packetSequenceNumber != expectedSequenceNumber)
            {
                if (protocolErrorBehavior == ProtocolErrorBehavior.Ignore)
                {
                    return(default(ValueTask <Packet>));
                }

                var exception = MySqlProtocolException.CreateForPacketOutOfOrder(expectedSequenceNumber, packetSequenceNumber);
                return(ValueTaskExtensions.FromException <Packet>(exception));
            }

            var payloadBytesTask = bufferedByteReader.ReadBytesAsync(byteHandler, payloadLength, ioBehavior);

            if (payloadBytesTask.IsCompleted)
            {
                return(CreatePacketFromPayload(payloadBytesTask.Result, payloadLength, protocolErrorBehavior));
            }
            return(AddContinuation(payloadBytesTask, payloadLength, protocolErrorBehavior));

            // NOTE: use a local function (with no captures) to defer creation of lambda objects
            ValueTask <Packet> AddContinuation(ValueTask <ArraySegment <byte> > payloadBytesTask_, int payloadLength_, ProtocolErrorBehavior protocolErrorBehavior_)
            => payloadBytesTask_.ContinueWith(x => CreatePacketFromPayload(x, payloadLength_, protocolErrorBehavior_));
        }
Ejemplo n.º 19
0
        private static ValueTask <Packet> ReadPacketAsync(BufferedByteReader bufferedByteReader, IByteHandler byteHandler, Func <int> getNextSequenceNumber, ProtocolErrorBehavior protocolErrorBehavior, IOBehavior ioBehavior)
        {
            var headerBytesTask = bufferedByteReader.ReadBytesAsync(byteHandler, 4, ioBehavior);

            if (headerBytesTask.IsCompleted)
            {
                return(ReadPacketAfterHeader(headerBytesTask.Result, bufferedByteReader, byteHandler, getNextSequenceNumber, protocolErrorBehavior, ioBehavior));
            }
            return(AddContinuation(headerBytesTask, bufferedByteReader, byteHandler, getNextSequenceNumber, protocolErrorBehavior, ioBehavior));

            // NOTE: use a local function (with no captures) to defer creation of lambda objects
            ValueTask <Packet> AddContinuation(ValueTask <ArraySegment <byte> > headerBytes_, BufferedByteReader bufferedByteReader_, IByteHandler byteHandler_, Func <int> getNextSequenceNumber_, ProtocolErrorBehavior protocolErrorBehavior_, IOBehavior ioBehavior_) =>
            headerBytes_.ContinueWith(x => ReadPacketAfterHeader(x, bufferedByteReader_, byteHandler_, getNextSequenceNumber_, protocolErrorBehavior_, ioBehavior_));
        }
 public StandardPayloadHandler(IByteHandler byteHandler)
 {
     ByteHandler             = byteHandler;
     m_getNextSequenceNumber = () => m_sequenceNumber++;
 }
Ejemplo n.º 21
0
 static async ValueTask <Packet> AddContinuation(ValueTask <ArraySegment <byte> > headerBytes_, BufferedByteReader bufferedByteReader_, IByteHandler byteHandler_, Func <int> getNextSequenceNumber_, ProtocolErrorBehavior protocolErrorBehavior_, IOBehavior ioBehavior_) =>
 await ReadPacketAfterHeader(await headerBytes_.ConfigureAwait(false), bufferedByteReader_, byteHandler_, getNextSequenceNumber_, protocolErrorBehavior_, ioBehavior_).ConfigureAwait(false);
Ejemplo n.º 22
0
        private static ValueTask <Packet> ReadPacketAsync(BufferedByteReader bufferedByteReader, IByteHandler byteHandler, Func <int> getNextSequenceNumber, ProtocolErrorBehavior protocolErrorBehavior, IOBehavior ioBehavior)
        {
            var headerBytesTask = bufferedByteReader.ReadBytesAsync(byteHandler, 4, ioBehavior);

            if (headerBytesTask.IsCompleted)
            {
                return(ReadPacketAfterHeader(headerBytesTask.Result, bufferedByteReader, byteHandler, getNextSequenceNumber, protocolErrorBehavior, ioBehavior));
            }
            return(AddContinuation(headerBytesTask, bufferedByteReader, byteHandler, getNextSequenceNumber, protocolErrorBehavior, ioBehavior));
Ejemplo n.º 23
0
 public static ValueTask <ArraySegment <byte> > ReadPayloadAsync(BufferedByteReader bufferedByteReader, IByteHandler byteHandler, Func <int?> getNextSequenceNumber, ArraySegment <byte> previousPayloads, ProtocolErrorBehavior protocolErrorBehavior, IOBehavior ioBehavior)
 {
     return(ReadPacketAsync(bufferedByteReader, byteHandler, getNextSequenceNumber, protocolErrorBehavior, ioBehavior).ContinueWith(packet =>
                                                                                                                                    ContinueRead(bufferedByteReader, byteHandler, getNextSequenceNumber, previousPayloads, packet, protocolErrorBehavior, ioBehavior)));
 }
Ejemplo n.º 24
0
        private static ValueTask <ArraySegment <byte> > ContinueRead(BufferedByteReader bufferedByteReader, IByteHandler byteHandler, Func <int?> getNextSequenceNumber, ArraySegment <byte> previousPayloads, Packet packet, ProtocolErrorBehavior protocolErrorBehavior, IOBehavior ioBehavior)
        {
            if (packet == null && protocolErrorBehavior == ProtocolErrorBehavior.Ignore)
            {
                return(default(ValueTask <ArraySegment <byte> >));
            }

            var previousPayloadsArray = previousPayloads.Array;

            if (previousPayloadsArray == null && packet.Contents.Count < MaxPacketSize)
            {
                return(new ValueTask <ArraySegment <byte> >(packet.Contents));
            }

            if (previousPayloadsArray == null)
            {
                previousPayloadsArray = new byte[ProtocolUtility.MaxPacketSize + 1];
            }
            else if (previousPayloads.Offset + previousPayloads.Count + packet.Contents.Count > previousPayloadsArray.Length)
            {
                Array.Resize(ref previousPayloadsArray, previousPayloadsArray.Length * 2);
            }

            Buffer.BlockCopy(packet.Contents.Array, packet.Contents.Offset, previousPayloadsArray, previousPayloads.Offset + previousPayloads.Count, packet.Contents.Count);
            previousPayloads = new ArraySegment <byte>(previousPayloadsArray, previousPayloads.Offset, previousPayloads.Count + packet.Contents.Count);

            return(packet.Contents.Count < ProtocolUtility.MaxPacketSize ?
                   new ValueTask <ArraySegment <byte> >(previousPayloads) :
                   ReadPayloadAsync(bufferedByteReader, byteHandler, getNextSequenceNumber, previousPayloads, protocolErrorBehavior, ioBehavior));
        }