protected final @Nullable CharSequence readChars(@NotNull ByteBuf input) {
    int readableBytes = input.readableBytes();
    if (readableBytes == 0) {
      input.release();
      return null;
    }

    int required = contentLength - consumedContentByteCount;
    if (readableBytes < required) {
      if (chunkedContent == null) {
        chunkedContent = CharBuffer.allocate(contentLength);
      }

      BufferToCharsKt.readIntoCharBuffer(input, readableBytes, chunkedContent);
      consumedContentByteCount += readableBytes;
      input.release();
      return null;
    }
    else {
      CharBuffer charBuffer = chunkedContent;
      CharSequence result;
      if (charBuffer != null) {
        chunkedContent = null;
        consumedContentByteCount = 0;
        BufferToCharsKt.readIntoCharBuffer(input, required, charBuffer);
        result = new CharSequenceBackedByChars(charBuffer);
      }
      else {
        result = input.toString(input.readerIndex(), required, StandardCharsets.UTF_8);
      }

      input.readerIndex(input.readerIndex() + required);
      return result;
    }
  }
protected final @Nullable CharSequence readChars(@NotNull ByteBuf input)