public static ByteBuffer Encode(FrameType type, ushort channel, Transfer transfer, ByteBuffer payload, int maxFrameSize, out int payloadSize) { int bufferSize = cmdBufferSize + payload.Length; if (bufferSize > maxFrameSize) { bufferSize = maxFrameSize; } bool more = false; // estimate it first if (payload.Length > bufferSize - 32) { transfer.More = more = true; } ByteBuffer buffer = new ByteBuffer(bufferSize, false); EncodeFrame(buffer, type, channel, transfer); if (more && payload.Length <= buffer.Size) { // guessed it wrong. correct it transfer.More = false; buffer.Reset(); EncodeFrame(buffer, type, channel, transfer); } payloadSize = Math.Min(payload.Length, buffer.Size); AmqpBitConverter.WriteBytes(buffer, payload.Buffer, payload.Offset, payloadSize); payload.Complete(payloadSize); AmqpBitConverter.WriteInt(buffer.Buffer, 0, buffer.Length); return(buffer); }
public void ExtractFrameBuffers(ByteBuffer buffer, SerializedWorker <ByteBuffer> bufferHandler) { if (this.currentFrameBuffer != null) { int num = Math.Min(this.currentFrameBuffer.Size, buffer.Length); AmqpBitConverter.WriteBytes(this.currentFrameBuffer, buffer.Buffer, buffer.Offset, num); buffer.Complete(num); if (this.currentFrameBuffer.Size == 0) { ByteBuffer byteBuffer = this.currentFrameBuffer; this.currentFrameBuffer = null; bufferHandler.DoWork(byteBuffer); } } while (buffer.Length >= AmqpCodec.MinimumFrameDecodeSize) { int frameSize = AmqpCodec.GetFrameSize(buffer); if (frameSize < AmqpCodec.MinimumFrameDecodeSize || frameSize > this.maxFrameSize) { throw new AmqpException(AmqpError.FramingError, SRClient.InvalidFrameSize(frameSize, this.maxFrameSize)); } int num1 = Math.Min(frameSize, buffer.Length); this.currentFrameBuffer = new ByteBuffer(frameSize, false); AmqpBitConverter.WriteBytes(this.currentFrameBuffer, buffer.Buffer, buffer.Offset, num1); buffer.Complete(num1); if (frameSize != num1) { break; } ByteBuffer byteBuffer1 = this.currentFrameBuffer; this.currentFrameBuffer = null; bufferHandler.DoWork(byteBuffer1); } }
internal override void OnTransfer(Delivery delivery, Transfer transfer, ByteBuffer buffer) { if (delivery != null) { this.deliveryCount++; if (!transfer.More) { // single transfer message - the most common case delivery.Buffer = buffer; this.DeliverMessage(delivery); } else { delivery.Buffer = new ByteBuffer(buffer.Length * 2, true); AmqpBitConverter.WriteBytes(delivery.Buffer, buffer.Buffer, buffer.Offset, buffer.Length); this.deliveryCurrent = delivery; } } else { delivery = this.deliveryCurrent; if (!transfer.More) { AmqpBitConverter.WriteBytes(delivery.Buffer, buffer.Buffer, buffer.Offset, buffer.Length); this.deliveryCurrent = null; this.DeliverMessage(delivery); } else { AmqpBitConverter.WriteBytes(delivery.Buffer, buffer.Buffer, buffer.Offset, buffer.Length); } } }
public static void Encode(ByteBuffer buffer, ushort channel, Transfer transfer, ByteBuffer payload) { Encode(buffer, FrameType.Amqp, channel, transfer); int payloadSize = payload.Length; int frameSize = buffer.Length + payloadSize; AmqpBitConverter.WriteInt(buffer.Buffer, buffer.Offset, frameSize); AmqpBitConverter.WriteBytes(buffer, payload.Buffer, payload.Offset, payload.Length); payload.Complete(payload.Length); }
static void WriteSection(ByteBuffer buffer, AmqpDescribed section, ByteBuffer source) { if (section != null) { if (source != null) { AmqpBitConverter.WriteBytes(buffer, source.Buffer, section.Offset, section.Length); } else { AmqpMessage.EncodeSection(buffer, section); } } }
internal override void EncodeValue(ByteBuffer buffer) { var byteBuffer = this.value as ByteBuffer; if (byteBuffer != null) { Encoder.WriteBinaryBuffer(buffer, byteBuffer); } else if (this.valueBuffer != null && !this.valueDecoded) { AmqpBitConverter.WriteBytes(buffer, this.valueBuffer.Buffer, this.valueBuffer.Offset, this.valueBuffer.Length); } else { this.WriteValue(buffer, this.value); } }
public static void WriteBinary(ByteBuffer buffer, byte[] value, bool smallEncoding) { if (value == null) { AmqpBitConverter.WriteUByte(buffer, FormatCode.Null); } else if (smallEncoding && value.Length <= byte.MaxValue) { AmqpBitConverter.WriteUByte(buffer, FormatCode.Binary8); AmqpBitConverter.WriteUByte(buffer, (byte)value.Length); AmqpBitConverter.WriteBytes(buffer, value, 0, value.Length); } else { AmqpBitConverter.WriteUByte(buffer, FormatCode.Binary32); AmqpBitConverter.WriteUInt(buffer, (uint)value.Length); AmqpBitConverter.WriteBytes(buffer, value, 0, value.Length); } }
public void ExtractFrameBuffers(ByteBuffer buffer, SerializedWorker <ByteBuffer> bufferHandler) { if (this.currentFrameBuffer != null) { int sizeToWrite = Math.Min(this.currentFrameBuffer.Size, buffer.Length); AmqpBitConverter.WriteBytes(this.currentFrameBuffer, buffer.Buffer, buffer.Offset, sizeToWrite); buffer.Complete(sizeToWrite); if (this.currentFrameBuffer.Size == 0) { ByteBuffer frameBuffer = this.currentFrameBuffer; this.currentFrameBuffer = null; bufferHandler.DoWork(frameBuffer); } } while (buffer.Length >= AmqpCodec.MinimumFrameDecodeSize) { int frameSize = AmqpCodec.GetFrameSize(buffer); if (frameSize < AmqpCodec.MinimumFrameDecodeSize || frameSize > this.maxFrameSize) { throw new AmqpException(AmqpErrorCode.FramingError, CommonResources.GetString(CommonResources.InvalidFrameSize, frameSize, this.maxFrameSize)); } int sizeToWrite = Math.Min(frameSize, buffer.Length); this.currentFrameBuffer = new ByteBuffer(frameSize, false); AmqpBitConverter.WriteBytes(this.currentFrameBuffer, buffer.Buffer, buffer.Offset, sizeToWrite); buffer.Complete(sizeToWrite); if (frameSize == sizeToWrite) { ByteBuffer frameBuffer = this.currentFrameBuffer; this.currentFrameBuffer = null; bufferHandler.DoWork(frameBuffer); } else { break; } } }
void CheckModified(ByteBuffer oldBuf) { if (this.failedCount == 0 && this.MessageAnnotations == null) { return; } ByteBuffer newBuf = new ByteBuffer(oldBuf.Size, true); Header header = new Header(); MessageAnnotations annotations = this.MessageAnnotations; int offset = oldBuf.Offset; while (oldBuf.Length > 0) { offset = oldBuf.Offset; var described = (RestrictedDescribed)Encoder.ReadDescribed(oldBuf, Encoder.ReadFormatCode(buffer)); if (described.Descriptor.Code == 0x70UL) { header = (Header)described; this.WriteHeader(ref header, newBuf); } else if (described.Descriptor.Code == 0x71UL) { this.WriteHeader(ref header, newBuf); AmqpBitConverter.WriteBytes(newBuf, oldBuf.Buffer, offset, oldBuf.Offset - offset); } else if (described.Descriptor.Code == 0x72UL) { this.WriteHeader(ref header, newBuf); this.WriteMessageAnnotations(ref annotations, (MessageAnnotations)described, newBuf); } else { this.WriteHeader(ref header, newBuf); this.WriteMessageAnnotations(ref annotations, null, newBuf); AmqpBitConverter.WriteBytes(newBuf, oldBuf.Buffer, offset, oldBuf.WritePos - offset); break; } } this.buffer = newBuf; this.messageOffset = 0; }
internal static ByteBuffer AddPayload(ByteBuffer dest, ByteBuffer payload, bool isLast) { if (dest == null && isLast) { // this should be the most common case: 1 transfer dest = payload.AddReference(); } else { // multi-transfer message: merge into one buffer // the individual transfer buffers are disposed if (dest == null) { dest = new ByteBuffer(payload.Length * 2, true); } AmqpBitConverter.WriteBytes(dest, payload.Buffer, payload.Offset, payload.Length); } return(dest); }
static void TryWrite(ByteBuffer buffer, int newData, bool fail, AmqpSymbol error) { try { AmqpBitConverter.WriteBytes(buffer, new byte[newData], 0, newData); if (fail) { Assert.True(false, "write should fail because buffer is smaller"); } } catch (AmqpException exp) { if (fail) { Assert.Equal(AmqpErrorCode.DecodeError, exp.Error.Condition); } else { throw; } } }
protected override void Initialize(SectionFlag desiredSections, bool force = false) { if (this.buffer != null && !force) { return; } int size = this.source == null ? 1024 : this.source.Length; ByteBuffer buffer = new ByteBuffer(size, true); AmqpMessage.EncodeSection(buffer, this.header); AmqpMessage.EncodeSection(buffer, this.deliveryAnnotations); AmqpMessage.EncodeSection(buffer, this.messageAnnotations); if (this.deepCopy) { AmqpMessage.EncodeSection(buffer, this.properties); AmqpMessage.EncodeSection(buffer, this.applicationProperties); } else { WriteSection(buffer, this.properties, this.source); WriteSection(buffer, this.applicationProperties, this.source); } if (this.source != null && this.bodyOffset >= 0) { AmqpBitConverter.WriteBytes(buffer, this.source.Buffer, this.bodyOffset, this.bodyLength); } else { this.EncodeBody(buffer); } AmqpMessage.EncodeSection(buffer, this.footer); this.buffer?.Dispose(); this.buffer = buffer; this.messageSize = buffer.Length; }
internal override void OnTransfer(Delivery delivery, Transfer transfer, ByteBuffer buffer) { if (delivery != null) { buffer.AddReference(); delivery.Buffer = buffer; this.deliveryCount++; } else { delivery = this.deliveryCurrent; AmqpBitConverter.WriteBytes(delivery.Buffer, buffer.Buffer, buffer.Offset, buffer.Length); } if (!transfer.More) { this.DeliverMessage(delivery); } else { this.deliveryCurrent = delivery; } }
public static void WriteSymbol(ByteBuffer buffer, Symbol value, bool smallEncoding) { if (value == null) { AmqpBitConverter.WriteUByte(buffer, FormatCode.Null); } else { byte[] data = Encoding.UTF8.GetBytes(value); if (smallEncoding && data.Length <= byte.MaxValue) { AmqpBitConverter.WriteUByte(buffer, FormatCode.Symbol8); AmqpBitConverter.WriteUByte(buffer, (byte)data.Length); AmqpBitConverter.WriteBytes(buffer, data, 0, data.Length); } else { AmqpBitConverter.WriteUByte(buffer, FormatCode.Symbol32); AmqpBitConverter.WriteUInt(buffer, (uint)data.Length); AmqpBitConverter.WriteBytes(buffer, data, 0, data.Length); } } }
public static void Encode(AnnotatedMessage message, ByteBuffer buffer) { if (message.Header != null) { message.Header.Encode(buffer); } if (message.DeliveryAnnotations != null) { message.DeliveryAnnotations.Encode(buffer); } if (message.MessageAnnotations != null) { message.MessageAnnotations.Encode(buffer); } if (message.BareMessage != null && message.BareMessage.Length > 0) { AmqpBitConverter.WriteBytes(buffer, message.BareMessage, 0, message.BareMessage.Length); } if (message.Footer != null) { message.Footer.Encode(buffer); } }
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); }
private void HandleTransferFrame(Transfer transfer, ByteBuffer buffer) { if (State != LinkStateEnum.ATTACHED) { throw new AmqpException(ErrorCode.IllegalState, $"Received Transfer frame but link state is {State.ToString()}."); } if (LinkCredit <= 0) { throw new AmqpException(ErrorCode.TransferLimitExceeded, "The link credit has dropped to 0. Wait for messages to finishing processing."); } if (!IsReceiverLink) { throw new AmqpException(ErrorCode.NotAllowed, "A Sender Link cannot receive Transfers."); } Delivery delivery; if (continuationDelivery == null) { // new transfer delivery = new Delivery(); delivery.Link = this; delivery.DeliveryId = transfer.DeliveryId.Value; delivery.DeliveryTag = transfer.DeliveryTag; delivery.Settled = transfer.Settled.IsTrue(); delivery.State = transfer.State; delivery.PayloadBuffer = new ByteBuffer(buffer.LengthAvailableToRead, true); delivery.ReceiverSettlementMode = receiverSettlementMode; if (transfer.ReceiverSettlementMode.HasValue) { delivery.ReceiverSettlementMode = (LinkReceiverSettlementModeEnum)transfer.ReceiverSettlementMode.Value; if (receiverSettlementMode == LinkReceiverSettlementModeEnum.First && delivery.ReceiverSettlementMode == LinkReceiverSettlementModeEnum.Second) { throw new AmqpException(ErrorCode.InvalidField, "rcv-settle-mode: If the negotiated link value is first, then it is illegal to set this field to second."); } } } else { // continuation if (transfer.DeliveryId.HasValue && transfer.DeliveryId.Value != continuationDelivery.DeliveryId) { throw new AmqpException(ErrorCode.NotAllowed, "Expecting Continuation Transfer but got a new Transfer."); } if (transfer.DeliveryTag != null && !transfer.DeliveryTag.SequenceEqual(continuationDelivery.DeliveryTag)) { throw new AmqpException(ErrorCode.NotAllowed, "Expecting Continuation Transfer but got a new Transfer."); } delivery = continuationDelivery; } if (transfer.Aborted.IsTrue()) { continuationDelivery = null; return; // ignore message } // copy and append the buffer (message payload) to the cached PayloadBuffer AmqpBitConverter.WriteBytes(delivery.PayloadBuffer, buffer.Buffer, buffer.ReadOffset, buffer.LengthAvailableToRead); if (transfer.More.IsTrue()) { continuationDelivery = delivery; return; // expecting more payload } // assume transferred complete payload at this point continuationDelivery = null; if (!delivery.Settled) { Session.NotifyUnsettledIncomingDelivery(this, delivery); } LinkCredit--; DeliveryCount++; Session.Connection.Container.OnDelivery(this, delivery); }
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; } }