*/
public SequenceIterator iterate(XPathContext context) throws XPathException {
SequenceIterator seq = argument[0].iterate(context);
AtomicValue startVal0 = (AtomicValue)argument[1].evaluateItem(context);
NumericValue startVal = (NumericValue)startVal0;
if (argument.length == 2) {
long lstart;
if (startVal instanceof Int64Value) {
lstart = startVal.longValue();
if (lstart <= 1) {
return seq;
}
} else {
startVal = startVal.round();
if (startVal.compareTo(Int64Value.PLUS_ONE) <= 0) {
return seq;
} else if (startVal.compareTo(Int64Value.MAX_LONG) > 0) {
return EmptyIterator.getInstance();
} else if (startVal.isNaN()) {
return EmptyIterator.getInstance();
} else {
lstart = startVal.longValue();
}
}
if (lstart > Integer.MAX_VALUE) {
// we don't allow sequences longer than an this
return EmptyIterator.getInstance();
}
return TailIterator.make(seq, (int)lstart);
} else {
// There are three arguments
AtomicValue lengthVal0 = (AtomicValue)argument[2].evaluateItem(context);
NumericValue lengthVal = (NumericValue)lengthVal0;
if (startVal instanceof Int64Value && lengthVal instanceof Int64Value) {
long lstart = startVal.longValue();
if (lstart > Integer.MAX_VALUE) {
return EmptyIterator.getInstance();
}
long llength = lengthVal.longValue();
if (llength > Integer.MAX_VALUE) {
llength = Integer.MAX_VALUE;
}
if (llength < 1) {
return EmptyIterator.getInstance();
}
long lend = lstart + llength - 1;
if (lend < 1) {
return EmptyIterator.getInstance();
}
int start = (lstart < 1 ? 1 : (int)lstart);
return SubsequenceIterator.make(seq, start, (int)lend);
} else {
if (startVal.isNaN()) {
return EmptyIterator.getInstance();
}
if (startVal.compareTo(Int64Value.MAX_LONG) > 0) {
return EmptyIterator.getInstance();
}
startVal = startVal.round();
if (lengthVal.isNaN()) {
return EmptyIterator.getInstance();
}
lengthVal = lengthVal.round();
if (lengthVal.compareTo(Int64Value.ZERO) <= 0) {
return EmptyIterator.getInstance();
}
NumericValue rend = (NumericValue)ArithmeticExpression.compute(
startVal, Calculator.PLUS, lengthVal, context);
rend = (NumericValue)ArithmeticExpression.compute(
rend, Calculator.MINUS, Int64Value.PLUS_ONE, context);
if (rend.compareTo(Int64Value.ZERO) <= 0) {
return EmptyIterator.getInstance();
}
long lstart;
if (startVal.compareTo(Int64Value.PLUS_ONE) <= 0) {
lstart = 1;
} else {
lstart = startVal.longValue();
}
if (lstart > Integer.MAX_VALUE) {
return EmptyIterator.getInstance();
}
long lend;
if (rend.compareTo(Int64Value.MAX_LONG) >= 0) {
lend = Integer.MAX_VALUE;
} else {
lend = rend.longValue();
}
return SubsequenceIterator.make(seq, (int)lstart, (int)lend);
}
}