Transparently decodes a single frame.
A call to any of the Read methods of this stream removes data from ReadBuffer object passed to the constructor. The data is then decoded and the decoded form is then returned.
Inheritance: BufferStream
        private async Task <int> ReadFromCurrentPacketAsync(
            byte[] buffer, int offset, int count, CancellationToken cancellationToken)
        {
            int read;

            while (((read = await this.deframedBuffer.ReadAsync(buffer, offset, count, cancellationToken)) == 0) &&
                   (count > 0) && (this.message != null) && this.message.CanHavePayload &&
                   this.message.CanHaveMultiplePackets && ((this.message.PacketFlags & PacketFlags.LastPacket) == 0))
            {
                this.deframingStream.Dispose();
                this.deframingStream = new DeframingStream(this.rawBuffer, this.outOfFrameByteReceived);
                this.ValidateMessage(await S101Message.ReadFromAsync(this.deframedBuffer, cancellationToken));
            }

            return(read);
        }
        private MessageDecodingStream(ReadBuffer rawBuffer, byte[] discardBuffer, Action <byte> outOfFrameByteReceived)
        {
            this.rawBuffer              = rawBuffer;
            this.discardBuffer          = discardBuffer;
            this.outOfFrameByteReceived = outOfFrameByteReceived;

            // This buffer is kept small in size, because a new one is allocated for each message.
            // This has the effect that only the bytes of reads <= MessageHeaderMaxLength bytes are actually copied into
            // this buffer. Larger reads are automatically done by calling this.ReadDeframed (without copying the bytes
            // into the MessageHeaderMaxLength byte buffer first). The former happens when packet headers are read
            // (multiple small-sized reads), the latter happens when the payload is read (typically done with a buffer
            // >= 1024 bytes).
            // This approach minimizes the allocations per message, while guaranteeing the best possible performance for
            // header *and* payload reading.
            this.deframedBuffer  = new ReadBuffer(this.ReadDeframedAsync, Constants.MessageHeaderMaxLength);
            this.deframingStream = new DeframingStream(this.rawBuffer, this.outOfFrameByteReceived);
        }
        private MessageDecodingStream(ReadBuffer rawBuffer, byte[] discardBuffer, Action<byte> outOfFrameByteReceived)
        {
            this.rawBuffer = rawBuffer;
            this.discardBuffer = discardBuffer;
            this.outOfFrameByteReceived = outOfFrameByteReceived;

            // This buffer is kept small in size, because a new one is allocated for each message.
            // This has the effect that only the bytes of reads <= MessageHeaderMaxLength bytes are actually copied into
            // this buffer. Larger reads are automatically done by calling this.ReadDeframed (without copying the bytes
            // into the MessageHeaderMaxLength byte buffer first). The former happens when packet headers are read
            // (multiple small-sized reads), the latter happens when the payload is read (typically done with a buffer
            // >= 1024 bytes).
            // This approach minimizes the allocations per message, while guaranteeing the best possible performance for
            // header *and* payload reading.
            this.deframedBuffer = new ReadBuffer(this.ReadDeframedAsync, Constants.MessageHeaderMaxLength);
            this.deframingStream = new DeframingStream(this.rawBuffer, this.outOfFrameByteReceived);
        }
        private async Task<int> ReadFromCurrentPacketAsync(
            byte[] buffer, int offset, int count, CancellationToken cancellationToken)
        {
            int read;

            while (((read = await this.deframedBuffer.ReadAsync(buffer, offset, count, cancellationToken)) == 0) &&
                (count > 0) && (this.message != null) && this.message.CanHavePayload &&
                this.message.CanHaveMultiplePackets && ((this.message.PacketFlags & PacketFlags.LastPacket) == 0))
            {
                this.deframingStream.Dispose();
                this.deframingStream = new DeframingStream(this.rawBuffer, this.outOfFrameByteReceived);
                this.ValidateMessage(await S101Message.ReadFromAsync(this.deframedBuffer, cancellationToken));
            }

            return read;
        }