internal void OnTransfer(List transfer, ByteBuffer payload) { for (int i = transfer.Count; i < 11; i++) { transfer.Add(null); } bool more = transfer[5] != null && true.Equals(transfer[5]); if (transfer[1] == null || (this.deliveryReceived && this.lastDeliveryId.Equals(transfer[1]))) { AmqpBitConverter.WriteBytes(this.messageBuffer, payload.Buffer, payload.Offset, payload.Length); } else { lock (this) { Fx.AssertAndThrow(ErrorCode.InvalidCreditOnTransfer, this.credit > 0); this.deliveryCount++; if (this.credit < uint.MaxValue) { this.credit--; } } this.lastDeliveryId = (uint)transfer[1]; this.deliveryReceived = true; if (this.messageBuffer == null) { if (more) { this.messageBuffer = new ByteBuffer(payload.Length * 2, true); AmqpBitConverter.WriteBytes(this.messageBuffer, payload.Buffer, payload.Offset, payload.Length); } else { this.messageBuffer = payload; } } } if (!more) // more { Message message = Message.Decode(this.messageBuffer); this.messageBuffer = null; message.deliveryId = this.lastDeliveryId; message.settled = transfer[4] != null && true.Equals(transfer[4]); this.onMessage(this, message); } }
internal int SendCommand(ushort channel, Transfer transfer, bool first, ByteBuffer payload, int reservedBytes) { this.ThrowIfClosed("Send"); ByteBuffer buffer = this.AllocateBuffer(Frame.CmdBufferSize); Frame.Encode(buffer, FrameType.Amqp, channel, transfer); int payloadSize = payload.Length; int frameSize = buffer.Length + payloadSize; bool more = frameSize > this.remoteMaxFrameSize; if (more) { transfer.More = true; buffer.Reset(); Frame.Encode(buffer, FrameType.Amqp, channel, transfer); frameSize = (int)this.remoteMaxFrameSize; payloadSize = frameSize - buffer.Length; } AmqpBitConverter.WriteInt(buffer.Buffer, buffer.Offset, frameSize); ByteBuffer frameBuffer; if (first && !more && reservedBytes >= buffer.Length) { // optimize for most common case: single-transfer message frameBuffer = this.WrapBuffer(payload, payload.Offset - buffer.Length, frameSize); Array.Copy(buffer.Buffer, buffer.Offset, frameBuffer.Buffer, frameBuffer.Offset, buffer.Length); buffer.ReleaseReference(); } else { AmqpBitConverter.WriteBytes(buffer, payload.Buffer, payload.Offset, payloadSize); frameBuffer = buffer; } payload.Complete(payloadSize); this.writer.Send(frameBuffer); if (Trace.TraceLevel >= TraceLevel.Frame) { Trace.WriteLine(TraceLevel.Frame, "SEND (ch={0}) {1} payload {2}", channel, transfer, payloadSize); } return(payloadSize); }
internal override void OnTransfer(Delivery delivery, Transfer transfer, ByteBuffer buffer) { if (delivery == null) { delivery = this.deliveryCurrent; AmqpBitConverter.WriteBytes(delivery.Buffer, buffer.Buffer, buffer.Offset, buffer.Length); } else { buffer.AddReference(); delivery.Buffer = buffer; lock (this.ThisLock) { this.OnDelivery(transfer.DeliveryId); } } if (!transfer.More) { this.deliveryCurrent = null; delivery.Message = Message.Decode(delivery.Buffer); Waiter waiter; MessageCallback callback = this.onMessage; lock (this.ThisLock) { waiter = (Waiter)this.waiterList.First; if (waiter != null) { this.waiterList.Remove(waiter); } else if (callback == null) { this.receivedMessages.Add(new MessageNode() { Message = delivery.Message }); return; } } while (waiter != null) { if (waiter.Signal(delivery.Message)) { return; } lock (this.ThisLock) { waiter = (Waiter)this.waiterList.First; if (waiter != null) { this.waiterList.Remove(waiter); } else if (callback == null) { this.receivedMessages.Add(new MessageNode() { Message = delivery.Message }); return; } } } Fx.Assert(waiter == null, "waiter must be null now"); Fx.Assert(callback != null, "callback must not be null now"); callback(this, delivery.Message); } else { this.deliveryCurrent = delivery; } }
internal override void OnTransfer(Delivery delivery, Transfer transfer, ByteBuffer buffer) { if (!transfer.More) { Waiter waiter; MessageCallback callback; lock (this.ThisLock) { if (delivery == null) { // multi-transfer delivery delivery = this.deliveryCurrent; this.deliveryCurrent = null; Fx.Assert(delivery != null, "Must have a delivery in the queue"); AmqpBitConverter.WriteBytes(delivery.Buffer, buffer.Buffer, buffer.Offset, buffer.Length); delivery.Message = Message.Decode(delivery.Buffer); delivery.Buffer = null; } else { // single tranfer delivery this.OnDelivery(transfer.DeliveryId); delivery.Message = Message.Decode(buffer); } callback = this.onMessage; waiter = (Waiter)this.waiterList.First; if (waiter != null) { this.waiterList.Remove(waiter); } if (waiter == null && callback == null) { this.receivedMessages.Add(new MessageNode() { Message = delivery.Message }); return; } } while (waiter != null) { if (waiter.Signal(delivery.Message)) { this.OnDeliverMessage(); return; } lock (this.ThisLock) { waiter = (Waiter)this.waiterList.First; if (waiter != null) { this.waiterList.Remove(waiter); } else if (callback == null) { this.receivedMessages.Add(new MessageNode() { Message = delivery.Message }); return; } } } Fx.Assert(waiter == null, "waiter must be null now"); Fx.Assert(callback != null, "callback must not be null now"); callback(this, delivery.Message); this.OnDeliverMessage(); } else { lock (this.ThisLock) { if (delivery == null) { delivery = this.deliveryCurrent; Fx.Assert(delivery != null, "Must have a current delivery"); AmqpBitConverter.WriteBytes(delivery.Buffer, buffer.Buffer, buffer.Offset, buffer.Length); } else { this.OnDelivery(transfer.DeliveryId); delivery.Buffer = new ByteBuffer(buffer.Length * 2, true); AmqpBitConverter.WriteBytes(delivery.Buffer, buffer.Buffer, buffer.Offset, buffer.Length); this.deliveryCurrent = delivery; } } } }