private void update()

in src/main/java/org/apache/sling/scripting/sightly/impl/html/dom/HtmlParser.java [135:424]


    private void update(final char[] buf, int len) throws IOException {
        int start = 0;
        final int end = len;

        for (int curr = start; curr < end; curr++) {
            final char c = buf[curr];

            switch (parseState) {
            case OUTSIDE:
                if (c == '<') {
                    if (curr > start) {
                        documentHandler.onCharacters(buf, start, curr - start);
                    }
                    start = curr;
                    parseState = PARSE_STATE.TAG;
                    parseSubState = 0;
                    tagType = TT_MAYBE;
                    resetTagName();
                } else if (c == '$') {
                    exprType = EXPR_MAYBE;
                    parseState = PARSE_STATE.EXPRESSION;
                }
                break;
            case TAG:
                switch (parseSubState) {
                case -1:
                    if (c == '"' || c == '\'') {
                        quoteChar = c;
                        prevParseState = parseState;
                        parseState = PARSE_STATE.STRING;
                        parseSubState = -1;
                    } else if (c == '>') {
                        parseState = PARSE_STATE.OUTSIDE;
                    }
                    break;
                case 0:
                    if (c == '!') {
                        parseState = PARSE_STATE.COMMENT;
                        parseSubState = 0;
                        tagType = TT_NONE;
                        // keep the accumulated buffer
                    } else if (c == '"' || c == '\'') {
                        quoteChar = c;
                        prevParseState = parseState;
                        parseState = PARSE_STATE.STRING;
                        parseSubState = -1;
                        tagType = TT_NONE;
                        flushBuffer();
                    } else if (c == '>') {
                        parseState = PARSE_STATE.OUTSIDE;
                        tagType = TT_NONE;
                        flushBuffer();
                    } else if (!Character.isWhitespace(c)) {
                        tagNameBuffer.write(c);
                        parseSubState = 1;
                    } else {
                        parseSubState = -1;
                        tagType = TT_NONE;
                        flushBuffer();
                    }
                    break;
                case 1:
                    if (c == '"' || c == '\'') {
                        tagType = TT_TAG;
                        parseSubState = 2;
                        quoteChar = c;
                        prevParseState = parseState;
                        parseState = PARSE_STATE.STRING;
                    } else if (c == '>') {
                        parseState = processTag(buf, start, curr - start + 1) ? PARSE_STATE.SCRIPT : PARSE_STATE.OUTSIDE;
                        start = curr + 1;
                        tagType = TT_NONE;
                        parseSubState = 0;
                    } else if (Character.isWhitespace(c)) {
                        tagType = TT_TAG;
                        parseSubState = 2;
                    } else {
                        tagNameBuffer.write(c);
                    }
                    break;
                case 2:
                    if (c == '"' || c == '\'') {
                        quoteChar = c;
                        prevParseState = parseState;
                        parseState = PARSE_STATE.STRING;
                    } else if (c == '>') {
                        if (tagType == TT_TAG) {
                            parseState = processTag(buf, start, curr - start + 1) ? PARSE_STATE.SCRIPT : PARSE_STATE.OUTSIDE;
                            start = curr + 1;
                        } else {
                            flushBuffer();
                            parseState = "SCRIPT".equalsIgnoreCase(getTagName()) ? PARSE_STATE.SCRIPT : PARSE_STATE.OUTSIDE;
                        }
                        tagType = TT_NONE;
                        parseSubState = 0;
                    }
                    break;
                default:
                    break;
                }
                break;
            case COMMENT:
                switch (parseSubState) {
                case 0:
                    if (c == '-') {
                        parseSubState++;
                    } else if (c == '"' || c == '\'') {
                        quoteChar = c;
                        prevParseState = PARSE_STATE.TAG;
                        parseState = PARSE_STATE.STRING;
                        parseSubState = -1;
                        tagType = TT_NONE;
                        flushBuffer();
                    } else if (c == '>') {
                        parseState = PARSE_STATE.OUTSIDE;
                        tagType = TT_NONE;
                        flushBuffer();
                    } else {
                        parseState = PARSE_STATE.TAG;
                        parseSubState = -1;
                        tagType = TT_NONE;
                        flushBuffer();
                    }
                    break;
                case 1:
                    if (c == '-') {
                        parseSubState++;
                    } else if (c == '"' || c == '\'') {
                        quoteChar = c;
                        prevParseState = PARSE_STATE.TAG;
                        parseState = PARSE_STATE.STRING;
                        parseSubState = -1;
                        tagType = TT_NONE;
                        flushBuffer();
                    } else if (c == '>') {
                        parseState = PARSE_STATE.OUTSIDE;
                        tagType = TT_NONE;
                        flushBuffer();
                    } else {
                        parseState = PARSE_STATE.TAG;
                        parseSubState = -1;
                        tagType = TT_NONE;
                        flushBuffer();
                    }
                    break;
                case 2:
                    if (c == '-') {
                        parseSubState++;
                    }
                    break;
                case 3:
                    if (c == '-') {
                        parseSubState++;
                    } else {
                        parseSubState = 2;
                    }
                    break;
                case 4:
                    if (c == '>') {
                        parseState = PARSE_STATE.OUTSIDE;
                        processComment(buf, start, curr - start + 1);
                        start = curr + 1;
                    } else {
                        parseSubState = 2;
                    }
                    break;
                default:
                    break;
                }
                break;

            case SCRIPT:
                switch (parseSubState) {
                case 0:
                    if (c == '<') {
                        if (curr > start) {
                            documentHandler.onCharacters(buf, start, curr - start);
                        }
                        start = curr;
                        tagType = TT_MAYBE;
                        parseSubState++;
                    }
                    break;
                case 1:
                    if (c == '/') {
                        parseSubState++;
                    } else {
                        tagType = TT_NONE;
                        parseSubState = 0;
                        flushBuffer();
                    }
                    break;
                case 2:
                    if (c == 'S' || c == 's') {
                        parseSubState++;
                    } else {
                        tagType = TT_NONE;
                        parseSubState = 0;
                        flushBuffer();
                    }
                    break;
                case 3:
                    if (c == 'C' || c == 'c') {
                        parseSubState++;
                    } else {
                        tagType = TT_NONE;
                        parseSubState = 0;
                        flushBuffer();
                    }
                    break;
                case 4:
                    if (c == 'R' || c == 'r') {
                        parseSubState++;
                    } else {
                        tagType = TT_NONE;
                        parseSubState = 0;
                        flushBuffer();
                    }
                    break;
                case 5:
                    if (c == 'I' || c == 'i') {
                        parseSubState++;
                    } else {
                        tagType = TT_NONE;
                        parseSubState = 0;
                        flushBuffer();
                    }
                    break;
                case 6:
                    if (c == 'P' || c == 'p') {
                        parseSubState++;
                    } else {
                        tagType = TT_NONE;
                        parseSubState = 0;
                        flushBuffer();
                    }
                    break;
                case 7:
                    if (c == 'T' || c == 't') {
                        parseSubState++;
                    } else {
                        tagType = TT_NONE;
                        parseSubState = 0;
                        flushBuffer();
                    }
                    break;
                case 8:
                    if (c == '>') {
                        processTag(buf, start, curr - start + 1);
                        start = curr + 1;
                        tagType = TT_NONE;
                        parseState = PARSE_STATE.OUTSIDE;
                    }
                    break;
                default:
                    break;
                }
                break;

            case STRING:
                if (c == quoteChar) {
                    parseState = prevParseState;
                }
                break;

            case EXPRESSION:
                if (exprType == EXPR_MAYBE && c != '{') {
                    // not a valid expression
                    if (c == '<') {
                        //reset to process tag correctly
                        curr--;
                    }
                    parseState = PARSE_STATE.OUTSIDE;
                } else if (c == '}') {
                    parseState = PARSE_STATE.OUTSIDE;
                }
                exprType = EXPR_NONE;
                break;
            default:
                break;
            }
        }
        if (start < end) {
            if (tagType == TT_NONE && parseState != PARSE_STATE.COMMENT) {
                documentHandler.onCharacters(buf, start, end - start);
            } else {
                buffer.write(buf, start, end - start);
            }
        }
    }