All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.sf.saxon.expr.CastExpression Maven / Gradle / Ivy

package net.sf.saxon.expr;
import net.sf.saxon.om.*;
import net.sf.saxon.sort.IntHashMap;
import net.sf.saxon.trace.ExpressionPresenter;
import net.sf.saxon.trans.XPathException;
import net.sf.saxon.type.*;
import net.sf.saxon.value.*;

/**
* Cast Expression: implements "cast as data-type ( expression )". It also allows an internal
* cast, which has the same semantics as a user-requested cast, but maps an empty sequence to
* an empty sequence.
*/

public final class CastExpression extends UnaryExpression  {

    static IntHashMap castingTable = new IntHashMap(25);

    static void addAllowedCasts(int source, int[] target) {
        castingTable.put(source, target);
    }

    /**
     * The following data represents all the "Y" and "M" entries in section 17.1 of the F+O spec.
     */

    static {
        final int uat = StandardNames.XS_UNTYPED_ATOMIC;
        final int str = StandardNames.XS_STRING;
        final int flt = StandardNames.XS_FLOAT;
        final int dbl = StandardNames.XS_DOUBLE;
        final int dec = StandardNames.XS_DECIMAL;
        final int ing = StandardNames.XS_INTEGER;
        final int dur = StandardNames.XS_DURATION;
        final int ymd = StandardNames.XS_YEAR_MONTH_DURATION;
        final int dtd = StandardNames.XS_DAY_TIME_DURATION;
        final int dtm = StandardNames.XS_DATE_TIME;
        final int tim = StandardNames.XS_TIME;
        final int dat = StandardNames.XS_DATE;
        final int gym = StandardNames.XS_G_YEAR_MONTH;
        final int gyr = StandardNames.XS_G_YEAR;
        final int gmd = StandardNames.XS_G_MONTH_DAY;
        final int gdy = StandardNames.XS_G_DAY;
        final int gmo = StandardNames.XS_G_MONTH;
        final int boo = StandardNames.XS_BOOLEAN;
        final int b64 = StandardNames.XS_BASE64_BINARY;
        final int hxb = StandardNames.XS_HEX_BINARY;
        final int uri = StandardNames.XS_ANY_URI;
        final int qnm = StandardNames.XS_QNAME;
        final int not = StandardNames.XS_NOTATION;

        final int[] t01 = {uat, str, flt, dbl, dec, ing, dur, ymd, dtd, dtm, tim, dat,
                          gym, gyr, gmd, gdy, gmo, boo, b64, hxb, uri};
        addAllowedCasts(uat, t01);
        final int[] t02 = {uat, str, flt, dbl, dec, ing, dur, ymd, dtd, dtm, tim, dat,
                          gym, gyr, gmd, gdy, gmo, boo, b64, hxb, uri, qnm, not};
        addAllowedCasts(str, t02);
        final int[] t03 = {uat, str, flt, dbl, dec, ing, boo};
        addAllowedCasts(flt, t03);
        addAllowedCasts(dbl, t03);
        addAllowedCasts(dec, t03);
        addAllowedCasts(ing, t03);
        final int[] t04 = {uat, str, dur, ymd, dtd};
        addAllowedCasts(dur, t04);
        addAllowedCasts(ymd, t04);
        addAllowedCasts(dtd, t04);
        final int[] t05 = {uat, str, dtm, tim, dat, gym, gyr, gmd, gdy, gmo};
        addAllowedCasts(dtm, t05);
        final int[] t06 = {uat, str, tim};
        addAllowedCasts(tim, t06);
        final int[] t07 = {uat, str, dtm, dat, gym, gyr, gmd, gdy, gmo};
        addAllowedCasts(dat, t07);
        final int[] t08 = {uat, str, gym};
        addAllowedCasts(gym, t08);
        final int[] t09 = {uat, str, gyr};
        addAllowedCasts(gyr, t09);
        final int[] t10 = {uat, str, gmd};
        addAllowedCasts(gmd, t10);
        final int[] t11 = {uat, str, gdy};
        addAllowedCasts(gdy, t11);
        final int[] t12 = {uat, str, gmo};
        addAllowedCasts(gmo, t12);
        final int[] t13 = {uat, str, flt, dbl, dec, ing, boo};
        addAllowedCasts(boo, t13);
        final int[] t14 = {uat, str, b64, hxb};
        addAllowedCasts(b64, t14);
        addAllowedCasts(hxb, t14);
        final int[] t15 = {uat, str, uri};
        addAllowedCasts(uri, t15);
        final int[] t16 = {uat, str, qnm};
        addAllowedCasts(qnm, t16);
        final int[] t17 = {uat, str, not};
        addAllowedCasts(not, t17);
    }

    /**
     * Determine whether casting from a source type to a target type is possible
     * @param source a primitive type (one that has an entry in the casting table)
     * @param target another primitive type
     * @return true if the entry in the casting table is either "Y" (casting always succeeds)
     * or "M" (casting allowed but may fail for some values)
     */

    public static boolean isPossibleCast(int source, int target) {
        if (source == StandardNames.XS_ANY_ATOMIC_TYPE || source == Type.EMPTY) {
            return true;
        }
        if (source == StandardNames.XS_NUMERIC) {
            source = StandardNames.XS_DOUBLE;
        }
        int[] targets = (int[])castingTable.get(source);
        if (targets == null) {
            return false;
        }
        for (int i=0; i




© 2015 - 2025 Weber Informatics LLC | Privacy Policy