void ReadBuffer() { try { if (this.asyncIo.State == AmqpObjectState.End) { this.Cleanup(); ByteBuffer buffer = (ByteBuffer)this.readAsyncEventArgs.UserToken2; if (buffer != null) { buffer.Dispose(); } } else { while (this.asyncIo.State != AmqpObjectState.End) { if (!this.asyncIo.transport.ReadAsync(this.readAsyncEventArgs)) { if (!this.HandleReadBufferComplete(this.readAsyncEventArgs)) { break; } } else { break; } } } } catch (Exception exception) { if (Fx.IsFatal(exception)) { throw; } this.asyncIo.ioHandler.OnIoFault(exception); this.Cleanup(); } }
internal bool SendDelivery(Delivery delivery) { bool settled = delivery.Settled; bool more = true; while (more) { bool firstTransfer = delivery.BytesTransfered == 0; Transfer transfer = new Transfer(); transfer.Handle = this.LocalHandle; transfer.More = more; if (firstTransfer) { transfer.DeliveryId = uint.MaxValue; // reserve the space first transfer.DeliveryTag = delivery.DeliveryTag; transfer.MessageFormat = delivery.MessageFormat ?? AmqpConstants.AmqpMessageFormat; transfer.Batchable = delivery.Batchable; transfer.State = delivery.State; if (settled) { transfer.Settled = true; } if (delivery.TxnId.Array != null) { transfer.State = new TransactionalState() { TxnId = delivery.TxnId }; } } uint maxFrameSize = this.MaxFrameSize == uint.MaxValue ? AmqpConstants.DefaultMaxFrameSize : this.MaxFrameSize; int overhead = Frame.HeaderSize + transfer.EncodeSize; if (overhead > maxFrameSize) { throw new AmqpException(AmqpErrorCode.FrameSizeTooSmall, null); } int payloadSize = (int)maxFrameSize - overhead; ByteBuffer payload = delivery.GetPayload(payloadSize, out more); transfer.More = more; if (!firstTransfer && payload == null) { Fx.Assert(!more, "More flag is set but a null payload is returned."); break; } if (!this.Session.TrySendTransfer(firstTransfer ? delivery : null, transfer, payload)) { payload.Dispose(); more = true; break; } delivery.CompletePayload(payload.Length); } if (!more && settled) { delivery.State = AmqpConstants.AcceptedOutcome; this.OnDisposeDeliveryInternal(delivery); } return(!more); }
bool HandleReadComplete(TransportAsyncCallbackArgs args) { bool completed = true; Exception exception = null; if (args.Exception != null) { exception = args.Exception; } else if (args.BytesTransfered == 0) { exception = new ObjectDisposedException(this.transport.ToString()); } else if (args.BytesTransfered == args.Count) { args.ByteBuffer?.Append(args.BytesTransfered); } else { completed = false; if (args.ByteBuffer == null) { args.SetBuffer(args.Buffer, args.Offset + args.BytesTransfered, args.Count - args.BytesTransfered); } else { args.ByteBuffer.Append(args.BytesTransfered); args.SetReadBuffer(args.ByteBuffer); } } if (completed) { if (exception != null || object.ReferenceEquals(args.CompletedCallback, onFrameComplete)) { ByteBuffer buffer = args.ByteBuffer; try { if (exception == null) { this.parent.OnReceiveBuffer(buffer); } else { this.parent.OnIoFault(exception); } } finally { buffer?.Dispose(); } } else { // read size completed ok uint size = AmqpBitConverter.ReadUInt(this.sizeBuffer, 0, this.sizeBuffer.Length); if (size > this.maxFrameSize) { completed = true; exception = new AmqpException(AmqpErrorCode.FramingError, CommonResources.GetString(CommonResources.InvalidFrameSize, size, this.maxFrameSize)); this.parent.OnIoFault(exception); } else { ByteBuffer buffer = this.parent.CreateBuffer((int)size); args.SetReadBuffer(buffer); args.CompletedCallback = onFrameComplete; completed = false; } } } return(completed); }