Пример #1
0
        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);
            }
        }
Пример #2
0
        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);
        }
Пример #3
0
        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;
            }
        }
Пример #4
0
        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;
                    }
                }
            }
        }