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);
Ejemplo n.º 2
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_));
        }