blob: 9ac37ca3f111265fdf3c95987b30e507459906ae [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*/
package org.apache.vxquery.runtime.functions.arithmetic;
import java.io.DataOutput;
import java.io.IOException;
import org.apache.vxquery.context.DynamicContext;
import org.apache.vxquery.datamodel.accessors.atomic.XSDatePointable;
import org.apache.vxquery.datamodel.accessors.atomic.XSDateTimePointable;
import org.apache.vxquery.datamodel.accessors.atomic.XSDecimalPointable;
import org.apache.vxquery.datamodel.accessors.atomic.XSTimePointable;
import org.apache.vxquery.datamodel.util.DateTime;
import org.apache.vxquery.datamodel.values.ValueTag;
import org.apache.vxquery.exceptions.ErrorCode;
import org.apache.vxquery.exceptions.SystemException;
import org.apache.hyracks.data.std.primitive.DoublePointable;
import org.apache.hyracks.data.std.primitive.FloatPointable;
import org.apache.hyracks.data.std.primitive.IntegerPointable;
import org.apache.hyracks.data.std.primitive.LongPointable;
import org.apache.hyracks.data.std.util.ArrayBackedValueStorage;
public class SubtractOperation extends AbstractArithmeticOperation {
protected final ArrayBackedValueStorage abvsInner1 = new ArrayBackedValueStorage();
protected final DataOutput dOutInner1 = abvsInner1.getDataOutput();
protected final ArrayBackedValueStorage abvsInner2 = new ArrayBackedValueStorage();
protected final DataOutput dOutInner2 = abvsInner2.getDataOutput();
private XSDecimalPointable decp1 = (XSDecimalPointable) XSDecimalPointable.FACTORY.createPointable();
private XSDecimalPointable decp2 = (XSDecimalPointable) XSDecimalPointable.FACTORY.createPointable();
private XSDateTimePointable ctxDatetimep = (XSDateTimePointable) XSDateTimePointable.FACTORY.createPointable();
private XSDateTimePointable datetimep1 = (XSDateTimePointable) XSDateTimePointable.FACTORY.createPointable();
private XSDateTimePointable datetimep2 = (XSDateTimePointable) XSDateTimePointable.FACTORY.createPointable();
private XSDateTimePointable datetimep3 = (XSDateTimePointable) XSDateTimePointable.FACTORY.createPointable();
private XSDateTimePointable datetimep4 = (XSDateTimePointable) XSDateTimePointable.FACTORY.createPointable();
public void operateDateDate(XSDatePointable datep1, XSDatePointable datep2, DynamicContext dCtx, DataOutput dOut)
throws SystemException, IOException {
abvsInner1.reset();
datetimep1.set(abvsInner1.getByteArray(), abvsInner1.getStartOffset(),
XSDateTimePointable.TYPE_TRAITS.getFixedLength());
datetimep1.setDateTime(datep1.getYear(), datep1.getMonth(), datep1.getDay(), 0, 0, 0, datep1.getTimezoneHour(),
datep1.getTimezoneMinute());
datetimep2.set(abvsInner1.getByteArray(),
abvsInner1.getStartOffset() + XSDateTimePointable.TYPE_TRAITS.getFixedLength(),
XSDateTimePointable.TYPE_TRAITS.getFixedLength());
datetimep2.setDateTime(datep2.getYear(), datep2.getMonth(), datep2.getDay(), 0, 0, 0, datep2.getTimezoneHour(),
datep2.getTimezoneMinute());
operateDatetimeDatetime(datetimep1, datetimep2, dCtx, dOut);
}
@Override
public void operateDateDTDuration(XSDatePointable datep1, LongPointable longp2, DataOutput dOut)
throws SystemException, IOException {
// Add duration.
abvsInner1.reset();
DateTime.normalizeDateTime(datep1.getYearMonth(), datep1.getDayTime() - longp2.getLong(),
datep1.getTimezoneHour(), datep1.getTimezoneMinute(), dOutInner1);
byte[] bytes = abvsInner1.getByteArray();
int startOffset = abvsInner1.getStartOffset() + 1;
// Convert to date.
bytes[startOffset + XSDatePointable.TIMEZONE_HOUR_OFFSET] = bytes[startOffset
+ XSDateTimePointable.TIMEZONE_HOUR_OFFSET];
bytes[startOffset + XSDatePointable.TIMEZONE_MINUTE_OFFSET] = bytes[startOffset
+ XSDateTimePointable.TIMEZONE_MINUTE_OFFSET];
dOut.write(ValueTag.XS_DATE_TAG);
dOut.write(bytes, startOffset, XSDatePointable.TYPE_TRAITS.getFixedLength());
}
@Override
public void operateDatetimeDatetime(XSDateTimePointable datetimep1, XSDateTimePointable datetimep2,
DynamicContext dCtx, DataOutput dOut) throws SystemException, IOException {
dCtx.getCurrentDateTime(ctxDatetimep);
abvsInner2.reset();
DateTime.getUtcTimezoneDateTime(datetimep1, ctxDatetimep, dOutInner2);
int startOffset1 = abvsInner2.getStartOffset() + 1;
datetimep3.set(abvsInner2.getByteArray(), startOffset1, XSDateTimePointable.TYPE_TRAITS.getFixedLength());
DateTime.getUtcTimezoneDateTime(datetimep2, ctxDatetimep, dOutInner2);
int startOffset2 = startOffset1 + 1 + XSDateTimePointable.TYPE_TRAITS.getFixedLength();
datetimep4.set(abvsInner2.getByteArray(), startOffset2, XSDateTimePointable.TYPE_TRAITS.getFixedLength());
// Default
long year = datetimep3.getYear();
long month = datetimep3.getMonth();
long dayTime = datetimep3.getDayTime();
// Loop is based on the YYYY-MM-01 00:00:00
long[] monthDayLimits = (DateTime.isLeapYear(year) ? DateTime.DAYS_OF_MONTH_LEAP : DateTime.DAYS_OF_MONTH_ORDI);
while (year != datetimep4.getYear() || (year == datetimep4.getYear() && month != datetimep4.getMonth())) {
if (year > datetimep4.getYear()) {
if (month == 1) {
--year;
monthDayLimits = (DateTime.isLeapYear(year) ? DateTime.DAYS_OF_MONTH_LEAP
: DateTime.DAYS_OF_MONTH_ORDI);
month = 12;
dayTime += monthDayLimits[(int) month - 1] * DateTime.CHRONON_OF_DAY;
} else {
--month;
dayTime += monthDayLimits[(int) month - 1] * DateTime.CHRONON_OF_DAY;
}
} else if (year < datetimep4.getYear()) {
if (month == 12) {
month = 1;
++year;
monthDayLimits = (DateTime.isLeapYear(year) ? DateTime.DAYS_OF_MONTH_LEAP
: DateTime.DAYS_OF_MONTH_ORDI);
dayTime -= monthDayLimits[(int) month - 1] * DateTime.CHRONON_OF_DAY;
} else {
++month;
dayTime -= monthDayLimits[(int) month - 1] * DateTime.CHRONON_OF_DAY;
}
} else {
if (month > datetimep4.getMonth()) {
--month;
dayTime += monthDayLimits[(int) month - 1] * DateTime.CHRONON_OF_DAY;
} else if (month < datetimep4.getMonth()) {
++month;
dayTime -= monthDayLimits[(int) month - 1] * DateTime.CHRONON_OF_DAY;
}
}
}
dayTime -= datetimep4.getDayTime();
// Save.
dOut.write(ValueTag.XS_DAY_TIME_DURATION_TAG);
dOut.writeLong(dayTime);
}
@Override
public void operateDatetimeDTDuration(XSDateTimePointable datetimep, LongPointable longp, DataOutput dOut)
throws SystemException, IOException {
// Add duration.
abvsInner1.reset();
DateTime.normalizeDateTime(datetimep.getYearMonth(), datetimep.getDayTime() - longp.getLong(),
datetimep.getTimezoneHour(), datetimep.getTimezoneMinute(), dOutInner1);
dOut.write(ValueTag.XS_DATETIME_TAG);
dOut.write(abvsInner1.getByteArray(), abvsInner1.getStartOffset() + 1,
XSDateTimePointable.TYPE_TRAITS.getFixedLength());
}
@Override
public void operateDatetimeYMDuration(XSDateTimePointable datetimep, IntegerPointable intp, DataOutput dOut)
throws SystemException, IOException {
// Add duration.
abvsInner1.reset();
DateTime.normalizeDateTime(datetimep.getYearMonth() - intp.getInteger(), datetimep.getDayTime(),
datetimep.getTimezoneHour(), datetimep.getTimezoneMinute(), dOutInner1);
dOut.write(ValueTag.XS_DATETIME_TAG);
dOut.write(abvsInner1.getByteArray(), abvsInner1.getStartOffset() + 1,
XSDateTimePointable.TYPE_TRAITS.getFixedLength());
}
@Override
public void operateDateYMDuration(XSDatePointable datep, IntegerPointable intp, DataOutput dOut)
throws SystemException, IOException {
// Add duration.
abvsInner1.reset();
DateTime.normalizeDateTime(datep.getYearMonth() - intp.getInteger(), datep.getDayTime(),
datep.getTimezoneHour(), datep.getTimezoneMinute(), dOutInner1);
byte[] bytes = abvsInner1.getByteArray();
int startOffset = abvsInner1.getStartOffset() + 1;
// Convert to date.
bytes[startOffset + XSDatePointable.TIMEZONE_HOUR_OFFSET] = bytes[startOffset
+ XSDateTimePointable.TIMEZONE_HOUR_OFFSET];
bytes[startOffset + XSDatePointable.TIMEZONE_MINUTE_OFFSET] = bytes[startOffset
+ XSDateTimePointable.TIMEZONE_MINUTE_OFFSET];
dOut.write(ValueTag.XS_DATE_TAG);
dOut.write(bytes, startOffset, XSDatePointable.TYPE_TRAITS.getFixedLength());
}
@Override
public void operateDecimalDecimal(XSDecimalPointable decp1, XSDecimalPointable decp2, DataOutput dOut)
throws SystemException, IOException {
// Prepare
long value1 = decp1.getDecimalValue();
long value2 = decp2.getDecimalValue();
byte place1 = decp1.getDecimalPlace();
byte place2 = decp2.getDecimalPlace();
byte count1 = decp1.getDigitCount();
byte count2 = decp2.getDigitCount();
// Convert to matching values
while (place1 > place2) {
++place2;
value2 *= 10;
++count2;
}
while (place1 < place2) {
++place1;
value1 *= 10;
++count1;
}
// Add
if (count1 > XSDecimalPointable.PRECISION || count2 > XSDecimalPointable.PRECISION) {
throw new SystemException(ErrorCode.XPDY0002);
}
value1 -= value2;
// Save
dOut.write(ValueTag.XS_DECIMAL_TAG);
dOut.writeByte(place1);
dOut.writeLong(value1);
}
@Override
public void operateDecimalDouble(XSDecimalPointable decp, DoublePointable doublep, DataOutput dOut)
throws SystemException, IOException {
double value = decp.doubleValue();
value -= doublep.doubleValue();
dOut.write(ValueTag.XS_DOUBLE_TAG);
dOut.writeDouble(value);
}
@Override
public void operateDecimalDTDuration(XSDecimalPointable decp, LongPointable longp, DataOutput dOut)
throws SystemException, IOException {
long value = operateDecimalInt(decp, longp.longValue());
dOut.write(ValueTag.XS_DAY_TIME_DURATION_TAG);
dOut.writeLong(value);
}
@Override
public void operateDecimalFloat(XSDecimalPointable decp, FloatPointable floatp, DataOutput dOut)
throws SystemException, IOException {
float value = decp.floatValue();
value -= floatp.floatValue();
dOut.write(ValueTag.XS_FLOAT_TAG);
dOut.writeFloat(value);
}
@Override
public void operateDecimalInteger(XSDecimalPointable decp1, LongPointable longp2, DataOutput dOut)
throws SystemException, IOException {
abvsInner1.reset();
decp2.set(abvsInner1.getByteArray(), abvsInner1.getStartOffset(),
XSDecimalPointable.TYPE_TRAITS.getFixedLength());
decp2.setDecimal(longp2.longValue(), (byte) 0);
operateDecimalDecimal(decp1, decp2, dOut);
}
@Override
public void operateDecimalYMDuration(XSDecimalPointable decp, IntegerPointable intp, DataOutput dOut)
throws SystemException, IOException {
int value = (int) operateDecimalInt(decp, intp.intValue());
dOut.write(ValueTag.XS_YEAR_MONTH_DURATION_TAG);
dOut.writeInt(value);
}
@Override
public void operateDoubleDecimal(DoublePointable doublep, XSDecimalPointable decp, DataOutput dOut)
throws SystemException, IOException {
double value = doublep.doubleValue();
value -= decp.doubleValue();
dOut.write(ValueTag.XS_DOUBLE_TAG);
dOut.writeDouble(value);
}
@Override
public void operateDoubleDouble(DoublePointable doublep, DoublePointable doublep2, DataOutput dOut)
throws SystemException, IOException {
double value = doublep.doubleValue();
value -= doublep2.doubleValue();
dOut.write(ValueTag.XS_DOUBLE_TAG);
dOut.writeDouble(value);
}
@Override
public void operateDoubleDTDuration(DoublePointable doublep, LongPointable longp, DataOutput dOut)
throws SystemException, IOException {
long value = doublep.intValue();
value -= longp.intValue();
dOut.write(ValueTag.XS_DAY_TIME_DURATION_TAG);
dOut.writeLong(value);
}
@Override
public void operateDoubleFloat(DoublePointable doublep, FloatPointable floatp, DataOutput dOut)
throws SystemException, IOException {
double value = doublep.doubleValue();
value -= floatp.doubleValue();
dOut.write(ValueTag.XS_DOUBLE_TAG);
dOut.writeDouble(value);
}
@Override
public void operateDoubleInteger(DoublePointable doublep, LongPointable longp, DataOutput dOut)
throws SystemException, IOException {
double value = doublep.doubleValue();
value -= longp.doubleValue();
dOut.write(ValueTag.XS_DOUBLE_TAG);
dOut.writeDouble(value);
}
@Override
public void operateDoubleYMDuration(DoublePointable doublep, IntegerPointable intp, DataOutput dOut)
throws SystemException, IOException {
int value = doublep.intValue();
value -= intp.intValue();
dOut.write(ValueTag.XS_YEAR_MONTH_DURATION_TAG);
dOut.writeInt(value);
}
@Override
public void operateDTDurationDate(LongPointable longp, XSDatePointable datep, DataOutput dOut)
throws SystemException, IOException {
throw new SystemException(ErrorCode.XPTY0004);
}
@Override
public void operateDTDurationDatetime(LongPointable longp, XSDateTimePointable datetimep, DataOutput dOut)
throws SystemException, IOException {
throw new SystemException(ErrorCode.XPTY0004);
}
@Override
public void operateDTDurationDecimal(LongPointable longp, XSDecimalPointable decp, DataOutput dOut)
throws SystemException, IOException {
long value = longp.longValue();
value -= decp.longValue();
dOut.write(ValueTag.XS_DAY_TIME_DURATION_TAG);
dOut.writeLong(value);
}
@Override
public void operateDTDurationDouble(LongPointable longp, DoublePointable doublep, DataOutput dOut)
throws SystemException, IOException {
long value = longp.longValue();
value -= doublep.longValue();
dOut.write(ValueTag.XS_DAY_TIME_DURATION_TAG);
dOut.writeLong(value);
}
@Override
public void operateDTDurationDTDuration(LongPointable longp1, LongPointable longp2, DataOutput dOut)
throws SystemException, IOException {
long value = longp1.longValue();
value -= longp2.longValue();
dOut.write(ValueTag.XS_DAY_TIME_DURATION_TAG);
dOut.writeLong(value);
}
@Override
public void operateDTDurationFloat(LongPointable longp, FloatPointable floatp, DataOutput dOut)
throws SystemException, IOException {
long value = longp.longValue();
value -= floatp.longValue();
dOut.write(ValueTag.XS_DAY_TIME_DURATION_TAG);
dOut.writeLong(value);
}
@Override
public void operateDTDurationInteger(LongPointable longp1, LongPointable longp2, DataOutput dOut)
throws SystemException, IOException {
long value = longp1.longValue();
value -= longp2.longValue();
dOut.write(ValueTag.XS_DAY_TIME_DURATION_TAG);
dOut.writeLong(value);
}
@Override
public void operateDTDurationTime(LongPointable longp, XSTimePointable timep, DataOutput dOut)
throws SystemException, IOException {
throw new SystemException(ErrorCode.XPTY0004);
}
@Override
public void operateFloatDecimal(FloatPointable floatp, XSDecimalPointable decp, DataOutput dOut)
throws SystemException, IOException {
float value = floatp.floatValue();
value -= decp.floatValue();
dOut.write(ValueTag.XS_FLOAT_TAG);
dOut.writeDouble(value);
}
@Override
public void operateFloatDouble(FloatPointable floatp, DoublePointable doublep, DataOutput dOut)
throws SystemException, IOException {
double value = floatp.doubleValue();
value -= doublep.doubleValue();
dOut.write(ValueTag.XS_DOUBLE_TAG);
dOut.writeDouble(value);
}
@Override
public void operateFloatDTDuration(FloatPointable floatp, LongPointable longp, DataOutput dOut)
throws SystemException, IOException {
long value = floatp.longValue();
value -= longp.longValue();
dOut.write(ValueTag.XS_DAY_TIME_DURATION_TAG);
dOut.writeLong(value);
}
@Override
public void operateFloatFloat(FloatPointable floatp, FloatPointable floatp2, DataOutput dOut)
throws SystemException, IOException {
float value = floatp.floatValue();
value -= floatp2.floatValue();
dOut.write(ValueTag.XS_FLOAT_TAG);
dOut.writeFloat(value);
}
@Override
public void operateFloatInteger(FloatPointable floatp, LongPointable longp, DataOutput dOut)
throws SystemException, IOException {
float value = floatp.floatValue();
value -= longp.floatValue();
dOut.write(ValueTag.XS_FLOAT_TAG);
dOut.writeFloat(value);
}
@Override
public void operateFloatYMDuration(FloatPointable floatp, IntegerPointable intp, DataOutput dOut)
throws SystemException, IOException {
int value = floatp.intValue();
value -= intp.intValue();
dOut.write(ValueTag.XS_YEAR_MONTH_DURATION_TAG);
dOut.writeInt(value);
}
@Override
public void operateIntegerDecimal(LongPointable longp, XSDecimalPointable decp, DataOutput dOut)
throws SystemException, IOException {
double value = longp.doubleValue();
value -= decp.doubleValue();
dOut.write(ValueTag.XS_DECIMAL_TAG);
dOut.writeDouble(value);
}
@Override
public void operateIntegerDouble(LongPointable longp, DoublePointable doublep, DataOutput dOut)
throws SystemException, IOException {
double value = longp.doubleValue();
value -= doublep.doubleValue();
dOut.write(ValueTag.XS_DOUBLE_TAG);
dOut.writeDouble(value);
}
@Override
public void operateIntegerDTDuration(LongPointable longp1, LongPointable longp2, DataOutput dOut)
throws SystemException, IOException {
long value = longp1.longValue();
value -= longp2.longValue();
dOut.write(ValueTag.XS_DAY_TIME_DURATION_TAG);
dOut.writeLong(value);
}
@Override
public void operateIntegerFloat(LongPointable longp, FloatPointable floatp, DataOutput dOut)
throws SystemException, IOException {
float value = longp.floatValue();
value -= floatp.floatValue();
dOut.write(ValueTag.XS_FLOAT_TAG);
dOut.writeFloat(value);
}
@Override
public void operateIntegerInteger(LongPointable longp, LongPointable longp2, DataOutput dOut)
throws SystemException, IOException {
long value = longp.getLong();
value -= longp2.getLong();
dOut.write(ValueTag.XS_INTEGER_TAG);
dOut.writeLong(value);
}
@Override
public void operateIntegerYMDuration(LongPointable longp, IntegerPointable intp, DataOutput dOut)
throws SystemException, IOException {
int value = longp.intValue();
value -= intp.intValue();
dOut.write(ValueTag.XS_YEAR_MONTH_DURATION_TAG);
dOut.writeInt(value);
}
@Override
public void operateTimeDTDuration(XSTimePointable timep1, LongPointable longp2, DataOutput dOut)
throws SystemException, IOException {
// Get time into a datetime value.
abvsInner1.reset();
datetimep1.set(abvsInner1.getByteArray(), abvsInner1.getStartOffset(),
XSDateTimePointable.TYPE_TRAITS.getFixedLength());
datetimep1.setDateTime(DateTime.TIME_DEFAULT_YEAR, DateTime.TIME_DEFAULT_MONTH, DateTime.TIME_DEFAULT_DAY,
timep1.getHour(), timep1.getMinute(), timep1.getMilliSecond(), timep1.getTimezoneHour(),
timep1.getTimezoneMinute());
// Subtract.
DateTime.normalizeDateTime(datetimep1.getYearMonth(), datetimep1.getDayTime() - longp2.getLong(),
timep1.getTimezoneHour(), timep1.getTimezoneMinute(), dOutInner1);
// Convert to time.
int startOffset = abvsInner1.getStartOffset() + 1 + XSDateTimePointable.HOUR_OFFSET;
dOut.write(ValueTag.XS_TIME_TAG);
dOut.write(abvsInner1.getByteArray(), startOffset, XSTimePointable.TYPE_TRAITS.getFixedLength());
}
@Override
public void operateTimeTime(XSTimePointable timep1, XSTimePointable timep2, DynamicContext dCtx, DataOutput dOut)
throws SystemException, IOException {
abvsInner1.reset();
datetimep1.set(abvsInner1.getByteArray(), abvsInner1.getStartOffset(),
XSDateTimePointable.TYPE_TRAITS.getFixedLength());
datetimep1.setDateTime(DateTime.TIME_DEFAULT_YEAR, DateTime.TIME_DEFAULT_MONTH, DateTime.TIME_DEFAULT_DAY,
timep1.getHour(), timep1.getMinute(), timep1.getMilliSecond(), timep1.getTimezoneHour(),
timep1.getTimezoneMinute());
datetimep2.set(abvsInner1.getByteArray(),
abvsInner1.getStartOffset() + XSDateTimePointable.TYPE_TRAITS.getFixedLength(),
XSDateTimePointable.TYPE_TRAITS.getFixedLength());
datetimep2.setDateTime(DateTime.TIME_DEFAULT_YEAR, DateTime.TIME_DEFAULT_MONTH, DateTime.TIME_DEFAULT_DAY,
timep2.getHour(), timep2.getMinute(), timep2.getMilliSecond(), timep2.getTimezoneHour(),
timep2.getTimezoneMinute());
operateDatetimeDatetime(datetimep1, datetimep2, dCtx, dOut);
}
@Override
public void operateYMDurationDate(IntegerPointable intp, XSDatePointable datep, DataOutput dOut)
throws SystemException, IOException {
throw new SystemException(ErrorCode.XPTY0004);
}
@Override
public void operateYMDurationDatetime(IntegerPointable intp, XSDateTimePointable datetimep, DataOutput dOut)
throws SystemException, IOException {
throw new SystemException(ErrorCode.XPTY0004);
}
@Override
public void operateYMDurationDecimal(IntegerPointable intp, XSDecimalPointable decp, DataOutput dOut)
throws SystemException, IOException {
int value = intp.intValue();
value -= decp.intValue();
dOut.write(ValueTag.XS_YEAR_MONTH_DURATION_TAG);
dOut.writeInt(value);
}
@Override
public void operateYMDurationDouble(IntegerPointable intp, DoublePointable doublep, DataOutput dOut)
throws SystemException, IOException {
int value = intp.intValue();
value -= doublep.intValue();
dOut.write(ValueTag.XS_YEAR_MONTH_DURATION_TAG);
dOut.writeInt(value);
}
@Override
public void operateYMDurationFloat(IntegerPointable intp, FloatPointable floatp, DataOutput dOut)
throws SystemException, IOException {
int value = intp.intValue();
value -= floatp.intValue();
dOut.write(ValueTag.XS_YEAR_MONTH_DURATION_TAG);
dOut.writeInt(value);
}
@Override
public void operateYMDurationInteger(IntegerPointable intp, LongPointable longp, DataOutput dOut)
throws SystemException, IOException {
int value = intp.intValue();
value -= longp.intValue();
dOut.write(ValueTag.XS_YEAR_MONTH_DURATION_TAG);
dOut.writeInt(value);
}
@Override
public void operateYMDurationYMDuration(IntegerPointable intp, IntegerPointable intp2, DataOutput dOut)
throws SystemException, IOException {
int value = intp.intValue();
value -= intp2.intValue();
dOut.write(ValueTag.XS_YEAR_MONTH_DURATION_TAG);
dOut.writeInt(value);
}
public long operateIntDecimal(long longValue, XSDecimalPointable decp2) throws SystemException, IOException {
abvsInner1.reset();
decp1.set(abvsInner1.getByteArray(), abvsInner1.getStartOffset(),
XSDecimalPointable.TYPE_TRAITS.getFixedLength());
decp1.setDecimal(longValue, (byte) 0);
// Prepare
long value1 = longValue;
long value2 = decp2.getDecimalValue();
byte place1 = 0;
byte place2 = decp2.getDecimalPlace();
byte count1 = decp1.getDigitCount();
byte count2 = decp2.getDigitCount();
// Convert to matching values
while (place1 > place2) {
++place2;
value2 *= 10;
++count2;
}
while (place1 < place2) {
++place1;
value1 *= 10;
++count1;
}
// Add
if (count1 > XSDecimalPointable.PRECISION || count2 > XSDecimalPointable.PRECISION) {
throw new SystemException(ErrorCode.XPDY0002);
}
value1 -= value2;
// Save
decp2.setDecimal(value1, place1);
return decp2.longValue();
}
public long operateDecimalInt(XSDecimalPointable decp1, long longValue) throws SystemException, IOException {
abvsInner2.reset();
decp2.set(abvsInner2.getByteArray(), abvsInner2.getStartOffset(),
XSDecimalPointable.TYPE_TRAITS.getFixedLength());
decp2.setDecimal(longValue, (byte) 0);
// Prepare
long value1 = decp1.getDecimalValue();
long value2 = decp2.getDecimalValue();
byte place1 = decp1.getDecimalPlace();
byte place2 = decp2.getDecimalPlace();
byte count1 = decp1.getDigitCount();
byte count2 = decp2.getDigitCount();
// Convert to matching values
while (place1 > place2) {
++place2;
value2 *= 10;
++count2;
}
while (place1 < place2) {
++place1;
value1 *= 10;
++count1;
}
// Add
if (count1 > XSDecimalPointable.PRECISION || count2 > XSDecimalPointable.PRECISION) {
throw new SystemException(ErrorCode.XPDY0002);
}
value1 -= value2;
// Save
decp2.setDecimal(value1, place1);
return decp2.longValue();
}
}