Parse until next Event.

@param buffer the buffer to parse
@return True if an {@link RequestHandler} method was called and it returned true;
974578
public boolean parseNext(ByteBuffer buffer) {
        if (DEBUG)
            LOG.debug("parseNext s={} {}", _state, BufferUtils.toDetailString(buffer));
        try {
            // Start a request/response
            if (_state == State.START) {
                _version = null;
                _method = null;
                _methodString = null;
                _endOfContent = EndOfContent.UNKNOWN_CONTENT;
                _header = null;
                if (quickStart(buffer))
                    return true;
            }

            // Request/response line
            if (_state.ordinal() >= State.START.ordinal() && _state.ordinal() < State.HEADER.ordinal()) {
                if (parseLine(buffer))
                    return true;
            }

            // parse headers
            if (_state == State.HEADER) {
                if (parseFields(buffer))
                    return true;
            }

            // parse content
            if (_state.ordinal() >= State.CONTENT.ordinal() && _state.ordinal() < State.TRAILER.ordinal()) {
                // Handle HEAD response
                if (_responseStatus > 0 && _headResponse) {
                    setState(State.END);
                    return handleContentMessage();
                } else {
                    if (parseContent(buffer))
                        return true;
                }
            }

            // parse headers
            if (_state == State.TRAILER) {
                if (parseFields(buffer))
                    return true;
            }

            // handle end states
            if (_state == State.END) {
                // eat white space
                while (buffer.remaining() > 0 && buffer.get(buffer.position()) <= HttpTokens.SPACE)
                    buffer.get();
            } else if (isClose() || isClosed()) {
                BufferUtils.clear(buffer);
            }

            // Handle EOF
            if (_eof && !buffer.hasRemaining()) {
                switch (_state) {
                    case CLOSED:
                        break;

                    case START:
                        setState(State.CLOSED);
                        _handler.earlyEOF();
                        break;

                    case END:
                    case CLOSE:
                        setState(State.CLOSED);
                        break;

                    case EOF_CONTENT:
                    case TRAILER:
                        if (_fieldState == FieldState.FIELD) {
                            // Be forgiving of missing last CRLF
                            setState(State.CLOSED);
                            return handleContentMessage();
                        }
                        setState(State.CLOSED);
                        _handler.earlyEOF();
                        break;

                    case CONTENT:
                    case CHUNKED_CONTENT:
                    case CHUNK_SIZE:
                    case CHUNK_PARAMS:
                    case CHUNK:
                        setState(State.CLOSED);
                        _handler.earlyEOF();
                        break;

                    default:
                        if (DEBUG)
                            LOG.debug("{} EOF in {}", this, _state);
                        setState(State.CLOSED);
                        _handler.badMessage(new BadMessageException(HttpStatus.BAD_REQUEST_400));
                        break;
                }
            }
        } catch (BadMessageException x) {
            BufferUtils.clear(buffer);
            badMessage(x);
        } catch (Throwable x) {
            BufferUtils.clear(buffer);
            badMessage(new BadMessageException(HttpStatus.BAD_REQUEST_400, _requestHandler != null ? "Bad Request" : "Bad Response", x));
        }
        return false;
    }
28544
void parseDocument(
            final Reader reader, final int suggestedBufferSize,
            final IMarkupHandler handler, final ParseStatus status)
            throws ParseException {


        final long parsingStartTimeNanos = System.nanoTime();

        char[] buffer = null;

        try {

            handler.handleDocumentStart(parsingStartTimeNanos, 1, 1);

            int bufferSize = suggestedBufferSize;
            buffer = this.pool.allocateBuffer(bufferSize);

            int bufferContentSize = reader.read(buffer);

            boolean cont = (bufferContentSize != -1);

            status.offset = -1;
            status.line = 1;
            status.col = 1;
            status.inStructure = false;
            status.parsingDisabled = true;
            status.parsingDisabledLimitSequence = null;
            status.autoCloseRequired = null;
            status.autoCloseLimits = null;

            while (cont) {

                parseBuffer(buffer, 0, bufferContentSize, handler, status);

                int readOffset = 0;
                int readLen = bufferSize;

                if (status.offset == 0) {

                    if (bufferContentSize == bufferSize) {
                        // Buffer is not big enough, double it!

                        char[] newBuffer = null;
                        try {

                            bufferSize *= 2;

                            newBuffer = this.pool.allocateBuffer(bufferSize);
                            System.arraycopy(buffer, 0, newBuffer, 0, bufferContentSize);

                            this.pool.releaseBuffer(buffer);

                            buffer = newBuffer;

                        } catch (final Exception ignored) {
                            this.pool.releaseBuffer(newBuffer);
                        }

                    }

                    // it's possible for two reads to occur in a row and 1) read less than the bufferSize and 2)
                    // still not find the next tag/end of structure
                    readOffset = bufferContentSize;
                    readLen = bufferSize - readOffset;

                } else if (status.offset < bufferContentSize) {

                    System.arraycopy(buffer, status.offset, buffer, 0, bufferContentSize - status.offset);

                    readOffset = bufferContentSize - status.offset;
                    readLen = bufferSize - readOffset;

                    status.offset = 0;
                    bufferContentSize = readOffset;

                }

                final int read = reader.read(buffer, readOffset, readLen);
                if (read != -1) {
                    bufferContentSize = readOffset + read;
                } else {
                    cont = false;
                }

            }

            // Iteration done, now it's time to clean up in case we still have some text to be notified

            int lastLine = status.line;
            int lastCol = status.col;

            final int lastStart = status.offset;
            final int lastLen = bufferContentSize - lastStart;

            if (lastLen > 0) {

                if (status.inStructure) {
                    throw new ParseException(
                            "Incomplete structure: \"" + new String(buffer, lastStart, lastLen) + "\"", status.line, status.col);
                }

                handler.handleText(buffer, lastStart, lastLen, status.line, status.col);

                // As we have produced an additional text event, we need to fast-forward the
                // lastLine and lastCol position to include the last text structure.
                for (int i = lastStart; i < (lastStart + lastLen); i++) {
                    final char c = buffer[i];
                    if (c == '\n') {
                        lastLine++;
                        lastCol = 1;
                    } else {
                        lastCol++;
                    }

                }

            }

            final long parsingEndTimeNanos = System.nanoTime();
            handler.handleDocumentEnd(parsingEndTimeNanos, (parsingEndTimeNanos - parsingStartTimeNanos), lastLine, lastCol);

        } catch (final ParseException e) {
            throw e;
        } catch (final Exception e) {
            throw new ParseException(e);
        } finally {
            this.pool.releaseBuffer(buffer);
            try {
                reader.close();
            } catch (final Throwable ignored) {
                // This exception can be safely ignored
            }
        }

    }
446947
public void setBuffer(final String buffer) {
        initRandomBuffer();
        byteBufferAry = Arrays.copyOf(buffer.getBytes(), MAX_PACKETBUFFER_LENGTH);
    }
1177585
public boolean parse(Context context, ProcPatternElement terminator) {
        if (isNextIn(context)) {
            if(!ghost) {
                context.getSource().incOffset(valueLength);
            }
            return true;
        } else {
            return false;
        }
    }
1126975
@SuppressWarnings("PMD.AvoidInstantiatingObjectsInLoops")
    private static Request parse(final InputStream input) throws IOException {
        boolean eof = true;
        final Collection<String> head = new LinkedList<>();
        final ByteArrayOutputStream baos = new ByteArrayOutputStream();
        Opt<Integer> data = new Opt.Empty<>();
        data = RqLive.data(input, data, false);
        while (data.get() > 0) {
            eof = false;
            if (data.get() == '\r') {
                RqLive.checkLineFeed(input, baos, head.size() + 1);
                if (baos.size() == 0) {
                    break;
                }
                data = new Opt.Single<>(input.read());
                final Opt<String> header = RqLive.newHeader(data, baos);
                if (header.has()) {
                    head.add(header.get());
                }
                data = RqLive.data(input, data, false);
                continue;
            }
            baos.write(RqLive.legalCharacter(data, baos, head.size() + 1));
            data = RqLive.data(input, new Opt.Empty<>(), true);
        }
        if (eof) {
            throw new IOException("empty request");
        }
        return new Request() {
            @Override
            public Iterable<String> head() {
                return head;
            }

            @Override
            public InputStream body() {
                return input;
            }
        };
    }
743729
protected void clientMessageHandler(DirectBuffer buffer, int offset, int length, Header header) {
        /**
         *  All incoming messages here are supposed to be "just messages", only unicast communication
         *  All of them should implement MeaningfulMessage interface
         */
        // TODO: to be implemented
        //  log.info("clientMessageHandler message request incoming");

        byte[] data = new byte[length];
        buffer.getBytes(offset, data);

        MeaningfulMessage message = (MeaningfulMessage) VoidMessage.fromBytes(data);
        completed.put(message.getTaskId(), message);
    }
750882
protected void processRequest() {
        final int timeout = getHTTPContext().getReadTimeout();
        final TCPReadCompletedCallback callback = HttpICLReadCallback.getRef();

        // keep looping on processing information until we fully parse the message
        // and hand it off, or until the reads for more data go async
        VirtualConnection rc = null;
        do {
            if (handleNewInformation()) {
                // new information triggered an error message, so we're done
                return;
            }
            // Note: handleNewInformation will allocate the read buffers
            if (!isPartiallyParsed()) {
                // we're done parsing at this point. Note: cannot take any action
                // with information after this call because it may go all the way
                // from the channel above us back to the persist read, must exit
                // this callstack immediately
                handleNewRequest();
                return;
            }
            rc = this.myTSC.getReadInterface().read(1, callback, false, timeout);
        } while (null != rc);
    }
968758
protected final boolean parseRequestLine(ByteBuffer in) throws InvalidState, BadMessage {
        lineLoop: while(true) {
            char ch;
            switch (lineState) {
                case START:
                    lineState = LineState.METHOD;
                    resetLimit(maxRequestLineSize);

                case METHOD:
                    for(ch = next(in, false); HttpTokens.A <= ch && ch <= HttpTokens.Z; ch = next(in, false)) {
                        putChar(ch);
                    }

                    if (ch == HttpTokens.EMPTY_BUFF) return false;

                    method = getString();
                    clearBuffer();


                    if (!HttpTokens.isWhiteSpace(ch)) {
                        String badmethod = method + (char)ch;
                        shutdownParser();
                        throw new BadMessage("Invalid request method: '" + badmethod + "'");
                    }

                   lineState = LineState.SPACE1;

                case SPACE1:
                    // Eat whitespace
                    for(ch = next(in, false); ch == HttpTokens.SPACE || ch == HttpTokens.TAB; ch = next(in, false));

                    if (ch == HttpTokens.EMPTY_BUFF) return false;

                    putChar(ch);
                    lineState = LineState.PATH;

                case PATH:
                    for(ch = next(in, false); ch != HttpTokens.SPACE && ch != HttpTokens.TAB; ch = next(in, false)) {
                        if (ch == HttpTokens.EMPTY_BUFF) return false;
                        putChar(ch);
                    }

                    path = getString();
                    clearBuffer();

                    lineState = LineState.SPACE2;

                case SPACE2:
                    // Eat whitespace
                    for(ch = next(in, false); ch == HttpTokens.SPACE || ch == HttpTokens.TAB; ch = next(in, false));

                    if (ch == HttpTokens.EMPTY_BUFF) return false;

                    if (ch != 'H') {
                        shutdownParser();
                        throw new BadMessage("Http version started with illegal character: " + ch);
                    }

                    putChar(ch);
                    lineState = LineState.VERSION;

                case VERSION:
                    for(ch = next(in, false); ch != HttpTokens.LF; ch = next(in, false)) {
                        if (ch == HttpTokens.EMPTY_BUFF) return false;
                        putChar(ch);
                    }

                    int majorVersion;
                    int minorVersion;
                    String scheme;

                    if (arrayMatches(HTTP11Bytes)) {
                        majorVersion = 1;
                        minorVersion = 1;
                        scheme = "http";
                    } else if (arrayMatches(HTTPS11Bytes)) {
                        majorVersion = 1;
                        minorVersion = 1;
                        scheme = "https";
                    } else if (arrayMatches(HTTP10Bytes)) {
                        majorVersion = 1;
                        minorVersion = 0;
                        scheme = "http";
                    } else if (arrayMatches(HTTPS10Bytes)) {
                        majorVersion = 1;
                        minorVersion = 0;
                        scheme = "https";
                    } else {
                        String reason =  "Bad HTTP version: " + getString();
                        clearBuffer();
                        shutdownParser();
                        throw new BadMessage(reason);
                    }

                    clearBuffer();

                    // We are through parsing the request line
                    lineState = LineState.END;
                    return !submitRequestLine(method, path, scheme, majorVersion, minorVersion);

                default:
                    throw new InvalidState(
                            "Attempted to parse Request line when already " +
                                    "complete. LineState: '" + lineState + "'");
            }    // switch
        }        // while loop
    }
1275610
private boolean readRequest(ReadStream is)
    throws IOException
  {
    // server/12o3 - default to 1.0 for error messages in request
    _version = HTTP_1_0;
    
    boolean []isHttpWhitespace = _isHttpWhitespace;
    char []toUpperAscii = _toUpperAscii;
    
    byte []readBuffer = is.buffer();
    int readOffset = is.offset();
    int readLength = is.length();
    int ch;

    // skip leading whitespace
    do {
      if (readLength <= readOffset) {
        if ((readLength = is.fillBuffer()) < 0) {
          return false;
        }

        readOffset = 0;
      }

      ch = readBuffer[readOffset++] & 0xff;
    } while (isHttpWhitespace[ch]);

    char []buffer = _method.buffer();
    int length = buffer.length;
    int offset = 0;

    // scan method
    while (true) {
      if (length <= offset) {
      }
      else if (ch > ' ') {
        buffer[offset++] = toUpperAscii[ch];
      }
      else {
        break;
      }
        

      if (readLength <= readOffset) {
        if ((readLength = is.fillBuffer()) < 0)
          return false;

        readOffset = 0;
      }
      
      ch = readBuffer[readOffset++];
    }
    
    _method.length(offset);

    // skip whitespace
    while (ch == ' ' || ch == '\t') {
      if (readLength <= readOffset) {
        if ((readLength = is.fillBuffer()) < 0)
          return false;

        readOffset = 0;
      }

      ch = readBuffer[readOffset++];
    }
    
    if (ch == '*') {
      if (_method.matches("PRI") && startHttp2()) {
        return false;
      }
      else if (_method.matches("HAMP")) {
        if (! request().startBartender()) {
          return false;
        }
        else {
          log.warning("Invalid Request: unable to start HAMP");
          
          throw new BadRequestException("Invalid Request(Remote IP=" + connTcp().ipRemote() + ")");
        }
      }
    }

    byte []uriBuffer = _uri;
    int uriLength = 0;

    // skip 'http:'
    if (ch != '/') {
      while (ch > ' ' && ch != '/') {
        if (readLength <= readOffset) {
          if ((readLength = is.fillBuffer()) < 0)
            return false;
          readOffset = 0;
        }
        ch = readBuffer[readOffset++];
      }
      
      if (ch == '/') {
      }
      else {
        log.warning("Invalid Request (method='" + _method + "' url ch=0x" + Integer.toHexString(ch & 0xff)
                    + " off=" +readOffset + " len=" + readLength
                    + ") (IP=" + connTcp().ipRemote() + ")");
        log.warning(new String(readBuffer, 0, readLength));
        
        throw new BadRequestException("Invalid Request (Remote IP=" + connTcp().ipRemote() + ")");
      }

      if (readLength <= readOffset) {
        if ((readLength = is.fillBuffer()) < 0) {
          if (ch == '/') {
            uriBuffer[uriLength++] = (byte) ch;
            _uriLength = uriLength;
          }
          
          _version = 0;

          return true;
        }
        readOffset = 0;
      }

      int ch1 = readBuffer[readOffset++] & 0xff;

      if (ch1 != '/') {
        uriBuffer[uriLength++] = (byte) ch;
        ch = ch1;
      }
      else {
        // read host
        host:
        while (true) {
          if (readLength <= readOffset) {
            if ((readLength = is.fillBuffer()) < 0) {
              _version = 0;
              
              return true;
            }
            readOffset = 0;
          }
          ch = readBuffer[readOffset++] & 0xff;

          switch (ch) {
          case ' ': case '\t': case '\n': case '\r':
            break host;

          case '?':
            break host;

          case '/':
            break host;

          default:
            _uriHost.append((char) ch);
            break;
          }
        }
      }
    }
    
    int readTail = uriBuffer.length - uriLength - 1;
    
    readTail = Math.min(readTail, readLength);

    // read URI
    while (! isHttpWhitespace[ch]) {
      // There's no check for over-running the length because
      // allowing resizing would allow a DOS memory attack and
      // also lets us save a bit of efficiency.
      uriBuffer[uriLength++] = (byte) ch;

      if (readTail <= readOffset) {
        if ((readTail = fillUrlTail(is, readOffset, uriLength)) <= 0) {
          _uriLength = uriLength;
          _version = 0;
          return true;
        }

        readOffset = is.offset();
        uriBuffer = _uri;
        uriLength = _uriLength;
      }
      
      ch = readBuffer[readOffset++] & 0xff;
    }
    
    _uriLength = uriLength;
    _version = 0;

    // skip whitespace
    while (ch == ' ' || ch == '\t') {
      if (readLength <= readOffset) {
        readOffset = 0;
        if ((readLength = is.fillBuffer()) < 0)
          return true;
      }
      ch = readBuffer[readOffset++] & 0xff;
    }

    buffer = _protocol.buffer();
    length = buffer.length;
    offset = 0;
    
    // scan protocol
    while (! isHttpWhitespace[ch]) {
      if (offset < length) {
        buffer[offset++] = toUpperAscii[ch];
      }

      if (readLength <= readOffset) {
        readOffset = 0;
        if ((readLength = is.fillBuffer()) < 0) {
          _protocol.length(offset);
          return true;
        }
      }
      ch = readBuffer[readOffset++] & 0xff;
    }

    _protocol.length(offset);

    if (offset != 8) {
      _protocol.append("HTTP/0.9");
      _version = HTTP_0_9;
      killKeepalive("0.9");
    }
    else if (buffer[7] == '1') { // && _protocol.equals(_http11Cb))
      _version = HTTP_1_1;
    }
    else if (buffer[7] == '0') { // && _protocol.equals(_http10Cb))
      _version = HTTP_1_0;
    }
    else {
      _version = HTTP_0_9;
      killKeepalive("0.9");
    }

    // skip to end of line
    while (ch != '\n') {
      if (readLength <= readOffset) {
        if ((readLength = is.fillBuffer()) < 0)
          return true;
        readOffset = 0;
      }
      ch = readBuffer[readOffset++];
    }

    is.offset(readOffset);

    return true;
  }
1129900
@Override
    public ReadStream<Buffer> handler(Handler<Buffer> handler) {
        if (handler == null) {
            throw new IllegalArgumentException("handler");
        }
        this.dataHandler = handler;
        doRead();
        return this;
    }
1257014
public synchronized final void parseDetails() {
        LOG.debug("parsing details of {}", this.getType());
        if (content != null) {
            ByteBuffer content = this.content;
            isParsed = true;
            content.rewind();
            _parseDetails(content);
            if (content.remaining() > 0) {
                deadBytes = content.slice();
            }
            this.content = null;
            assert verify(content);
        }
    }
268161
protected boolean parseMimePartHeaders(ByteBuffer buffer) {
        // Process headers
        while (_state == State.BODY_PART && hasNextByte(buffer)) {
            // process each character
            HttpTokens.Token t = next(buffer);
            if (t == null)
                break;

            if (t.getType() != HttpTokens.Type.LF)
                _totalHeaderLineLength++;

            if (_totalHeaderLineLength > MAX_HEADER_LINE_LENGTH)
                throw new IllegalStateException("Header Line Exceeded Max Length");

            switch (_fieldState) {
                case FIELD:
                    switch (t.getType()) {
                        case SPACE:
                        case HTAB: {
                            // Folded field value!

                            if (_fieldName == null)
                                throw new IllegalStateException("First field folded");

                            if (_fieldValue == null) {
                                _string.reset();
                                _length = 0;
                            } else {
                                setString(_fieldValue);
                                _string.append(' ');
                                _length++;
                                _fieldValue = null;
                            }
                            setState(FieldState.VALUE);
                            break;
                        }

                        case LF:
                            handleField();
                            setState(State.FIRST_OCTETS);
                            _partialBoundary = 2; // CRLF is option for empty parts

                            if (LOG.isDebugEnabled())
                                LOG.debug("headerComplete {}", this);

                            if (_handler.headerComplete())
                                return true;
                            break;

                        case ALPHA:
                        case DIGIT:
                        case TCHAR:
                            // process previous header
                            handleField();

                            // New header
                            setState(FieldState.IN_NAME);
                            _string.reset();
                            _string.append(t.getChar());
                            _length = 1;

                            break;

                        default:
                            throw new IllegalCharacterException(_state, t, buffer);
                    }
                    break;

                case IN_NAME:
                    switch (t.getType()) {
                        case COLON:
                            _fieldName = takeString();
                            _length = -1;
                            setState(FieldState.VALUE);
                            break;

                        case SPACE:
                            // Ignore trailing whitespaces
                            setState(FieldState.AFTER_NAME);
                            break;

                        case LF: {
                            if (LOG.isDebugEnabled())
                                LOG.debug("Line Feed in Name {}", this);

                            handleField();
                            setState(FieldState.FIELD);
                            break;
                        }

                        case ALPHA:
                        case DIGIT:
                        case TCHAR:
                            _string.append(t.getChar());
                            _length = _string.length();
                            break;

                        default:
                            throw new IllegalCharacterException(_state, t, buffer);
                    }
                    break;

                case AFTER_NAME:
                    switch (t.getType()) {
                        case COLON:
                            _fieldName = takeString();
                            _length = -1;
                            setState(FieldState.VALUE);
                            break;

                        case LF:
                            _fieldName = takeString();
                            _string.reset();
                            _fieldValue = "";
                            _length = -1;
                            break;

                        case SPACE:
                            break;

                        default:
                            throw new IllegalCharacterException(_state, t, buffer);
                    }
                    break;

                case VALUE:
                    switch (t.getType()) {
                        case LF:
                            _string.reset();
                            _fieldValue = "";
                            _length = -1;

                            setState(FieldState.FIELD);
                            break;

                        case SPACE:
                        case HTAB:
                            break;

                        case ALPHA:
                        case DIGIT:
                        case TCHAR:
                        case VCHAR:
                        case COLON:
                        case OTEXT:
                            _string.append(t.getByte());
                            _length = _string.length();
                            setState(FieldState.IN_VALUE);
                            break;

                        default:
                            throw new IllegalCharacterException(_state, t, buffer);
                    }
                    break;

                case IN_VALUE:
                    switch (t.getType()) {
                        case SPACE:
                        case HTAB:
                            _string.append(' ');
                            break;

                        case LF:
                            if (_length > 0) {
                                _fieldValue = takeString();
                                _length = -1;
                                _totalHeaderLineLength = -1;
                            }
                            setState(FieldState.FIELD);
                            break;

                        case ALPHA:
                        case DIGIT:
                        case TCHAR:
                        case VCHAR:
                        case COLON:
                        case OTEXT:
                            _string.append(t.getByte());
                            _length = _string.length();
                            break;

                        default:
                            throw new IllegalCharacterException(_state, t, buffer);
                    }
                    break;

                default:
                    throw new IllegalStateException(_state.toString());

            }
        }
        return false;
    }
497111
private int next(final byte[] buffer, final int offset,
        final int length) throws IOException {
        final int max = Math.min(length, this.input.remaining());
        this.input.put(buffer, offset, max);
        this.input.flip();
        while (true) {
            final CoderResult result = this.decoder.decode(
                this.input, this.output, false
            );
            if (result.isError()) {
                result.throwException();
            }
            this.writer.write(
                this.output.array(), 0, this.output.position()
            );
            this.writer.flush();
            this.output.rewind();
            if (result.isUnderflow()) {
                break;
            }
        }
        this.input.compact();
        return max;
    }
724141
def parse!(buffer)
      offset = parse(buffer)
      return if offset.zero?

      buffer.slice!(0..offset - 1)
      buffer
    end
737896
private boolean initRequestHandler(SelectionKey selectionKey) {
        ByteBuffer inputBuffer = inputStream.getBuffer();
        int remaining = inputBuffer.remaining();

        // Don't have enough bytes to determine the protocol yet...
        if(remaining < 3)
            return true;

        byte[] protoBytes = { inputBuffer.get(0), inputBuffer.get(1), inputBuffer.get(2) };

        try {
            String proto = ByteUtils.getString(protoBytes, "UTF-8");
            inputBuffer.clear();
            RequestFormatType requestFormatType = RequestFormatType.fromCode(proto);
            requestHandler = requestHandlerFactory.getRequestHandler(requestFormatType);

            if(logger.isInfoEnabled())
                logger.info("Protocol negotiated for " + socketChannel.socket() + ": "
                            + requestFormatType.getDisplayName());

            // The protocol negotiation is the first request, so respond by
            // sticking the bytes in the output buffer, signaling the Selector,
            // and returning false to denote no further processing is needed.
            outputStream.getBuffer().put(ByteUtils.getBytes("ok", "UTF-8"));
            prepForWrite(selectionKey);

            return false;
        } catch(IllegalArgumentException e) {
            // okay we got some nonsense. For backwards compatibility,
            // assume this is an old client who does not know how to negotiate
            RequestFormatType requestFormatType = RequestFormatType.VOLDEMORT_V0;
            requestHandler = requestHandlerFactory.getRequestHandler(requestFormatType);

            if(logger.isInfoEnabled())
                logger.info("No protocol proposal given for " + socketChannel.socket()
                            + ", assuming " + requestFormatType.getDisplayName());

            return true;
        }
    }
482585
protected boolean parseOctetContent(ByteBuffer buffer) {

        // Starts With
        if (_partialBoundary > 0) {
            int partial = _delimiterSearch.startsWith(buffer.array(), buffer.arrayOffset() + buffer.position(), buffer.remaining(), _partialBoundary);
            if (partial > 0) {
                if (partial == _delimiterSearch.getLength()) {
                    buffer.position(buffer.position() + _delimiterSearch.getLength() - _partialBoundary);
                    setState(State.DELIMITER);
                    _partialBoundary = 0;

                    if (LOG.isDebugEnabled())
                        LOG.debug("Content={}, Last={} {}", BufferUtils.toDetailString(BufferUtils.EMPTY_BUFFER), true, this);

                    return _handler.content(BufferUtils.EMPTY_BUFFER, true);
                }

                _partialBoundary = partial;
                BufferUtils.clear(buffer);
                return false;
            } else {
                // output up to _partialBoundary of the search pattern
                ByteBuffer content = _patternBuffer.slice();
                if (_state == State.FIRST_OCTETS) {
                    setState(State.OCTETS);
                    content.position(2);
                }
                content.limit(_partialBoundary);
                _partialBoundary = 0;

                if (LOG.isDebugEnabled())
                    LOG.debug("Content={}, Last={} {}", BufferUtils.toDetailString(content), false, this);

                if (_handler.content(content, false))
                    return true;
            }
        }

        // Contains
        int delimiter = _delimiterSearch.match(buffer.array(), buffer.arrayOffset() + buffer.position(), buffer.remaining());
        if (delimiter >= 0) {
            ByteBuffer content = buffer.slice();
            content.limit(delimiter - buffer.arrayOffset() - buffer.position());

            buffer.position(delimiter - buffer.arrayOffset() + _delimiterSearch.getLength());
            setState(State.DELIMITER);

            if (LOG.isDebugEnabled())
                LOG.debug("Content={}, Last={} {}", BufferUtils.toDetailString(content), true, this);

            return _handler.content(content, true);
        }

        // Ends With
        _partialBoundary = _delimiterSearch.endsWith(buffer.array(), buffer.arrayOffset() + buffer.position(), buffer.remaining());
        if (_partialBoundary > 0) {
            ByteBuffer content = buffer.slice();
            content.limit(content.limit() - _partialBoundary);

            if (LOG.isDebugEnabled())
                LOG.debug("Content={}, Last={} {}", BufferUtils.toDetailString(content), false, this);

            BufferUtils.clear(buffer);
            return _handler.content(content, false);
        }

        // There is normal content with no delimiter
        ByteBuffer content = buffer.slice();

        if (LOG.isDebugEnabled())
            LOG.debug("Content={}, Last={} {}", BufferUtils.toDetailString(content), false, this);

        BufferUtils.clear(buffer);
        return _handler.content(content, false);
    }
1296983
void parseDocument(
            final char[] buffer, final int offset, final int len,
            final IMarkupHandler handler, final ParseStatus status)
            throws ParseException {


        final long parsingStartTimeNanos = System.nanoTime();

        try {

            handler.handleDocumentStart(parsingStartTimeNanos, 1, 1);

            status.offset = -1;
            status.line = 1;
            status.col = 1;
            status.inStructure = false;
            status.parsingDisabled = true;
            status.parsingDisabledLimitSequence = null;
            status.autoCloseRequired = null;
            status.autoCloseLimits = null;

            parseBuffer(buffer, offset, len, handler, status);

            // First parse done, now it's time to clean up in case we still have some text to be notified

            int lastLine = status.line;
            int lastCol = status.col;

            final int lastStart = status.offset;
            final int lastLen = (offset + len) - lastStart;

            if (lastLen > 0) {

                if (status.inStructure) {
                    throw new ParseException(
                            "Incomplete structure: \"" + new String(buffer, lastStart, lastLen) + "\"", status.line, status.col);
                }

                handler.handleText(buffer, lastStart, lastLen, status.line, status.col);

                // As we have produced an additional text event, we need to fast-forward the
                // lastLine and lastCol position to include the last text structure.
                for (int i = lastStart; i < (lastStart + lastLen); i++) {
                    final char c = buffer[i];
                    if (c == '\n') {
                        lastLine++;
                        lastCol = 1;
                    } else {
                        lastCol++;
                    }

                }

            }

            final long parsingEndTimeNanos = System.nanoTime();
            handler.handleDocumentEnd(parsingEndTimeNanos, (parsingEndTimeNanos - parsingStartTimeNanos), lastLine, lastCol);

        } catch (final ParseException e) {
            throw e;
        } catch (final Exception e) {
            throw new ParseException(e);
        }

    }