protected override void Encode(IChannelHandlerContext context, IByteBuffer input, IByteBuffer output) { while (input.IsReadable()) { if (input.ReadableBytes % Frame.BlockSize != 0) { throw new CorruptedFrameException($"Frame prepared for sending was in incorrect format: length was {input.ReadableBytes}"); } FrameHeaderReader.FrameInfo frame = _headerReader.ReadFrameHeader(input); // 0 if the buffer has enough writable bytes, and its capacity is unchanged. // 1 if the buffer does not have enough bytes, and its capacity is unchanged. // 2 if the buffer has enough writable bytes, and its capacity has been increased. // 3 if the buffer does not have enough bytes, but its capacity has been increased to its maximum. int code = output.EnsureWritable(Frame.HeaderSize + Frame.MacSize + frame.PayloadSize + Frame.MacSize, true); WriteHeader(output); WriteHeaderMac(output); for (int i = 0; i < frame.PayloadSize / Frame.BlockSize; i++) { WritePayloadBlock(input, output); } WritePayloadMac(output); } }
protected override void Decode(IChannelHandlerContext context, IByteBuffer input, List <object> output) { // Note that each input is a full frame header16|payload that are automatically released by the base class. // If the input is not a full and valid frame we can throw as this is an unexpected behaviour from the // decoder up the pipeline. // Moreover we will never receive more than a full packet in a single input so the input buffer // is expected to have no readable bytes after the merging operation. if (_logger.IsTrace) { _logger.Trace("Merging frames"); } if (input.ReferenceCount != 1) { throw new IllegalReferenceCountException(input.ReferenceCount); } FrameHeaderReader.FrameInfo frame = _headerReader.ReadFrameHeader(input); if (frame.IsFirst) { ReadFirstChunk(context, input, frame); } else { ReadChunk(input, frame); } if (!_zeroPacket.Content.IsWritable()) { input.SkipBytes(frame.Padding); output.Add(_zeroPacket); _zeroPacket = null; if (input.IsReadable()) { throw new CorruptedFrameException($"{nameof(ZeroFrameMerger)} received a corrupted frame - {input.ReadableBytes} longer than expected"); } } }
private void ReadFirstChunk(IChannelHandlerContext context, IByteBuffer input, FrameHeaderReader.FrameInfo frame) { byte packetTypeRlp = input.ReadByte(); IByteBuffer content; if (frame.IsChunked) { content = context.Allocator.Buffer(frame.TotalPacketSize - 1); } else { content = input.ReadSlice(frame.Size - 1); // Since we will call release in the next handler and we use a derived buffer here // we need to call Retain to prevent the buffer from being released twice // (once in the next handler and once in the base class). content.Retain(); } _zeroPacket = new ZeroPacket(content); _zeroPacket.PacketType = GetPacketType(packetTypeRlp); // If not chunked then we already used a slice of the input, // otherwise we need to read into the freshly allocated buffer. if (frame.IsChunked) { input.ReadBytes(_zeroPacket.Content, frame.Size - 1); // do not call Release since the input buffer is managed by } }
private void ReadChunk(IByteBuffer input, FrameHeaderReader.FrameInfo frame) { input.ReadBytes(_zeroPacket.Content, frame.Size); }