package org.basex.util; import static org.basex.core.Text.*; import static org.basex.util.Token.*; import org.basex.io.IO; /** * Simple command and query parser; can be overwritten to support more complex * parsings. * * @author BaseX Team 2005-12, BSD License * @author Christian Gruen */ public abstract class InputParser { /** Parsing exception. */ private static final String FOUND = ", found '%'"; /** Input query. */ public final String query; /** Query length. */ public final int ql; /** Optional reference to query input. */ public IO file; /** Current query position. */ public int qp; /** Marked query position. */ public int qm; /** * Constructor. * @param q input query */ protected InputParser(final String q) { this(q, null); } /** * Constructor. * @param q input query * @param f file */ protected InputParser(final String q, final IO f) { query = q; ql = query.length(); file = f; } /** * Checks if more characters are found. * @return current character */ protected final boolean more() { return qp < ql; } /** * Returns the current character. * @return current character */ protected final char curr() { final int p = qp; return p < ql ? query.charAt(p) : 0; } /** * Checks if the current character equals the specified one. * @param ch character to be checked * @return result of check */ protected final boolean curr(final int ch) { final int p = qp; return p < ql && ch == query.charAt(p); } /** * Remembers the current position. */ protected final void mark() { qm = qp; } /** * Returns the next character. * @return result of check */ protected final char next() { final int p = qp + 1; return p < ql ? query.charAt(p) : 0; } /** * Returns next character. * @return next character */ protected final char consume() { return qp < ql ? query.charAt(qp++) : 0; } /** * Peeks forward and consumes the character if it equals the specified one. * @param ch character to consume * @return true if character was found */ protected final boolean consume(final int ch) { final int p = qp; if(p >= ql || ch != query.charAt(p)) return false; ++qp; return true; } /** * Checks if the specified character is a quote. * @param ch character to be checked * @return result */ protected static final 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 */ protected final boolean consume(final String str) { int p = qp; final int l = str.length(); if(p + l > ql) return false; for(int s = 0; s < l; ++s) { if(query.charAt(p++) != str.charAt(s)) return false; } qp = p; 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 int e = Math.min(ql, qp + 15); return query.substring(qp, e) + (e == ql ? "" : DOTS); } /** * Creates input information. * @return input information */ protected final InputInfo input() { return new InputInfo(this); } }