public async Task PumpAsync(uint maxFrameSize, Func <ProtocolHeader, bool> onHeader, Func <ByteBuffer, bool> onBuffer)
{
byte[] header = new byte[FixedWidth.ULong];
if (onHeader != null)
{
// header
await this.ReceiveBufferAsync(header, 0, FixedWidth.ULong).ConfigureAwait(false);
Trace.WriteBuffer("RECV {0}", header, 0, header.Length);
if (!onHeader(ProtocolHeader.Create(header, 0)))
{
return;
}
}
// frames
while (true)
{
await this.ReceiveBufferAsync(header, 0, FixedWidth.UInt).ConfigureAwait(false);
int frameSize = AmqpBitConverter.ReadInt(header, 0);
if ((uint)frameSize > maxFrameSize)
{
throw new AmqpException(ErrorCode.InvalidField,
Fx.Format(SRAmqp.InvalidFrameSize, frameSize, maxFrameSize));
}
ByteBuffer buffer = this.bufferManager.GetByteBuffer(frameSize);
try
{
Buffer.BlockCopy(header, 0, buffer.Buffer, buffer.Offset, FixedWidth.UInt);
await this.ReceiveBufferAsync(buffer.Buffer, buffer.Offset + FixedWidth.UInt, frameSize - FixedWidth.UInt).ConfigureAwait(false);
buffer.Append(frameSize);
Trace.WriteBuffer("RECV {0}", buffer.Buffer, buffer.Offset, buffer.Length);
if (!onBuffer(buffer))
{
break;
}
}
finally
{
buffer.ReleaseReference();
}
}
}