Пример #1
0
            public override void WriteObject(ByteBuffer buffer, object graph)
            {
                if (graph == null)
                {
                    Encoder.WriteObject(buffer, null);
                    return;
                }

                if (!this.WriteFormatCode(buffer))
                {
                    return;
                }

                int pos = buffer.WritePos;                  // remember the current position

                AmqpBitConverter.WriteULong(buffer, 0);     // reserve space for size and count

                int count = this.WriteMembers(buffer, graph);

                AmqpBitConverter.WriteInt(buffer.Buffer, pos, buffer.WritePos - pos - FixedWidth.UInt);
                AmqpBitConverter.WriteInt(buffer.Buffer, pos + FixedWidth.UInt, count);
            }
Пример #2
0
        public static void WriteMap(ByteBuffer buffer, Map value, bool smallEncoding)
        {
            if (value == null)
            {
                AmqpBitConverter.WriteUByte(buffer, FormatCode.Null);
            }
            else
            {
                int pos = buffer.WritePos;
                AmqpBitConverter.WriteUByte(buffer, 0);
                AmqpBitConverter.WriteUInt(buffer, 0);
                AmqpBitConverter.WriteUInt(buffer, 0);

                foreach (var key in value.Keys)
                {
                    Encoder.WriteObject(buffer, key);
                    Encoder.WriteObject(buffer, value[key]);
                }

                int size  = buffer.WritePos - pos - 9;
                int count = value.Count * 2;

                if (smallEncoding && size < byte.MaxValue && count <= byte.MaxValue)
                {
                    buffer.Buffer[pos]     = FormatCode.Map8;
                    buffer.Buffer[pos + 1] = (byte)(size + 1);
                    buffer.Buffer[pos + 2] = (byte)count;
                    Array.Copy(buffer.Buffer, pos + 9, buffer.Buffer, pos + 3, size);
                    buffer.Shrink(6);
                }
                else
                {
                    buffer.Buffer[pos] = FormatCode.Map32;
                    AmqpBitConverter.WriteInt(buffer.Buffer, pos + 1, size + 4);
                    AmqpBitConverter.WriteInt(buffer.Buffer, pos + 5, count);
                }
            }
        }
Пример #3
0
        protected override void EncodeValue(ByteBuffer buffer, bool arrayEncoding)
        {
            int pos = buffer.WriteOffset;

            // initial values for ctor, size, length
            AmqpBitConverter.WriteUByte(buffer, 0);
            AmqpBitConverter.WriteUInt(buffer, 0);
            AmqpBitConverter.WriteUInt(buffer, 0);

            var propertyCount                = GetEncodablePropertyCount(GetType());
            int lastNotNullIndex             = -1;
            int lastNotNullBufferWriteOffset = buffer.WriteOffset;

            var thisType = GetType();

            for (int i = 0; i < propertyCount; i++)
            {
                var encoderFunc  = GetEncoderDelegate(thisType, i);
                var valueWasNull = encoderFunc(this, buffer, arrayEncoding); // returns true if the value == null, false otherwise
                if (!valueWasNull || i == 0)
                {
                    lastNotNullIndex             = i;
                    lastNotNullBufferWriteOffset = buffer.WriteOffset;
                }
            }

            // rewind the buffer to just after we wrote the last not-null value
            var listLength = lastNotNullIndex + 1;

            buffer.AdjustWriteOffset(lastNotNullBufferWriteOffset);

            int size = buffer.WriteOffset - pos - 9; // recalculate list size

            // set ctor, size, length
            buffer.Buffer[pos] = FormatCode.List32;
            AmqpBitConverter.WriteInt(buffer.Buffer, pos + 1, size + 4);
            AmqpBitConverter.WriteInt(buffer.Buffer, pos + 5, listLength);
        }
Пример #4
0
        public static void EncodeFrame(ByteBuffer buffer, AmqpFrame frame, ushort channelNumber)
        {
            buffer.ValidateWrite(8);

            var frameStartOffset = buffer.WriteOffset;

            // header
            buffer.AppendWrite(FixedWidth.UInt);       // placeholder for frame size
            AmqpBitConverter.WriteUByte(buffer, 0x02); // data offset (2*4 = 8 bytes to account for header)
            AmqpBitConverter.WriteUByte(buffer, 0x00); // frame type = AMQP frame
            AmqpBitConverter.WriteUShort(buffer, channelNumber);

            // frame body, may be null/empty
            if (frame != null)
            {
                frame.Encode(buffer);
            }

            // frame size
            int frameSize = buffer.WriteOffset - frameStartOffset;

            AmqpBitConverter.WriteInt(buffer.Buffer, frameStartOffset, frameSize);
        }
Пример #5
0
        public static void FRM(Stream stream, ulong code, byte type, ushort channel, params object[] value)
        {
            List list = new List();

            if (value != null)
            {
                list.AddRange(value);
            }
            ByteBuffer buffer = new ByteBuffer(256, true);

            buffer.Append(4);
            AmqpBitConverter.WriteUByte(buffer, 2);
            AmqpBitConverter.WriteUByte(buffer, type);
            AmqpBitConverter.WriteUShort(buffer, channel);
            Encoder.WriteObject(buffer, new DescribedValue(code, list));
            if (code == 0x14UL) // transfer
            {
                byte[] bytes = new byte[] { 0x00, 0x53, 0x77, 0xa1, 0x05, 0x48, 0x65, 0x6c, 0x6c, 0x6f };
                AmqpBitConverter.WriteBytes(buffer, bytes, 0, bytes.Length);
            }

            AmqpBitConverter.WriteInt(buffer.Buffer, 0, buffer.Length);
            stream.Write(buffer.Buffer, buffer.Offset, buffer.Length);
        }
Пример #6
0
        public void TestMethod_AmqpBitConverter()
        {
            ByteBuffer buffer = new ByteBuffer(128, true);

            AmqpBitConverter.WriteByte(buffer, 0x22);
            AmqpBitConverter.WriteByte(buffer, -0x22);

            AmqpBitConverter.WriteUByte(buffer, 0x22);
            AmqpBitConverter.WriteUByte(buffer, 0xB2);

            AmqpBitConverter.WriteShort(buffer, 0x22B7);
            AmqpBitConverter.WriteShort(buffer, -0x22B7);

            AmqpBitConverter.WriteUShort(buffer, 0x22B7);
            AmqpBitConverter.WriteUShort(buffer, 0xC2B7);

            AmqpBitConverter.WriteInt(buffer, 0x340da287);
            AmqpBitConverter.WriteInt(buffer, -0x340da287);

            AmqpBitConverter.WriteUInt(buffer, 0x340da287);
            AmqpBitConverter.WriteUInt(buffer, 0xF40da287);

            AmqpBitConverter.WriteLong(buffer, 0x5d00BB9A340da287);
            AmqpBitConverter.WriteLong(buffer, -0x5d00BB9A340da287);

            AmqpBitConverter.WriteULong(buffer, 0x5d00BB9A340da287);
            AmqpBitConverter.WriteULong(buffer, 0xad00BB9A340da287);

            AmqpBitConverter.WriteFloat(buffer, 12344.4434F);
            AmqpBitConverter.WriteFloat(buffer, -12344.4434F);

            AmqpBitConverter.WriteDouble(buffer, 39432123244.44352334);
            AmqpBitConverter.WriteDouble(buffer, -39432123244.44352334);

            Guid uuid = Guid.NewGuid();

            AmqpBitConverter.WriteUuid(buffer, uuid);

            sbyte b  = AmqpBitConverter.ReadByte(buffer);
            sbyte b2 = AmqpBitConverter.ReadByte(buffer);

            byte ub  = AmqpBitConverter.ReadUByte(buffer);
            byte ub2 = AmqpBitConverter.ReadUByte(buffer);

            short s  = AmqpBitConverter.ReadShort(buffer);
            short s2 = AmqpBitConverter.ReadShort(buffer);

            ushort us  = AmqpBitConverter.ReadUShort(buffer);
            ushort us2 = AmqpBitConverter.ReadUShort(buffer);

            int i  = AmqpBitConverter.ReadInt(buffer);
            int i2 = AmqpBitConverter.ReadInt(buffer);

            uint ui  = AmqpBitConverter.ReadUInt(buffer);
            uint ui2 = AmqpBitConverter.ReadUInt(buffer);

            long l  = AmqpBitConverter.ReadLong(buffer);
            long l2 = AmqpBitConverter.ReadLong(buffer);

            ulong ul  = AmqpBitConverter.ReadULong(buffer);
            ulong ul2 = AmqpBitConverter.ReadULong(buffer);

            float f  = AmqpBitConverter.ReadFloat(buffer);
            float f2 = AmqpBitConverter.ReadFloat(buffer);

            double d  = AmqpBitConverter.ReadDouble(buffer);
            double d2 = AmqpBitConverter.ReadDouble(buffer);

            Guid uuid2 = AmqpBitConverter.ReadUuid(buffer);
        }
Пример #7
0
 public static void WriteChar(ByteBuffer buffer, char value)
 {
     AmqpBitConverter.WriteUByte(buffer, FormatCode.Char);
     AmqpBitConverter.WriteInt(buffer, value);   // TODO: utf32
 }
Пример #8
0
        internal void SendTransfer(Delivery delivery)
        {
            delivery.DeliveryId = nextOutgoingId++;

            var transfer = new Transfer()
            {
                Handle        = delivery.Link.LocalHandle,
                DeliveryId    = delivery.DeliveryId,
                DeliveryTag   = delivery.DeliveryTag,
                MessageFormat = 0,
                Settled       = delivery.Settled,
                More          = false,
            };

            if (!delivery.Settled)
            {
                outgoingUnsettledMap.Add(delivery);
            }

            while (delivery.PayloadBuffer.LengthAvailableToRead > 0)
            {
                var buffer            = new ByteBuffer((int)Connection.MaxFrameSize, false);
                var bufferStartOffset = buffer.WriteOffset;
                transfer.More = false;

                AmqpCodec.EncodeFrame(buffer, transfer, ChannelNumber); // encode to get space available for payload
                int frameSize = buffer.LengthAvailableToRead;
                int payloadBufferSpaceAvailable = (int)Connection.MaxFrameSize - frameSize;

                int payloadSize = delivery.PayloadBuffer.LengthAvailableToRead;

                // payload is too big, need to split into multiple transfers
                if (payloadSize > payloadBufferSpaceAvailable)
                {
                    transfer.More = true;
                    // payloadBufferSpaceAvailable should not change after encoding again
                    buffer.ResetReadWrite();
                    AmqpCodec.EncodeFrame(buffer, transfer, ChannelNumber); // re-encode with correct value. TODO: is there a way to estimate instead of encoding, testing, and reencoding?
                    frameSize   = buffer.LengthAvailableToRead;
                    payloadSize = payloadBufferSpaceAvailable;              // max size
                }

                // copy payload to buffer to write
                AmqpBitConverter.WriteBytes(buffer, delivery.PayloadBuffer.Buffer, delivery.PayloadBuffer.ReadOffset, payloadSize);
                delivery.PayloadBuffer.CompleteRead(payloadSize);

                // rewrite frame size
                AmqpBitConverter.WriteInt(buffer.Buffer, bufferStartOffset, frameSize + payloadSize);

                if (Trace.IsDebugEnabled)
                {
                    trace.Debug("SEND CH({0}) {1} Payload {2} Bytes", ChannelNumber.ToString(), transfer.ToString(), payloadSize.ToString());
                }
                Connection.SendBuffer(buffer);

                // following fields may be null on subsequent transfers
                transfer.DeliveryId    = null;
                transfer.DeliveryTag   = null;
                transfer.MessageFormat = null;
                transfer.Settled       = null;
            }
        }