/* * ============================================================================= * * Copyright (c) 2011-2016, The THYMELEAF team (http://www.thymeleaf.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * ============================================================================= */ package org.thymeleaf.templateparser.text; /* * Class containing utility methods for general text parsing. * * @author Daniel Fernandez * @since 3.0.0 */ final class TextParsingUtil { private TextParsingUtil() { super(); } static int findNextStructureEndAvoidQuotes( final char[] text, final int offset, final int maxi, final int[] locator) { boolean inQuotes = false; boolean inApos = false; char c; int colIndex = offset; int i = offset; int n = (maxi - offset); while (n-- != 0) { c = text[i]; if (c == '\n') { colIndex = i; locator[1] = 0; locator[0]++; } else if (c == '"' && !inApos) { inQuotes = !inQuotes; } else if (c == '\'' && !inQuotes) { inApos = !inApos; } else if (c == ']' && !inQuotes && !inApos) { locator[1] += (i - colIndex); return i; } i++; } locator[1] += (maxi - colIndex); return -1; } static int findNextCommentBlockEnd( final char[] text, final int offset, final int maxi, final int[] locator) { char c; int colIndex = offset; int i = offset; int n = (maxi - offset); while (n-- != 0) { c = text[i]; if (c == '\n') { colIndex = i; locator[1] = 0; locator[0]++; } else if (i > offset && c == '/' && text[i - 1] == '*') { locator[1] += (i - colIndex); return i; } i++; } locator[1] += (maxi - colIndex); return -1; } static int findNextCommentLineEnd( final char[] text, final int offset, final int maxi, final int[] locator) { char c; int colIndex = offset; int i = offset; int n = (maxi - offset); while (n-- != 0) { c = text[i]; if (c == '\n') { locator[1] += (i - colIndex); return i; } i++; } locator[1] += (maxi - colIndex); return -1; } static int findNextLiteralEnd( final char[] text, final int offset, final int maxi, final int[] locator, final char literalMarker) { char c; int colIndex = offset; int i = offset; int n = (maxi - offset); while (n-- != 0) { c = text[i]; if (c == '\n') { colIndex = i; locator[1] = 0; locator[0]++; } else if (i > offset && c == literalMarker) { if (isLiteralDelimiter(text, offset, i)) { locator[1] += (i - colIndex); return i; } } i++; } locator[1] += (maxi - colIndex); return -1; } static int findNextStructureStartOrLiteralMarker( final char[] text, final int offset, final int maxi, final int[] locator, final boolean processCommentsAndLiterals) { char c; int colIndex = offset; int i = offset; int n = (maxi - offset); while (n-- != 0) { c = text[i]; if (c == '\n') { colIndex = i; locator[1] = 0; locator[0]++; } else if (c == '[') { // '[' is for elements locator[1] += (i - colIndex); return i; } else if (processCommentsAndLiterals) { if (c == '/') { // '/' is for comments (/*...*/, //...\n) locator[1] += (i - colIndex); return i; } else if (c == '\'' || c == '"') { // literal markers if (isLiteralDelimiter(text, offset, i)) { // check it is not escaped locator[1] += (i - colIndex); return i; } } } i++; } locator[1] += (maxi - colIndex); return -1; } private static boolean isLiteralDelimiter(final char[] text, final int offset, final int i) { int escapes = 0; int j = i - 1; while (j >= offset && text[j--] == '\\') { escapes++; } return escapes % 2 == 0; } static int findNextWhitespaceCharWildcard( final char[] text, final int offset, final int maxi, final boolean avoidQuotes, final int[] locator) { boolean inQuotes = false; boolean inApos = false; char c; int i = offset; int n = (maxi - offset); while (n-- != 0) { c = text[i]; if (avoidQuotes && !inApos && c == '"') { inQuotes = !inQuotes; } else if (avoidQuotes && !inQuotes && c == '\'') { inApos = !inApos; } else if (!inQuotes && !inApos && (c == ' ' || c == '\n' || c == '\t' || c == '\r' || c == '\f' || c == '\u000B' || c == '\u001C' || c == '\u001D' || c == '\u001E' || c == '\u001F' || (c > '\u007F' && Character.isWhitespace(c)))) { return i; } ParsingLocatorUtil.countChar(locator, c); i++; } return -1; } static int findNextNonWhitespaceCharWildcard( final char[] text, final int offset, final int maxi, final int[] locator) { char c; boolean isWhitespace; int i = offset; int n = (maxi - offset); while (n-- != 0) { c = text[i]; isWhitespace = (c == ' ' || c == '\n' || c == '\t' || c == '\r' || c == '\f' || c == '\u000B' || c == '\u001C' || c == '\u001D' || c == '\u001E' || c == '\u001F' || (c > '\u007F' && Character.isWhitespace(c))); if (!isWhitespace) { return i; } ParsingLocatorUtil.countChar(locator, c); i++; } return -1; } static int findNextOperatorCharWildcard( final char[] text, final int offset, final int maxi, final int[] locator) { char c; int i = offset; int n = (maxi - offset); while (n-- != 0) { c = text[i]; if (c == '=' || (c == ' ' || c == '\n' || c == '\t' || c == '\r' || c == '\f' || c == '\u000B' || c == '\u001C' || c == '\u001D' || c == '\u001E' || c == '\u001F' || (c > '\u007F' && Character.isWhitespace(c)))) { return i; } ParsingLocatorUtil.countChar(locator, c); i++; } return -1; } static int findNextNonOperatorCharWildcard( final char[] text, final int offset, final int maxi, final int[] locator) { char c; int i = offset; int n = (maxi - offset); while (n-- != 0) { c = text[i]; if (c != '=' && !(c == ' ' || c == '\n' || c == '\t' || c == '\r' || c == '\f' || c == '\u000B' || c == '\u001C' || c == '\u001D' || c == '\u001E' || c == '\u001F' || (c > '\u007F' && Character.isWhitespace(c)))) { return i; } ParsingLocatorUtil.countChar(locator, c); i++; } return -1; } static int findNextAnyCharAvoidQuotesWildcard( final char[] text, final int offset, final int maxi, final int[] locator) { boolean inQuotes = false; boolean inApos = false; char c; int i = offset; int n = (maxi - offset); while (n-- != 0) { c = text[i]; if (!inApos && c == '"') { if (inQuotes) { ParsingLocatorUtil.countChar(locator, c); i++; return (i < maxi ? i : -1); } inQuotes = true; } else if (!inQuotes && c == '\'') { if (inApos) { ParsingLocatorUtil.countChar(locator, c); i++; return (i < maxi ? i : -1); } inApos = true; } else if (!inQuotes && !inApos) { return i; } ParsingLocatorUtil.countChar(locator, c); i++; } return -1; } }