A byte array wrapper that has read and write cursors.
Example #1
0
        internal void Encode(ByteBuffer buffer)
        {
            if (this.MessageAnnotations != null)
            {
                Encoder.WriteObject(buffer, new DescribedValue(0x72ul, this.MessageAnnotations));
            }

            if (this.Properties != null)
            {
                Encoder.WriteObject(buffer, new DescribedValue(0x73ul, this.Properties));
            }

            if (this.ApplicationProperties != null)
            {
                Encoder.WriteObject(buffer, new DescribedValue(0x74ul, this.ApplicationProperties));
            }

            if (this.Body != null)
            {
                if (this.Body is byte[])
                {
                    Encoder.WriteObject(buffer, new DescribedValue(0x75ul, this.Body));
                }
                else
                {
                    Encoder.WriteObject(buffer, new DescribedValue(0x77ul, this.Body));
                }
            }
        }
Example #2
0
        internal static Message Decode(ByteBuffer buffer)
        {
            Message message = new Message();
            while (buffer.Length > 0)
            {
                var section = (DescribedValue)Encoder.ReadObject(buffer);
                if (section.Descriptor.Equals(0x72ul))
                {
                    message.MessageAnnotations = (Map)section.Value;
                }
                else if (section.Descriptor.Equals(0x73ul))
                {
                    List list = (List)section.Value;
                    for (int i = list.Count; i < 13; i++)
                    {
                        list.Add(null);
                    }

                    message.properties = list;
                }
                else if (section.Descriptor.Equals(0x74ul))
                {
                    message.ApplicationProperties = (Map)section.Value;
                }
                else if (section.Descriptor.Equals(0x75ul) ||
                    section.Descriptor.Equals(0x76ul) ||
                    section.Descriptor.Equals(0x77ul))
                {
                    message.Body = section.Value;
                }
            }

            return message;
        }
Example #3
0
 void ITransport.Send(ByteBuffer buffer)
 {
     base.Write(buffer.Buffer, buffer.Offset, buffer.Length);
 }
Example #4
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))
                    {
                        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
            {
                this.deliveryCurrent = delivery;
            }
        }
Example #5
0
 public void Send(ByteBuffer buffer)
 {
     this.socketTransport.Send(buffer);
 }
Example #6
0
 void ITransport.Send(ByteBuffer buffer)
 {
     base.Send(buffer.Buffer, buffer.Offset, buffer.Length, SocketFlags.None);
 }
Example #7
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;
                    }
                }
            }
        }
Example #8
0
 void ITransport.Send(ByteBuffer buffer)
 {
     this.pipeStream.Write(buffer.Buffer, buffer.Offset, buffer.Length);
 }
Example #9
0
 void ITransport.Send(ByteBuffer buffer)
 {
     // make it non-blocking
     this.pipeStream.WriteAsync(buffer.Buffer, buffer.Offset, buffer.Length);
 }
Example #10
0
        void ReadFrame(out byte frameType, out ushort channel, out ulong code, out List fields, out ByteBuffer payload)
        {
            byte[] headerBuffer = this.ReadFixedSizeBuffer(8);
            int    size         = AmqpBitConverter.ReadInt(headerBuffer, 0);

            frameType = headerBuffer[5];    // TODO: header EXT
            channel   = (ushort)(headerBuffer[6] << 8 | headerBuffer[7]);

            size -= 8;
            if (size > 0)
            {
                byte[]     frameBuffer = this.ReadFixedSizeBuffer(size);
                ByteBuffer buffer      = new ByteBuffer(frameBuffer, 0, size, size);
                Fx.AssertAndThrow(ErrorCode.ClientInvalidFormatCodeRead, Encoder.ReadFormatCode(buffer) == FormatCode.Described);

                code   = Encoder.ReadULong(buffer, Encoder.ReadFormatCode(buffer));
                fields = Encoder.ReadList(buffer, Encoder.ReadFormatCode(buffer));
                if (buffer.Length > 0)
                {
                    payload = new ByteBuffer(buffer.Buffer, buffer.Offset, buffer.Length, buffer.Length);
                }
                else
                {
                    payload = null;
                }
            }
            else
            {
                code    = 0;
                fields  = null;
                payload = null;
            }
        }
Example #11
0
        void OnFrame(ushort channel, ulong code, List fields, ByteBuffer payload)
        {
            switch (code)
            {
            case 0x10ul:      // open
                Fx.DebugPrint(false, channel, "open", fields, "container-id", "host-name", "max-frame-size", "channel-max", "idle-time-out");
                this.state |= OpenReceived;

                // process open.idle-time-out if exists: final value is determined by the min of the local and the remote values
                uint remoteValue = uint.MaxValue;
                if (fields.Count >= 5 && fields[4] != null)
                {
                    remoteValue = (uint)fields[4];
                }
                uint timeout = this.idleTimeout < remoteValue ? this.idleTimeout : remoteValue;
                if (timeout < uint.MaxValue)
                {
                    timeout            -= 5000;
                    timeout             = timeout > MaxIdleTimeout ? MaxIdleTimeout : timeout;
                    this.heartBeatTimer = new Timer(onHeartBeatTimer, this, (int)timeout, (int)timeout);
                }
                break;

            case 0x11ul:      // begin
                Fx.DebugPrint(false, channel, "begin", fields, "remote-channel", "next-outgoing-id", "incoming-window", "outgoing-window", "handle-max");
                this.nextIncomingId = (uint)fields[1];
                this.outWindow      = (uint)fields[2];
                this.state         |= BeginReceived;
                break;

            case 0x12ul:      // attach
            {
                Fx.DebugPrint(false, channel, "attach", fields, "name", "handle", "role", "snd-mode", "rcv-mode", "source", "target");
                Link link         = null;
                uint remoteHandle = (uint)fields[1];
                Fx.AssertAndThrow(ErrorCode.ClientInvalidHandle, remoteHandle < this.links.Length);
                lock (this)
                {
                    for (int i = 0; i < this.links.Length; i++)
                    {
                        if (this.links[i] != null && this.links[i].Name.Equals(fields[0]))
                        {
                            link = this.links[i];
                            int index = (int)~link.RemoteHandle;
                            Fx.AssertAndThrow(ErrorCode.ClientInvalidHandle, index == i);
                            if (index != (int)remoteHandle)
                            {
                                Fx.AssertAndThrow(ErrorCode.ClientHandlInUse, this.links[(int)remoteHandle] == null);
                                this.links[(int)remoteHandle] = link;
                                this.links[i] = null;
                            }
                            break;
                        }
                    }
                }
                Fx.AssertAndThrow(ErrorCode.ClientLinkNotFound, link != null);
                link.RemoteHandle = remoteHandle;
                link.State       |= AttachReceived;
                link.OnAttach(fields);
                break;
            }

            case 0x13ul:      // flow
            {
                Fx.DebugPrint(false, channel, "flow", fields, "next-in-id", "in-window", "next-out", "out-window", "handle", "dc", "credit");
                uint nextIncomingId = (uint)fields[0];
                uint incomingWindow = (uint)fields[1];
                lock (this)
                {
                    this.outWindow = incomingWindow < uint.MaxValue ?
                                     nextIncomingId + incomingWindow - this.nextOutgoingId :
                                     uint.MaxValue;
                }

                if (fields[4] != null)
                {
                    Link link = this.links[(uint)fields[4]];
                    Fx.AssertAndThrow(ErrorCode.ClientLinkNotFound, link != null);
                    link.OnFlow(fields);
                }
                break;
            }

            case 0x14ul:      // transfer
            {
                lock (this)
                {
                    this.nextOutgoingId++;
                    if (--this.inWindow == 0)
                    {
                        this.inWindow = DefaultWindowSize;
                        List flow = new List()
                        {
                            this.nextIncomingId, this.inWindow, this.nextOutgoingId, this.outWindow
                        };
                        this.WriteFrame(0, 0, 0x13, flow);
                        Fx.DebugPrint(true, 0, "flow", flow, "next-in-id", "in-window", "next-out", "out-window", "handle", "dc", "credit");
                    }
                }

                Link link = this.links[(uint)fields[0]];
                Fx.AssertAndThrow(ErrorCode.ClientLinkNotFound, link != null);
                ((Receiver)link).OnTransfer(fields, payload);
                break;
            }

            case 0x15ul:      // disposition
            {
                Fx.DebugPrint(false, channel, "disposition", fields, "role", "first", "last");
                bool role  = (bool)fields[0];
                uint first = (uint)fields[1];
                uint last  = fields[2] == null ? first : (uint)fields[2];
                for (int i = 0; i < this.links.Length; i++)
                {
                    Link link = this.links[i];
                    if (link != null && role != link.Role)
                    {
                        link.OnDisposition(first, last, fields[4] as DescribedValue);
                    }
                }
                break;
            }

            case 0x16ul:      // detach
            {
                Fx.DebugPrint(false, channel, "detach", fields, "handle");
                Link link = this.links[(uint)fields[0]];
                Fx.AssertAndThrow(ErrorCode.ClientLinkNotFound, link != null);
                link.State |= DetachReceived;
                if ((link.State & DetachSent) == 0)
                {
                    this.CloseLink(link);
                    this.RaiseErrorEvent(link, GetError(fields, 2));
                }
                break;
            }

            case 0x17ul:      // end
                Fx.DebugPrint(false, channel, "end", null);
                this.state |= EndReceived;
                if ((this.state & EndSent) == 0)
                {
                    this.WriteFrame(0, 0, 0x17ul, new List());
                    Fx.DebugPrint(true, channel, "end", null);
                    this.ClearLinks();
                }
                break;

            case 0x18ul:      // close
                Fx.DebugPrint(false, channel, "close", null);
                this.state |= CloseReceived;
                if ((this.state & CloseSent) == 0)
                {
                    this.Close();
                    this.RaiseErrorEvent(null, GetError(fields, 0));
                }
                break;

            default:
                Fx.AssertAndThrow(ErrorCode.ClientInvalidCodeOnFrame, false);
                break;
            }
        }