public synchronized MessageData deframe(final ByteBuf buf) throws FramingException {
    if (buf == null || !buf.isReadable()) {
      return null;
    }

    if (!headerProcessed) {
      // We don't have enough bytes to read the header.
      if (buf.readableBytes() < LENGTH_FULL_HEADER) {
        return null;
      }
      frameSize = processHeader(buf.readSlice(LENGTH_FULL_HEADER));
      headerProcessed = true;
      buf.discardReadBytes();
    }

    final int size = frameSize + padding16(frameSize) + LENGTH_MAC;
    if (buf.readableBytes() < size) {
      return null;
    }

    final MessageData msg = processFrame(buf.readSlice(size), frameSize);
    buf.discardReadBytes();
    headerProcessed = false;
    return msg;
  }
Deframes a full message from the byte buffer, if possible.

<p>If the byte buffer contains insufficient bytes to extract a full message, this method
returns <code>null</code>.

<p>If the buffer contains at least a header, it offloads it and processes it, setting an
internal expectation to subsequently receive as many bytes for the frame as the header
specified. In this case, this method also returns <code>null</code> to inform the caller that
it requires more bytes before it can produce an output.

<p>This method can be called repetitively whenever new bytes appear in the buffer. It is worthy
to note that the byte buffer is not consumed unless the next expected amount of bytes appears.

<p>If there is more than one message in the byte buffer, only the first one is returned,
consuming it from the byte buffer. The caller should call this method again with the same byte
buffer to continue extracting more messages, if possible.

<p>When this method throws an exception, it is recommended that the caller scraps away the RLPx
connection, as the digests and stream ciphers could have become corrupted.

@param buf The buffer containing no messages, partial messages or multiple messages.
@return The first fully extracted message from this buffer, or <code>null</code> if no message
    could be extracted yet.
@throws FramingException Thrown when a decryption or internal error occurs.
ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/rlpx/framing/Framer.java