} else {
start = start.round();
// We need to be careful to handle cases such as plus/minus infinity and NaN
if (start.compareTo(IntegerValue.ZERO) <= 0) {
lstart = 0;
} else if (start.compareTo(new IntegerValue(slength)) > 0) {
// this works even where the string contains surrogate pairs,
// because the Java length is always >= the XPath length
return "";
} else if (start.isNaN()) {
return "";
} else {
try {
lstart = start.longValue();
} catch (XPathException err) {
// this shouldn't happen unless the string length exceeds the bounds
// of a long
throw new AssertionError("string length out of permissible range");
}
}
}
NumericValue end;
try {
end = start.arithmetic(Token.PLUS, len.round(), context);
} catch (XPathException e) {
throw new AssertionError("Unexpected arithmetic failure in substring");
}
long lend;
if (end instanceof IntegerValue) {
lend = ((IntegerValue)end).longValue();
} else {
// We need to be careful to handle cases such as plus/minus infinity and NaN
if (end.compareTo(IntegerValue.ZERO) <= 0) {
return "";
} else if (end.isNaN()) {
return "";
} else if (end.compareTo(new IntegerValue(slength)) > 0) {
// this works even where the string contains surrogate pairs,
// because the Java length is always >= the XPath length
lend = slength+1;
} else {
try {