package org.basex.util;
import static org.basex.core.Text.*;
import static org.basex.util.Token.*;
/**
* Abstract class for parsing various inputs, such as database commands or queries.
*
* @author BaseX Team 2005-17, BSD License
* @author Christian Gruen
*/
public class InputParser {
/** Parsing exception. */
private static final String FOUND = ", found '%'";
/** Input to be parsed. */
public final String input;
/** Query length. */
public final int length;
/** File reference. */
public String file;
/** Current input position. */
public int pos;
/** Marked input position. */
public int mark;
/**
* Constructor.
* @param input input
*/
public InputParser(final String input) {
this.input = input;
length = input.length();
}
/**
* Checks if more characters are found.
* @return current character
*/
public final boolean more() {
return pos < length;
}
/**
* Returns the current character.
* @return current character
*/
public final char curr() {
final int i = pos;
return i < length ? input.charAt(i) : 0;
}
/**
* Checks if the current character equals the specified one.
* @param ch character to be checked
* @return result of check
*/
public final boolean curr(final int ch) {
final int i = pos;
return i < length && ch == input.charAt(i);
}
/**
* Remembers the current position.
*/
protected final void mark() {
mark = pos;
}
/**
* Returns the next character.
* @return next character, or {@code 0} if string is exhausted
*/
protected final char next() {
final int i = pos + 1;
return i < length ? input.charAt(i) : 0;
}
/**
* Consumes the next character.
* @return next character, or {@code 0} if string is exhausted
*/
public final char consume() {
return pos < length ? input.charAt(pos++) : 0;
}
/**
* Peeks forward and consumes the character if it equals the specified one.
* @param ch character to consume
* @return true if character was found
*/
public final boolean consume(final int ch) {
final int i = pos;
if(i >= length || ch != input.charAt(i)) return false;
++pos;
return true;
}
/**
* Checks if the specified character is a quote.
* @param ch character to be checked
* @return result
*/
protected static boolean quote(final int ch) {
return ch == '"' || ch == '\'';
}
/**
* Peeks forward and consumes the string if it equals the specified one.
* @param str string to consume
* @return true if string was found
*/
public final boolean consume(final String str) {
int i = pos;
final int l = str.length();
if(i + l > length) return false;
for(int s = 0; s < l; ++s) {
if(input.charAt(i++) != str.charAt(s)) return false;
}
pos = i;
return true;
}
/**
* Returns a "found" string, containing the current character.
* @return completion
*/
protected final byte[] found() {
return curr() == 0 ? EMPTY : Util.inf(FOUND, curr());
}
/**
* Returns the remaining, unscanned query substring.
* @return query substring
*/
protected final String rest() {
final StringBuilder sb = new StringBuilder();
final int pl = Math.min(length, pos + 15);
int p = pos;
for(; p < pl; p++) {
final char ch = input.charAt(p);
if(ch == '\n') break;
sb.append(ch);
}
return sb + (pl == length ? "" : DOTS);
}
/**
* Creates input information.
* @return input information
*/
public final InputInfo info() {
return new InputInfo(this);
}
}