removed AreaEval.getValues (initial work for bug 45358)

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@690761 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Josh Micich 2008-08-31 19:08:36 +00:00
parent b944df7e56
commit 908e676d57
10 changed files with 315 additions and 307 deletions

View File

@ -61,13 +61,6 @@ public interface AreaEval extends ValueEval {
*/ */
boolean isColumn(); boolean isColumn();
/**
* The array of values in this area. Although the area
* maybe 1D (ie. isRow() or isColumn() returns true) or 2D
* the returned array is 1D.
*/
ValueEval[] getValues();
/** /**
* @return the ValueEval from within this area at the specified row and col index. Never * @return the ValueEval from within this area at the specified row and col index. Never
* <code>null</code> (possibly {@link BlankEval}). The specified indexes should be absolute * <code>null</code> (possibly {@link BlankEval}). The specified indexes should be absolute

View File

@ -77,11 +77,6 @@ abstract class AreaEvalBase implements AreaEval {
return _lastRow; return _lastRow;
} }
public final ValueEval[] getValues() {
// TODO - clone() - but some junits rely on not cloning at the moment
return _values;
}
public final ValueEval getValueAt(int row, int col) { public final ValueEval getValueAt(int row, int col) {
int rowOffsetIx = row - _firstRow; int rowOffsetIx = row - _firstRow;
int colOffsetIx = col - _firstColumn; int colOffsetIx = col - _firstColumn;

View File

@ -69,5 +69,11 @@ public class NumberEval implements NumericValueEval, StringValueEval {
} }
} }
} }
public final String toString() {
StringBuffer sb = new StringBuffer(64);
sb.append(getClass().getName()).append(" [");
sb.append(getStringValue());
sb.append("]");
return sb.toString();
}
} }

View File

@ -1,28 +1,28 @@
/* /* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one or more Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0 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 not use this file except in compliance with
* the License. You may obtain a copy of the License at 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.
*/
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.poi.hssf.record.formula.functions; package org.apache.poi.hssf.record.formula.functions;
import org.apache.poi.hssf.record.formula.eval.AreaEval; import org.apache.poi.hssf.record.formula.eval.AreaEval;
import org.apache.poi.hssf.record.formula.eval.ErrorEval; import org.apache.poi.hssf.record.formula.eval.ErrorEval;
import org.apache.poi.hssf.record.formula.eval.Eval; import org.apache.poi.hssf.record.formula.eval.Eval;
import org.apache.poi.hssf.record.formula.eval.NumberEval; import org.apache.poi.hssf.record.formula.eval.EvaluationException;
import org.apache.poi.hssf.record.formula.eval.RefEval; import org.apache.poi.hssf.record.formula.eval.OperandResolver;
import org.apache.poi.hssf.record.formula.eval.ValueEval;
/** /**
* Implementation for the Excel function INDEX<p/> * Implementation for the Excel function INDEX<p/>
@ -51,15 +51,23 @@ public final class Index implements Function {
return ErrorEval.VALUE_INVALID; return ErrorEval.VALUE_INVALID;
} }
Eval firstArg = args[0]; Eval firstArg = args[0];
if(firstArg instanceof AreaEval) { if(!(firstArg instanceof AreaEval)) {
AreaEval reference = (AreaEval) firstArg;
int rowIx = 0; // else the other variation of this function takes an array as the first argument
int columnIx = 0; // it seems like interface 'ArrayEval' does not even exist yet
int areaIx = 0;
throw new RuntimeException("Incomplete code - cannot handle first arg of type ("
+ firstArg.getClass().getName() + ")");
}
AreaEval reference = (AreaEval) firstArg;
int rowIx = 0;
int columnIx = 0;
int areaIx = 0;
try {
switch(nArgs) { switch(nArgs) {
case 4: case 4:
areaIx = convertIndexArgToZeroBase(args[3]); areaIx = convertIndexArgToZeroBase(args[3], srcCellRow, srcCellCol);
throw new RuntimeException("Incomplete code" + throw new RuntimeException("Incomplete code" +
" - don't know how to support the 'area_num' parameter yet)"); " - don't know how to support the 'area_num' parameter yet)");
// Excel expression might look like this "INDEX( (A1:B4, C3:D6, D2:E5 ), 1, 2, 3) // Excel expression might look like this "INDEX( (A1:B4, C3:D6, D2:E5 ), 1, 2, 3)
@ -68,41 +76,41 @@ public final class Index implements Function {
// The formula parser doesn't seem to support this yet. Not sure if the evaluator does either // The formula parser doesn't seem to support this yet. Not sure if the evaluator does either
case 3: case 3:
columnIx = convertIndexArgToZeroBase(args[2]); columnIx = convertIndexArgToZeroBase(args[2], srcCellRow, srcCellCol);
case 2: case 2:
rowIx = convertIndexArgToZeroBase(args[1]); rowIx = convertIndexArgToZeroBase(args[1], srcCellRow, srcCellCol);
break; break;
default: default:
// too many arguments // too many arguments
return ErrorEval.VALUE_INVALID; return ErrorEval.VALUE_INVALID;
} }
return getValueFromArea(reference, rowIx, columnIx);
int nColumns = reference.getLastColumn()-reference.getFirstColumn()+1; } catch (EvaluationException e) {
int index = rowIx * nColumns + columnIx; return e.getErrorEval();
return reference.getValues()[index];
} }
// else the other variation of this function takes an array as the first argument
// it seems like interface 'ArrayEval' does not even exist yet
throw new RuntimeException("Incomplete code - cannot handle first arg of type ("
+ firstArg.getClass().getName() + ")");
} }
private static ValueEval getValueFromArea(AreaEval ae, int rowIx, int columnIx) throws EvaluationException {
int width = ae.getWidth();
int height = ae.getHeight();
// Slightly irregular logic for bounds checking errors
if (rowIx >= height || columnIx >= width) {
throw new EvaluationException(ErrorEval.REF_INVALID);
}
if (rowIx < 0 || columnIx < 0) {
throw new EvaluationException(ErrorEval.VALUE_INVALID);
}
return ae.getRelativeValue(rowIx, columnIx);
}
/** /**
* takes a NumberEval representing a 1-based index and returns the zero-based int value * takes a NumberEval representing a 1-based index and returns the zero-based int value
*/ */
private static int convertIndexArgToZeroBase(Eval ev) { private static int convertIndexArgToZeroBase(Eval arg, int srcCellRow, short srcCellCol) throws EvaluationException {
NumberEval ne;
if(ev instanceof RefEval) {
// TODO - write junit to justify this
RefEval re = (RefEval) ev;
ne = (NumberEval) re.getInnerValueEval();
} else {
ne = (NumberEval)ev;
}
return (int)ne.getNumberValue() - 1; ValueEval ev = OperandResolver.getSingleValue(arg, srcCellRow, srcCellCol);
int oneBasedVal = OperandResolver.coerceValueToInt(ev);
return oneBasedVal - 1;
} }
} }

View File

@ -126,30 +126,34 @@ public abstract class MultiOperandNumericFunction extends NumericFunction {
if (operand instanceof AreaEval) { if (operand instanceof AreaEval) {
AreaEval ae = (AreaEval) operand; AreaEval ae = (AreaEval) operand;
ValueEval[] values = ae.getValues();
DoubleList retval = new DoubleList(); DoubleList retval = new DoubleList();
for (int j=0, jSize=values.length; j<jSize; j++) { int width = ae.getWidth();
/* int height = ae.getHeight();
* TODO: For an AreaEval, we are constructing a RefEval for (int rrIx=0; rrIx<height; rrIx++) {
* per element. for (int rcIx=0; rcIx<width; rcIx++) {
* For now this is a tempfix solution since this may ValueEval ve1 = ae.getRelativeValue(rrIx, rcIx);
* require a more generic fix at the level of /*
* HSSFFormulaEvaluator where we store an array * TODO: For an AreaEval, we are constructing a RefEval
* of RefEvals as the "values" array. * per element.
*/ * For now this is a tempfix solution since this may
RefEval re = new Ref2DEval(null, values[j]); * require a more generic fix at the level of
ValueEval ve = singleOperandEvaluate(re, srcRow, srcCol); * HSSFFormulaEvaluator where we store an array
* of RefEvals as the "values" array.
if (ve instanceof NumericValueEval) { */
NumericValueEval nve = (NumericValueEval) ve; RefEval re = new Ref2DEval(null, ve1);
retval.add(nve.getNumberValue()); ValueEval ve = singleOperandEvaluate(re, srcRow, srcCol);
}
else if (ve instanceof BlankEval) { if (ve instanceof NumericValueEval) {
// note - blanks are ignored, so returned array will be smaller. NumericValueEval nve = (NumericValueEval) ve;
} retval.add(nve.getNumberValue());
else { }
return null; // indicate to calling subclass that error occurred else if (ve instanceof BlankEval) {
} // note - blanks are ignored, so returned array will be smaller.
}
else {
return null; // indicate to calling subclass that error occurred
}
}
} }
return retval.toArray(); return retval.toArray();
} }

View File

@ -1,22 +1,23 @@
/* /* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one or more Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0 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 not use this file except in compliance with
* the License. You may obtain a copy of the License at the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0 http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and See the License for the specific language governing permissions and
* limitations under the License. limitations under the License.
*/ ==================================================================== */
package org.apache.poi.hssf.record.formula.functions; package org.apache.poi.hssf.record.formula.functions;
/** /**
* Implementation of Excel function SUMX2MY2()<p/> * Implementation of Excel function SUMX2MY2()<p/>
* *
@ -30,7 +31,13 @@ package org.apache.poi.hssf.record.formula.functions;
*/ */
public final class Sumx2my2 extends XYNumericFunction { public final class Sumx2my2 extends XYNumericFunction {
protected double evaluate(double[] xArray, double[] yArray) { private static final Accumulator XSquaredMinusYSquaredAccumulator = new Accumulator() {
return MathX.sumx2my2(xArray, yArray); public double accumulate(double x, double y) {
} return x * x - y * y;
}
};
protected Accumulator createAccumulator() {
return XSquaredMinusYSquaredAccumulator;
}
} }

View File

@ -1,22 +1,23 @@
/* /* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one or more Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0 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 not use this file except in compliance with
* the License. You may obtain a copy of the License at the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0 http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and See the License for the specific language governing permissions and
* limitations under the License. limitations under the License.
*/ ==================================================================== */
package org.apache.poi.hssf.record.formula.functions; package org.apache.poi.hssf.record.formula.functions;
/** /**
* Implementation of Excel function SUMX2PY2()<p/> * Implementation of Excel function SUMX2PY2()<p/>
* *
@ -30,7 +31,13 @@ package org.apache.poi.hssf.record.formula.functions;
*/ */
public final class Sumx2py2 extends XYNumericFunction { public final class Sumx2py2 extends XYNumericFunction {
protected double evaluate(double[] xArray, double[] yArray) { private static final Accumulator XSquaredPlusYSquaredAccumulator = new Accumulator() {
return MathX.sumx2py2(xArray, yArray); public double accumulate(double x, double y) {
} return x * x + y * y;
}
};
protected Accumulator createAccumulator() {
return XSquaredPlusYSquaredAccumulator;
}
} }

View File

@ -1,19 +1,19 @@
/* /* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one or more Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0 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 not use this file except in compliance with
* the License. You may obtain a copy of the License at the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0 http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and See the License for the specific language governing permissions and
* limitations under the License. limitations under the License.
*/ ==================================================================== */
package org.apache.poi.hssf.record.formula.functions; package org.apache.poi.hssf.record.formula.functions;
@ -30,7 +30,14 @@ package org.apache.poi.hssf.record.formula.functions;
*/ */
public final class Sumxmy2 extends XYNumericFunction { public final class Sumxmy2 extends XYNumericFunction {
protected double evaluate(double[] xArray, double[] yArray) { private static final Accumulator XMinusYSquaredAccumulator = new Accumulator() {
return MathX.sumxmy2(xArray, yArray); public double accumulate(double x, double y) {
} double xmy = x - y;
return xmy * xmy;
}
};
protected Accumulator createAccumulator() {
return XMinusYSquaredAccumulator;
}
} }

View File

@ -1,19 +1,19 @@
/* /* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one or more Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0 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 not use this file except in compliance with
* the License. You may obtain a copy of the License at the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0 http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and See the License for the specific language governing permissions and
* limitations under the License. limitations under the License.
*/ ==================================================================== */
package org.apache.poi.hssf.record.formula.functions; package org.apache.poi.hssf.record.formula.functions;
@ -24,180 +24,162 @@ import org.apache.poi.hssf.record.formula.eval.EvaluationException;
import org.apache.poi.hssf.record.formula.eval.NumberEval; import org.apache.poi.hssf.record.formula.eval.NumberEval;
import org.apache.poi.hssf.record.formula.eval.RefEval; import org.apache.poi.hssf.record.formula.eval.RefEval;
import org.apache.poi.hssf.record.formula.eval.ValueEval; import org.apache.poi.hssf.record.formula.eval.ValueEval;
import org.apache.poi.hssf.record.formula.functions.LookupUtils.ValueVector;
/** /**
* @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt; * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
* *
*/ */
public abstract class XYNumericFunction implements Function { public abstract class XYNumericFunction implements Function {
protected static final int X = 0;
protected static final int Y = 1;
protected static final class DoubleArrayPair {
private final double[] _xArray; private static abstract class ValueArray implements ValueVector {
private final double[] _yArray; private final int _size;
protected ValueArray(int size) {
public DoubleArrayPair(double[] xArray, double[] yArray) { _size = size;
_xArray = xArray;
_yArray = yArray;
} }
public double[] getXArray() { public ValueEval getItem(int index) {
return _xArray; if (index < 0 || index > _size) {
throw new IllegalArgumentException("Specified index " + index
+ " is outside range (0.." + (_size - 1) + ")");
}
return getItemInternal(index);
} }
public double[] getYArray() { protected abstract ValueEval getItemInternal(int index);
return _yArray; public final int getSize() {
return _size;
} }
} }
private static final class SingleCellValueArray extends ValueArray {
private final ValueEval _value;
public SingleCellValueArray(ValueEval value) {
super(1);
_value = value;
}
protected ValueEval getItemInternal(int index) {
return _value;
}
}
public final Eval evaluate(Eval[] args, int srcCellRow, short srcCellCol) { private static final class RefValueArray extends ValueArray {
if(args.length != 2) { private final RefEval _ref;
return ErrorEval.VALUE_INVALID; public RefValueArray(RefEval ref) {
} super(1);
_ref = ref;
double[][] values; }
protected ValueEval getItemInternal(int index) {
return _ref.getInnerValueEval();
}
}
private static final class AreaValueArray extends ValueArray {
private final AreaEval _ae;
private final int _width;
public AreaValueArray(AreaEval ae) {
super(ae.getWidth() * ae.getHeight());
_ae = ae;
_width = ae.getWidth();
}
protected ValueEval getItemInternal(int index) {
int rowIx = index / _width;
int colIx = index % _width;
return _ae.getRelativeValue(rowIx, colIx);
}
}
protected static interface Accumulator {
double accumulate(double x, double y);
}
/**
* Constructs a new instance of the Accumulator used to calculated this function
*/
protected abstract Accumulator createAccumulator();
public final Eval evaluate(Eval[] args, int srcCellRow, short srcCellCol) {
if (args.length != 2) {
return ErrorEval.VALUE_INVALID;
}
double result;
try { try {
values = getValues(args[0], args[1]); ValueVector vvX = createValueVector(args[0]);
ValueVector vvY = createValueVector(args[1]);
int size = vvX.getSize();
if (size == 0 || vvY.getSize() != size) {
return ErrorEval.NA;
}
result = evaluateInternal(vvX, vvY, size);
} catch (EvaluationException e) { } catch (EvaluationException e) {
return e.getErrorEval(); return e.getErrorEval();
} }
if (values==null if (Double.isNaN(result) || Double.isInfinite(result)) {
|| values[X] == null || values[Y] == null
|| values[X].length == 0 || values[Y].length == 0
|| values[X].length != values[Y].length) {
return ErrorEval.VALUE_INVALID;
}
double d = evaluate(values[X], values[Y]);
if (Double.isNaN(d) || Double.isInfinite(d)) {
return ErrorEval.NUM_ERROR; return ErrorEval.NUM_ERROR;
} }
return new NumberEval(d); return new NumberEval(result);
} }
protected abstract double evaluate(double[] xArray, double[] yArray);
/** private double evaluateInternal(ValueVector x, ValueVector y, int size)
* Returns a double array that contains values for the numeric cells throws EvaluationException {
* from among the list of operands. Blanks and Blank equivalent cells Accumulator acc = createAccumulator();
* are ignored. Error operands or cells containing operands of type
* that are considered invalid and would result in #VALUE! error in // error handling is as if the x is fully evaluated before y
* excel cause this function to return null. ErrorEval firstXerr = null;
*/ ErrorEval firstYerr = null;
private static double[][] getNumberArray(Eval[] xops, Eval[] yops) throws EvaluationException { boolean accumlatedSome = false;
double result = 0.0;
// check for errors first: size mismatch, value errors in x, value errors in y
for (int i = 0; i < size; i++) {
int nArrayItems = xops.length; ValueEval vx = x.getItem(i);
if(nArrayItems != yops.length) { ValueEval vy = y.getItem(i);
throw new EvaluationException(ErrorEval.NA); if (vx instanceof ErrorEval) {
} if (firstXerr == null) {
for (int i = 0; i < xops.length; i++) { firstXerr = (ErrorEval) vx;
Eval eval = xops[i]; continue;
if (eval instanceof ErrorEval) { }
throw new EvaluationException((ErrorEval) eval); }
if (vy instanceof ErrorEval) {
if (firstYerr == null) {
firstYerr = (ErrorEval) vy;
continue;
}
}
// only count pairs if both elements are numbers
if (vx instanceof NumberEval && vy instanceof NumberEval) {
accumlatedSome = true;
NumberEval nx = (NumberEval) vx;
NumberEval ny = (NumberEval) vy;
result += acc.accumulate(nx.getNumberValue(), ny.getNumberValue());
} else {
// all other combinations of value types are silently ignored
} }
} }
for (int i = 0; i < yops.length; i++) { if (firstXerr != null) {
Eval eval = yops[i]; throw new EvaluationException(firstXerr);
if (eval instanceof ErrorEval) {
throw new EvaluationException((ErrorEval) eval);
}
} }
if (firstYerr != null) {
double[] xResult = new double[nArrayItems]; throw new EvaluationException(firstYerr);
double[] yResult = new double[nArrayItems];
int count = 0;
for (int i=0, iSize=nArrayItems; i<iSize; i++) {
Eval xEval = xops[i];
Eval yEval = yops[i];
if (isNumberEval(xEval) && isNumberEval(yEval)) {
xResult[count] = getDoubleValue(xEval);
yResult[count] = getDoubleValue(yEval);
if (Double.isNaN(xResult[count]) || Double.isNaN(xResult[count])) {
throw new EvaluationException(ErrorEval.NUM_ERROR);
}
count++;
}
} }
if (!accumlatedSome) {
return new double[][] { throw new EvaluationException(ErrorEval.DIV_ZERO);
trimToSize(xResult, count),
trimToSize(yResult, count),
};
}
private static double[][] getValues(Eval argX, Eval argY) throws EvaluationException {
if (argX instanceof ErrorEval) {
throw new EvaluationException((ErrorEval) argX);
} }
if (argY instanceof ErrorEval) { return result;
throw new EvaluationException((ErrorEval) argY); }
private static ValueVector createValueVector(Eval arg) throws EvaluationException {
if (arg instanceof ErrorEval) {
throw new EvaluationException((ErrorEval) arg);
} }
if (arg instanceof AreaEval) {
Eval[] xEvals; return new AreaValueArray((AreaEval) arg);
Eval[] yEvals;
if (argX instanceof AreaEval) {
AreaEval ae = (AreaEval) argX;
xEvals = ae.getValues();
} else {
xEvals = new Eval[] { argX, };
} }
if (arg instanceof RefEval) {
if (argY instanceof AreaEval) { return new RefValueArray((RefEval) arg);
AreaEval ae = (AreaEval) argY;
yEvals = ae.getValues();
} else {
yEvals = new Eval[] { argY, };
} }
if (arg instanceof ValueEval) {
return getNumberArray(xEvals, yEvals); return new SingleCellValueArray((ValueEval) arg);
} }
throw new RuntimeException("Unexpected eval class (" + arg.getClass().getName() + ")");
private static double[] trimToSize(double[] arr, int len) { }
double[] tarr = arr;
if (arr.length > len) {
tarr = new double[len];
System.arraycopy(arr, 0, tarr, 0, len);
}
return tarr;
}
private static boolean isNumberEval(Eval eval) {
boolean retval = false;
if (eval instanceof NumberEval) {
retval = true;
}
else if (eval instanceof RefEval) {
RefEval re = (RefEval) eval;
ValueEval ve = re.getInnerValueEval();
retval = (ve instanceof NumberEval);
}
return retval;
}
private static double getDoubleValue(Eval eval) {
double retval = 0;
if (eval instanceof NumberEval) {
NumberEval ne = (NumberEval) eval;
retval = ne.getNumberValue();
}
else if (eval instanceof RefEval) {
RefEval re = (RefEval) eval;
ValueEval ve = re.getInnerValueEval();
retval = (ve instanceof NumberEval)
? ((NumberEval) ve).getNumberValue()
: Double.NaN;
}
else if (eval instanceof ErrorEval) {
retval = Double.NaN;
}
return retval;
}
} }

View File

@ -113,7 +113,6 @@ public final class TestSumproduct extends TestCase {
}; };
AreaEval aeA = EvalFactory.createAreaEval("A1:A2", aValues); AreaEval aeA = EvalFactory.createAreaEval("A1:A2", aValues);
AreaEval aeB = EvalFactory.createAreaEval("B1:B2", new ValueEval[2]); AreaEval aeB = EvalFactory.createAreaEval("B1:B2", new ValueEval[2]);
aeB.getValues()[1] = ErrorEval.REF_INVALID;
Eval[] args = { aeA, aeB, }; Eval[] args = { aeA, aeB, };
assertEquals(ErrorEval.REF_INVALID, invokeSumproduct(args)); assertEquals(ErrorEval.REF_INVALID, invokeSumproduct(args));