Index: apache/jasper/compiler/JspReader.java =================================================================== --- apache/jasper/compiler/JspReader.java (revision 1370136) +++ apache/jasper/compiler/JspReader.java (working copy) @@ -191,6 +191,38 @@ } return ch; } + + /** + * A better performance solution for calling {@link #mark()} & {@link #nextChar()} + * Assume that the parameter mark should be used internal. + * + * @param mark + * @return + * @throws JasperException + */ + int nextChar(Mark mark) throws JasperException { + if (!hasMoreInput()) + return -1; + + int ch = current.stream[current.cursor]; + + if (singleFile) { //Simplified + mark.update(current); + } + else { + mark.init(current); + } + + current.cursor++; + + if (ch == '\n') { + current.line++; + current.col = 0; + } else { + current.col++; + } + return ch; + } /** * Back up the current cursor by one char, assumes current.cursor > 0, @@ -205,10 +237,10 @@ Mark oldstart = mark(); reset(start); CharArrayWriter caw = new CharArrayWriter(); - while (!stop.equals(mark())) + while (!markEquals(stop)) caw.write(nextChar()); caw.close(); - reset(oldstart); + setCurrent(oldstart); return caw.toString(); } @@ -221,10 +253,31 @@ Mark mark() { return new Mark(current); } + + /** + * This method can avoid to call {@link #mark()} when doing comparison. + * It is used in {@link #getText(Mark, Mark)} + * + * @param another + * @return + */ + boolean markEquals(Mark another) { + return another.equals(current); + } void reset(Mark mark) { current = new Mark(mark); } + + /** + * Similar with {@link #reset(Mark)}, however, no new Mark will be created. + * So the parameter mark must NOT be used in other place. + * + * @param mark + */ + void setCurrent(Mark mark) { + current = mark; + } /** * search the stream for a match to a string @@ -240,7 +293,7 @@ do { ch = nextChar(); if (((char) ch) != string.charAt(i++)) { - reset(mark); + setCurrent(mark); return false; } } while (i < string.length()); @@ -256,7 +309,7 @@ if (nextChar() == '>') return true; - reset(mark); + setCurrent(mark); return false; } @@ -271,7 +324,7 @@ if (nextChar() == '>') return true; - reset(mark); + setCurrent(mark); return false; } @@ -290,7 +343,7 @@ skipSpaces(); boolean result = matches( s ); if( !result ) { - reset( mark ); + setCurrent( mark ); } return result; @@ -315,20 +368,20 @@ * otherwise. */ Mark skipUntil(String limit) throws JasperException { - Mark ret = null; + Mark ret = mark(); int limlen = limit.length(); int ch; + char firstChar = limit.charAt(0); skip: - for (ret = mark(), ch = nextChar() ; ch != -1 ; - ret = mark(), ch = nextChar()) { - if (ch == limit.charAt(0)) { + for (ch = nextChar(ret) ; ch != -1 ;ch = nextChar(ret)) { + if (ch == firstChar) { Mark restart = mark(); for (int i = 1 ; i < limlen ; i++) { if (peekChar() == limit.charAt(i)) nextChar(); else { - reset(restart); + setCurrent(restart); continue skip; } } @@ -349,18 +402,18 @@ * otherwise. */ Mark skipUntilIgnoreEsc(String limit) throws JasperException { - Mark ret = null; + Mark ret = mark(); int limlen = limit.length(); int ch; int prev = 'x'; // Doesn't matter + char firstChar = limit.charAt(0); skip: - for (ret = mark(), ch = nextChar() ; ch != -1 ; - ret = mark(), prev = ch, ch = nextChar()) { + for (ch = nextChar(ret) ; ch != -1 ; prev = ch, ch = nextChar(ret)) { if (ch == '\\' && prev == '\\') { ch = 0; // Double \ is not an escape char anymore } - else if (ch == limit.charAt(0) && prev != '\\') { + else if (ch == firstChar && prev != '\\') { for (int i = 1 ; i < limlen ; i++) { if (peekChar() == limit.charAt(i)) nextChar(); @@ -477,10 +530,10 @@ Mark mark = mark(); if (((ch = nextChar()) == '>') || ((ch == '-') && (nextChar() == '>'))) { - reset(mark); + setCurrent(mark); return true; } else { - reset(mark); + setCurrent(mark); return false; } }