Package client.net.sf.saxon.ce.functions

Source Code of client.net.sf.saxon.ce.functions.Subsequence

package client.net.sf.saxon.ce.functions;
import client.net.sf.saxon.ce.expr.*;
import client.net.sf.saxon.ce.om.SequenceIterator;
import client.net.sf.saxon.ce.tree.iter.EmptyIterator;
import client.net.sf.saxon.ce.trans.XPathException;
import client.net.sf.saxon.ce.type.ItemType;
import client.net.sf.saxon.ce.type.TypeHierarchy;
import client.net.sf.saxon.ce.value.*;

/**
* Implements the XPath 2.0 subsequence()  function
*/


public class Subsequence extends SystemFunction {

    public Subsequence newInstance() {
        return new Subsequence();
    }

    /**
    * Determine the data type of the items in the sequence
    * @return the type of the argument
     * @param th the type hierarchy cache
     */

    public ItemType getItemType(TypeHierarchy th) {
        return argument[0].getItemType(th);
    }

    /**
    * Get the static properties of this expression (other than its type). The result is
    * bit-significant. These properties are used for optimizations. In general, if
    * property bit is set, it is true, but if it is unset, the value is unknown.
     */

    public int computeSpecialProperties() {
        return argument[0].getSpecialProperties();
    }


    /**
     * Determine the cardinality of the function.
     */

    public int computeCardinality() {
        if (getNumberOfArguments() == 3 && Literal.isConstantOne(argument[2])) {
            return StaticProperty.ALLOWS_ZERO_OR_ONE;
        }
        return argument[0].getCardinality() | StaticProperty.ALLOWS_ZERO;
    }

    /**
     * Perform optimisation of an expression and its subexpressions.
     * <p/>
     * <p>This method is called after all references to functions and variables have been resolved
     * to the declaration of the function or variable, and after all type checking has been done.</p>
     *
     * @param visitor         an expression visitor
     * @param contextItemType the static type of "." at the point where this expression is invoked.
     *                        The parameter is set to null if it is known statically that the context item will be undefined.
     *                        If the type of the context item is not known statically, the argument is set to
     *                        {@link client.net.sf.saxon.ce.type.Type#ITEM_TYPE}
     * @return the original expression, rewritten if appropriate to optimize execution
     * @throws client.net.sf.saxon.ce.trans.XPathException
     *          if an error is discovered during this phase
     *          (typically a type error)
     */

    public Expression optimize(ExpressionVisitor visitor, ItemType contextItemType) throws XPathException {
        Expression e = super.optimize(visitor, contextItemType);
        if (e != this) {
            return e;
        }
        return this;
    }

    /**
    * Evaluate the function to return an iteration of selected nodes.
    */

    public SequenceIterator iterate(XPathContext context) throws XPathException {
        SequenceIterator seq = argument[0].iterate(context);
        DoubleValue startVal = (DoubleValue)argument[1].evaluateItem(context);
        if (startVal.isNaN()) {
            return EmptyIterator.getInstance();
        }
        if (startVal.compareTo(IntegerValue.MAX_LONG) > 0) {
            return EmptyIterator.getInstance();
        }
        startVal = (DoubleValue)startVal.round();
        int lstart;
        if (startVal.compareTo(IntegerValue.PLUS_ONE) <= 0) {
            lstart = 1;
        } else {
            lstart = startVal.intValue();
        }

        int lend;
        if (argument.length == 2) {
            lend = Integer.MAX_VALUE;
        } else {
            DoubleValue lengthVal = (DoubleValue)argument[2].evaluateItem(context);
            if (lengthVal.isNaN()) {
                return EmptyIterator.getInstance();
            }
            lengthVal = (DoubleValue)lengthVal.round();

            if (lengthVal.compareTo(IntegerValue.ZERO) <= 0) {
                return EmptyIterator.getInstance();
            }

            NumericValue rend = (NumericValue)ArithmeticExpression.compute(
                    startVal, Calculator.PLUS, lengthVal, context);
            if (rend.isNaN()) {
                // Can happen when start = -INF, length = +INF
                return EmptyIterator.getInstance();
            }
            rend = (NumericValue)ArithmeticExpression.compute(
                    rend, Calculator.MINUS, IntegerValue.PLUS_ONE, context);
            if (rend.compareTo(IntegerValue.ZERO) <= 0) {
                return EmptyIterator.getInstance();
            }
            lend = rend.intValue();
        }
        return SubsequenceIterator.make(seq, lstart, lend);
    }

}

// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
// If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
// This Source Code Form is “Incompatible With Secondary Licenses”, as defined by the Mozilla Public License, v. 2.0.
TOP

Related Classes of client.net.sf.saxon.ce.functions.Subsequence

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.