1 package net.sf.saxon.functions; 2 import net.sf.saxon.expr.PositionIterator; 3 import net.sf.saxon.expr.TailExpression; 4 import net.sf.saxon.expr.XPathContext; 5 import net.sf.saxon.expr.Token; 6 import net.sf.saxon.om.SequenceIterator; 7 import net.sf.saxon.om.EmptyIterator; 8 import net.sf.saxon.trans.XPathException; 9 import net.sf.saxon.type.ItemType; 10 import net.sf.saxon.value.AtomicValue; 11 import net.sf.saxon.value.NumericValue; 12 import net.sf.saxon.value.IntegerValue; 13 14 17 18 19 public class Subsequence extends SystemFunction { 20 21 25 29 30 public ItemType getItemType() { 31 return argument[0].getItemType(); 32 } 33 34 39 40 public int computeSpecialProperties() { 41 return argument[0].getSpecialProperties(); 42 } 43 44 47 48 public SequenceIterator iterate(XPathContext context) throws XPathException { 49 SequenceIterator seq = argument[0].iterate(context); 50 AtomicValue startVal0 = (AtomicValue)argument[1].evaluateItem(context); 51 NumericValue startVal = (NumericValue)startVal0.getPrimitiveValue(); 52 53 if (argument.length == 2) { 54 long lstart; 55 if (startVal instanceof IntegerValue) { 56 lstart = ((IntegerValue)startVal).longValue(); 57 if (lstart <= 1) { 58 return seq; 59 } 60 } else { 61 startVal = startVal.round(); 62 if (startVal.compareTo(IntegerValue.PLUS_ONE) <= 0) { 63 return seq; 64 } else if (startVal.compareTo(IntegerValue.MAX_LONG) > 0) { 65 return EmptyIterator.getInstance(); 66 } else if (startVal.isNaN()) { 67 return EmptyIterator.getInstance(); 68 } else { 69 lstart = startVal.longValue(); 70 } 71 } 72 73 if (lstart > Integer.MAX_VALUE) { 74 return EmptyIterator.getInstance(); 76 } 77 78 return new TailExpression.TailIterator(seq, (int)lstart); 79 80 } else { 81 82 84 AtomicValue lengthVal0 = (AtomicValue)argument[2].evaluateItem(context); 85 NumericValue lengthVal = (NumericValue)lengthVal0.getPrimitiveValue(); 86 87 if (startVal instanceof IntegerValue && lengthVal instanceof IntegerValue) { 88 long lstart = ((IntegerValue)startVal).longValue(); 89 if (lstart > Integer.MAX_VALUE) { 90 return EmptyIterator.getInstance(); 91 } 92 long llength = ((IntegerValue)lengthVal).longValue(); 93 if (llength > Integer.MAX_VALUE) { 94 llength = Integer.MAX_VALUE; 95 } 96 if (llength < 1) { 97 return EmptyIterator.getInstance(); 98 } 99 long lend = lstart + llength - 1; 100 if (lend < 1) { 101 return EmptyIterator.getInstance(); 102 } 103 int start = (lstart < 1 ? 1 : (int)lstart); 104 return PositionIterator.make(seq, start, (int)lend); 105 } else { 106 if (startVal.isNaN()) { 107 return EmptyIterator.getInstance(); 108 } 109 if (startVal.compareTo(IntegerValue.MAX_LONG) > 0) { 110 return EmptyIterator.getInstance(); 111 } 112 startVal = startVal.round(); 113 114 if (lengthVal.isNaN()) { 115 return EmptyIterator.getInstance(); 116 } 117 lengthVal = lengthVal.round(); 118 119 if (lengthVal.compareTo(IntegerValue.ZERO) <= 0) { 120 return EmptyIterator.getInstance(); 121 } 122 NumericValue rend = startVal 123 .arithmetic(Token.PLUS, lengthVal, context) 124 .arithmetic(Token.MINUS, IntegerValue.PLUS_ONE, context); 125 if (rend.compareTo(IntegerValue.ZERO) <= 0) { 126 return EmptyIterator.getInstance(); 127 } 128 129 long lstart; 130 if (startVal.compareTo(IntegerValue.PLUS_ONE) <= 0) { 131 lstart = 1; 132 } else { 133 lstart = startVal.longValue(); 134 } 135 if (lstart > Integer.MAX_VALUE) { 136 return EmptyIterator.getInstance(); 137 } 138 139 long lend; 140 if (rend.compareTo(IntegerValue.MAX_LONG) >= 0) { 141 lend = Integer.MAX_VALUE; 142 } else { 143 lend = rend.longValue(); 144 } 145 return PositionIterator.make(seq, (int)lstart, (int)lend); 146 147 } 148 } 149 } 150 151 } 152 153 | Popular Tags |