code: private static String readLine(ByteBuf undecodedChunk, Charset charset) {
          if (!undecodedChunk.hasArray()) {
              return readLineStandard(undecodedChunk, charset);
          }
          SeekAheadOptimize sao = new SeekAheadOptimize(undecodedChunk);
          int readerIndex = undecodedChunk.readerIndex();
          try {
              ByteBuf line = buffer(64);
  
              while (sao.pos < sao.limit) {
                  byte nextByte = sao.bytes[sao.pos++];
                  if (nextByte == HttpConstants.CR) {
                      if (sao.pos < sao.limit) {
                          nextByte = sao.bytes[sao.pos++];
                          if (nextByte == HttpConstants.LF) {
                              sao.setReadPosition(0);
                              return line.toString(charset);
                          } else {
                              // Write CR (not followed by LF)
                              sao.pos--;
                              line.writeByte(HttpConstants.CR);
                          }
                      } else {
                          line.writeByte(nextByte);
                      }
                  } else if (nextByte == HttpConstants.LF) {
                      sao.setReadPosition(0);
                      return line.toString(charset);
                  } else {
                      line.writeByte(nextByte);
                  }
              }
          } catch (IndexOutOfBoundsException e) {
              undecodedChunk.readerIndex(readerIndex);
              throw new NotEnoughDataDecoderException(e);
          }
          undecodedChunk.readerIndex(readerIndex);
          throw new NotEnoughDataDecoderException();
      }
docs: Read one line up to the CRLF or LF
  
  @return the String from one line
  @throws NotEnoughDataDecoderException
  Need more chunks and reset the {@code readerIndex} to the previous
  value