private void processChars()

in java/org/apache/jasper/compiler/JspDocumentParser.java [385:516]


    private void processChars() throws SAXException {

        if (charBuffer == null || directivesOnly) {
            return;
        }

        /*
         * JSP.6.1.1: All textual nodes that have only white space are to be dropped from the document, except for nodes
         * in a jsp:text element, and any leading and trailing white-space-only textual nodes in a jsp:attribute whose
         * 'trim' attribute is set to FALSE, which are to be kept verbatim. <p> JSP.6.2.3 defines white space
         * characters.
         */
        boolean isAllSpace = true;
        if (!(current instanceof Node.JspText) && !(current instanceof Node.NamedAttribute)) {
            for (int i = 0; i < charBuffer.length(); i++) {
                char ch = charBuffer.charAt(i);
                if (!(ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t')) {
                    isAllSpace = false;
                    break;
                }
            }
        }

        if (!isAllSpace && tagDependentPending) {
            tagDependentPending = false;
            tagDependentNesting++;
        }

        if (tagDependentNesting > 0 || pageInfo.isELIgnored() || current instanceof Node.ScriptingElement) {
            if (!charBuffer.isEmpty()) {
                @SuppressWarnings("unused")
                Node unused = new Node.TemplateText(charBuffer.toString(), startMark, current);
            }
            startMark = new Mark(ctxt, path, locator.getLineNumber(), locator.getColumnNumber());
            charBuffer = null;
            return;
        }

        if ((current instanceof Node.JspText) || (current instanceof Node.NamedAttribute) || !isAllSpace) {

            int line = startMark.getLineNumber();
            int column = startMark.getColumnNumber();

            CharArrayWriter ttext = new CharArrayWriter();
            int lastCh = 0;
            int elType;
            for (int i = 0; i < charBuffer.length(); i++) {

                int ch = charBuffer.charAt(i);
                if (ch == '\n') {
                    column = 1;
                    line++;
                } else {
                    column++;
                }
                if ((lastCh == '$' || lastCh == '#') && ch == '{') {
                    elType = lastCh;
                    if (ttext.size() > 0) {
                        @SuppressWarnings("unused")
                        Node unused = new Node.TemplateText(ttext.toString(), startMark, current);
                        ttext.reset();
                        // We subtract two from the column number to
                        // account for the '[$,#]{' that we've already parsed
                        startMark = new Mark(ctxt, path, line, column - 2);
                    }
                    // following "${" || "#{" to first unquoted "}"
                    i++;
                    boolean singleQ = false;
                    boolean doubleQ = false;
                    lastCh = 0;
                    for (;; i++) {
                        if (i >= charBuffer.length()) {
                            throw new SAXParseException(
                                    Localizer.getMessage("jsp.error.unterminated", (char) elType + "{"), locator);

                        }
                        ch = charBuffer.charAt(i);
                        if (ch == '\n') {
                            column = 1;
                            line++;
                        } else {
                            column++;
                        }
                        if (lastCh == '\\' && (singleQ || doubleQ)) {
                            ttext.write(ch);
                            lastCh = 0;
                            continue;
                        }
                        if (ch == '}') {
                            @SuppressWarnings("unused")
                            Node unused = new Node.ELExpression((char) elType, ttext.toString(), startMark, current);
                            ttext.reset();
                            startMark = new Mark(ctxt, path, line, column);
                            break;
                        }
                        if (ch == '"') {
                            doubleQ = !doubleQ;
                        } else if (ch == '\'') {
                            singleQ = !singleQ;
                        }

                        ttext.write(ch);
                        lastCh = ch;
                    }
                } else if (lastCh == '\\' && (ch == '$' || ch == '#')) {
                    if (pageInfo.isELIgnored()) {
                        ttext.write('\\');
                    }
                    ttext.write(ch);
                    ch = 0; // Not start of EL anymore
                } else {
                    if (lastCh == '$' || lastCh == '#' || lastCh == '\\') {
                        ttext.write(lastCh);
                    }
                    if (ch != '$' && ch != '#' && ch != '\\') {
                        ttext.write(ch);
                    }
                }
                lastCh = ch;
            }
            if (lastCh == '$' || lastCh == '#' || lastCh == '\\') {
                ttext.write(lastCh);
            }
            if (ttext.size() > 0) {
                @SuppressWarnings("unused")
                Node unused = new Node.TemplateText(ttext.toString(), startMark, current);
            }
        }
        startMark = new Mark(ctxt, path, locator.getLineNumber(), locator.getColumnNumber());

        charBuffer = null;
    }