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);
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_)); }