package org.basex.query.util;
import java.io.IOException;
import java.util.Arrays;
import org.basex.core.Text;
import org.basex.data.ExprInfo;
import org.basex.io.serial.Serializer;
import org.basex.query.QueryException;
import org.basex.query.item.QNm;
import org.basex.util.Array;
/**
* Variable stack.
*
* @author BaseX Team 2005-12, BSD License
* @author Christian Gruen
*/
public final class VarStack extends ExprInfo {
/** Variable expressions. */
public Var[] vars;
/** Number of stored variables. */
public int size;
/**
* Default constructor.
*/
public VarStack() {
this(4);
}
/**
* Default constructor.
* @param c initial capacity
*/
public VarStack(final int c) {
vars = new Var[c];
}
/**
* Adds or replaces the specified variable.
* @param v variable
*/
public void update(final Var v) {
final int i = indexOf(v);
if(i == -1) add(v);
else vars[i] = v;
}
/**
* Adds the specified variable.
* @param v variable
*/
public void add(final Var v) {
if(size == vars.length) vars = Arrays.copyOf(vars, Array.newSize(size));
vars[size++] = v;
}
/**
* Returns a variable with the specified name; should only be
* used while parsing because it ignores ids of variables.
* @param name variable name
* @return variable
*/
public Var get(final QNm name) {
for(int i = size; i-- > 0;) if(name.eq(vars[i].name)) return vars[i];
return null;
}
/**
* Returns a variable with the same id.
* @param v variable
* @return variable
*/
public Var get(final Var v) {
final int i = indexOf(v);
return i == -1 ? null : vars[i];
}
/**
* Returns the index of a variable with the same id, or {@code -1}.
* @param v variable
* @return index
*/
private int indexOf(final Var v) {
for(int s = size - 1; s >= 0; s--) if(v.is(vars[s])) return s;
return -1;
}
/**
* Checks if the given variable is in this list.
* @param v variable
* @return {@code true} if the variable was found, {@code false} otherwise
*/
public boolean contains(final Var v) {
return indexOf(v) != -1;
}
/**
* Checks if none of the variables contains an updating expression.
* @throws QueryException query exception
*/
public void checkUp() throws QueryException {
for(int i = 0; i < size; ++i) vars[i].checkUp();
}
@Override
public void plan(final Serializer ser) throws IOException {
if(size == 0) return;
ser.openElement(this);
for(int i = 0; i < size; ++i) vars[i].plan(ser);
ser.closeElement();
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder();
for(int i = 0; i < size; ++i)
sb.append((i == 0 ? "" : Text.NL) + i + Text.COLS + vars[i]);
return sb.toString();
}
}