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); }
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); } } }
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); }
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); }
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); }
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); }
public static void WriteChar(ByteBuffer buffer, char value) { AmqpBitConverter.WriteUByte(buffer, FormatCode.Char); AmqpBitConverter.WriteInt(buffer, value); // TODO: utf32 }
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; } }