Package xbird.xquery.operator.math

Source Code of xbird.xquery.operator.math.NumericOp$Exec

/*
* @(#)$Id: NumericOp.java 3619 2008-03-26 07:23:03Z yui $
*
* Copyright 2006-2008 Makoto YUI
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Contributors:
*     Makoto YUI - initial implementation
*/
package xbird.xquery.operator.math;

import static xbird.xquery.type.TypeTable.*;

import java.math.BigDecimal;

import xbird.util.string.StringUtils;
import xbird.xquery.DynamicError;
import xbird.xquery.XQueryException;
import xbird.xquery.dm.value.AtomicValue;
import xbird.xquery.dm.value.Item;
import xbird.xquery.dm.value.literal.*;
import xbird.xquery.meta.DynamicContext;
import xbird.xquery.operator.OverloadedFunction;
import xbird.xquery.type.AtomicType;
import xbird.xquery.type.Type;
import xbird.xquery.type.xs.*;

/**
*
* <DIV lang="en"></DIV>
* <DIV lang="ja"></DIV>
*
* @author Makoto YUI (yuin405+xbird@gmail.com)
*/
public abstract class NumericOp extends OverloadedFunction {

    protected static final int INT_INT = (INTEGER_TID << 4) + INTEGER_TID;
    protected static final int INT_FLOAT = (INTEGER_TID << 4) + FLOAT_TID;
    protected static final int INT_DOUBLE = (INTEGER_TID << 4) + DOUBLE_TID;
    protected static final int INT_DECIMAL = (INTEGER_TID << 4) + DECIMAL_TID;
    protected static final int FLOAT_INT = (FLOAT_TID << 4) + INTEGER_TID;
    protected static final int FLOAT_FLOAT = (FLOAT_TID << 4) + FLOAT_TID;
    protected static final int FLOAT_DOUBLE = (FLOAT_TID << 4) + DOUBLE_TID;
    protected static final int FLOAT_DECIMAL = (FLOAT_TID << 4) + DECIMAL_TID;
    protected static final int DOUBLE_INT = (DOUBLE_TID << 4) + INTEGER_TID;
    protected static final int DOUBLE_FLOAT = (DOUBLE_TID << 4) + FLOAT_TID;
    protected static final int DOUBLE_DOUBLE = (DOUBLE_TID << 4) + DOUBLE_TID;
    protected static final int DOUBLE_DECIMAL = (DOUBLE_TID << 4) + DECIMAL_TID;
    protected static final int DECIMAL_INT = (DECIMAL_TID << 4) + INTEGER_TID;
    protected static final int DECIMAL_FLOAT = (DECIMAL_TID << 4) + FLOAT_TID;
    protected static final int DECIMAL_DOUBLE = (DECIMAL_TID << 4) + DOUBLE_TID;
    protected static final int DECIMAL_DECIMAL = (DECIMAL_TID << 4) + DECIMAL_TID;

    public NumericOp(String funcName) {
        super(funcName);
    }

    protected static int combinedArgTypes(Item it1, Item it2) {
        int t1, t2;
        Type type1 = it1.getType();
        if(type1 instanceof AtomicType) {
            t1 = ((AtomicType) type1).getTypeId();
            if(t1 == UNTYPED_ATOMIC_TID) {
                t1 = DOUBLE_TID;
            }
        } else {
            t1 = UNRESOLVED;
        }
        Type type2 = it2.getType();
        if(type2 instanceof AtomicType) {
            t2 = ((AtomicType) type2).getTypeId();
            if(t2 == UNTYPED_ATOMIC_TID) {
                t2 = DOUBLE_TID;
            }
        } else {
            t2 = UNRESOLVED;
        }
        return (t1 << 4) + t2;
    }

    protected static double asDouble(final Item it, final DynamicContext dynEnv)
            throws XQueryException {
        final double d;
        if(it instanceof XDouble) {
            d = ((XDouble) it).getValue();
        } else if(it instanceof XNumber) {
            d = ((XNumber) it).asDouble();
        } else if(it instanceof AtomicValue) {
            XDouble v = ((AtomicValue) it).castAs(DoubleType.DOUBLE, dynEnv);
            d = v.getValue();
        } else {
            final String sv = DoubleType.DOUBLE.processWhitespace(it.stringValue());
            if(StringUtils.isNumber(sv)) {
                d = Double.parseDouble(sv);
            } else {
                throw new DynamicError("err:FORG0001", "Illegal value for xs:double: " + sv);
            }
        }
        return d;
    }

    protected static long asLong(final Item it, final DynamicContext dynEnv) throws XQueryException {
        final long l;
        if(it instanceof XInteger) {
            l = ((XInteger) it).getValue();
        } else if(it instanceof XNumber) {
            l = ((XNumber) it).asLong();
        } else if(it instanceof AtomicValue) {
            XInteger v = ((AtomicValue) it).castAs(LongType.LONG, dynEnv);
            l = v.getValue();
        } else {
            final String sv = LongType.LONG.processWhitespace(it.stringValue());
            if(StringUtils.isNumber(sv)) {
                l = Long.parseLong(sv);
            } else {
                throw new DynamicError("err:FORG0001", "Illegal value for xs:long: " + sv);
            }
        }
        return l;
    }

    protected static float asFloat(final Item it, final DynamicContext dynEnv)
            throws XQueryException {
        final float f;
        if(it instanceof XFloat) {
            f = ((XFloat) it).getValue();
        } else if(it instanceof XNumber) {
            f = ((XNumber) it).asFloat();
        } else if(it instanceof AtomicValue) {
            XFloat v = ((AtomicValue) it).castAs(FloatType.FLOAT, dynEnv);
            f = v.getValue();
        } else {
            final String sv = FloatType.FLOAT.processWhitespace(it.stringValue());
            if(StringUtils.isNumber(sv)) {
                f = Float.parseFloat(sv);
            } else {
                throw new DynamicError("err:FORG0001", "Illegal value for xs:long: " + sv);
            }
        }
        return f;
    }

    protected static BigDecimal asDecimal(final Item it, final DynamicContext dynEnv)
            throws XQueryException {
        final BigDecimal d;
        if(it instanceof XDecimal) {
            d = ((XDecimal) it).getValue();
        } else if(it instanceof XNumber) {
            d = ((XNumber) it).asDecimal();
        } else if(it instanceof AtomicValue) {
            XDecimal v = ((AtomicValue) it).castAs(DecimalType.DECIMAL, dynEnv);
            d = v.getValue();
        } else {
            final String sv = DecimalType.DECIMAL.processWhitespace(it.stringValue());
            if(StringUtils.isNumber(sv)) {
                d = new BigDecimal(sv);
            } else {
                throw new DynamicError("err:FORG0001", "Illegal value for xs:long: " + sv);
            }
        }
        return d;
    }

    protected static abstract class Exec {

        protected Exec() {}

        public abstract AtomicValue eval(DynamicContext dynEnv, Item v1, Item v2)
                throws XQueryException;

        public static long addL(final long a, final long b) throws DynamicError {
            final long sum = a + b;
            if(a < 0 && b < 0) {
                if(sum > 0) {
                    throw new DynamicError("err:FOAR0002", "long overflows: " + a + " + " + b
                            + " = " + sum);
                }
            } else if(a > 0 && b > 0) {
                if(sum < 0) {
                    throw new DynamicError("err:FOAR0002", "long overflows: " + a + " + " + b
                            + " = " + sum);
                }
            }
            return sum;
        }

        public static long subtractL(final long a, final long b) throws DynamicError {
            final long surplus = a - b;
            if(a < 0 && b > 0) {
                if(surplus > 0) {
                    throw new DynamicError("err:FOAR0002", "long overflows: " + a + " - " + b
                            + " = " + surplus);
                }
            } else if(a > 0 && b < 0) {
                if(surplus < 0) {
                    throw new DynamicError("err:FOAR0002", "long overflows: " + a + " - " + b
                            + " = " + surplus);
                }
            }
            return surplus;
        }

        public static long multiplyL(final long a, final long b) throws DynamicError {
            if(a == 0L) {
                return 0L;
            }
            final long product = a * b;
            final long b2 = product / a;
            if(b2 != b) {
                throw new DynamicError("err:FOAR0002", "long overflows: " + a + " * " + b + " = "
                        + product);
            }
            return product;
        }

        @Deprecated
        public static long divideL(final long a, final long b) throws DynamicError {
            final long divided = a / b;
            final long a2 = divided * b;
            if(a2 != a) {
                throw new DynamicError("err:FOAR0002", "long overflows: " + a + " / " + b + " = "
                        + divided);
            }
            return divided;
        }
    }

}
TOP

Related Classes of xbird.xquery.operator.math.NumericOp$Exec

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.