use spaces for indents

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1849067 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
PJ Fanning 2018-12-17 09:11:06 +00:00
parent 458b9e3aed
commit 9f7520e86f

View File

@ -39,187 +39,188 @@ import org.apache.poi.ss.formula.eval.ValueEval;
*/
public abstract class MultiOperandNumericFunction implements Function {
private final boolean _isReferenceBoolCounted;
private final boolean _isBlankCounted;
private final boolean _isReferenceBoolCounted;
private final boolean _isBlankCounted;
protected MultiOperandNumericFunction(boolean isReferenceBoolCounted, boolean isBlankCounted) {
_isReferenceBoolCounted = isReferenceBoolCounted;
_isBlankCounted = isBlankCounted;
}
static final double[] EMPTY_DOUBLE_ARRAY = { };
static final double[] EMPTY_DOUBLE_ARRAY = {};
private static class DoubleList {
private double[] _array;
private int _count;
private static class DoubleList {
private double[] _array;
private int _count;
public DoubleList() {
_array = new double[8];
_count = 0;
}
public DoubleList() {
_array = new double[8];
_count = 0;
}
public double[] toArray() {
if(_count < 1) {
return EMPTY_DOUBLE_ARRAY;
}
double[] result = new double[_count];
System.arraycopy(_array, 0, result, 0, _count);
return result;
}
public double[] toArray() {
if (_count < 1) {
return EMPTY_DOUBLE_ARRAY;
}
double[] result = new double[_count];
System.arraycopy(_array, 0, result, 0, _count);
return result;
}
private void ensureCapacity(int reqSize) {
if(reqSize > _array.length) {
int newSize = reqSize * 3 / 2; // grow with 50% extra
double[] newArr = new double[newSize];
System.arraycopy(_array, 0, newArr, 0, _count);
_array = newArr;
}
}
private void ensureCapacity(int reqSize) {
if (reqSize > _array.length) {
int newSize = reqSize * 3 / 2; // grow with 50% extra
double[] newArr = new double[newSize];
System.arraycopy(_array, 0, newArr, 0, _count);
_array = newArr;
}
}
public void add(double value) {
ensureCapacity(_count + 1);
_array[_count] = value;
_count++;
}
}
public void add(double value) {
ensureCapacity(_count + 1);
_array[_count] = value;
_count++;
}
}
private static final int DEFAULT_MAX_NUM_OPERANDS = SpreadsheetVersion.EXCEL2007.getMaxFunctionArgs();
private static final int DEFAULT_MAX_NUM_OPERANDS = SpreadsheetVersion.EXCEL2007.getMaxFunctionArgs();
public final ValueEval evaluate(ValueEval[] args, int srcCellRow, int srcCellCol) {
try {
double[] values = getNumberArray(args);
double d = evaluate(values);
if (Double.isNaN(d) || Double.isInfinite(d)) {
return ErrorEval.NUM_ERROR;
}
return new NumberEval(d);
} catch (EvaluationException e) {
return e.getErrorEval();
}
}
public final ValueEval evaluate(ValueEval[] args, int srcCellRow, int srcCellCol) {
try {
double[] values = getNumberArray(args);
double d = evaluate(values);
if (Double.isNaN(d) || Double.isInfinite(d)) {
return ErrorEval.NUM_ERROR;
}
return new NumberEval(d);
} catch (EvaluationException e) {
return e.getErrorEval();
}
}
protected abstract double evaluate(double[] values) throws EvaluationException;
/**
* Maximum number of operands accepted by this function.
* Subclasses may override to change default value.
*/
protected int getMaxNumOperands() {
return DEFAULT_MAX_NUM_OPERANDS;
}
/**
* Returns a double array that contains values for the numeric cells
* from among the list of operands. Blanks and Blank equivalent cells
* are ignored. Error operands or cells containing operands of type
* that are considered invalid and would result in #VALUE! error in
* excel cause this function to return <code>null</code>.
*
* @return never <code>null</code>
*/
protected final double[] getNumberArray(ValueEval[] operands) throws EvaluationException {
if (operands.length > getMaxNumOperands()) {
throw EvaluationException.invalidValue();
}
DoubleList retval = new DoubleList();
for (int i=0, iSize=operands.length; i<iSize; i++) {
collectValues(operands[i], retval);
}
return retval.toArray();
}
protected abstract double evaluate(double[] values) throws EvaluationException;
/**
* Whether to count nested subtotals.
* Maximum number of operands accepted by this function.
* Subclasses may override to change default value.
*/
public boolean isSubtotalCounted(){
protected int getMaxNumOperands() {
return DEFAULT_MAX_NUM_OPERANDS;
}
/**
* Returns a double array that contains values for the numeric cells
* from among the list of operands. Blanks and Blank equivalent cells
* are ignored. Error operands or cells containing operands of type
* that are considered invalid and would result in #VALUE! error in
* excel cause this function to return <code>null</code>.
*
* @return never <code>null</code>
*/
protected final double[] getNumberArray(ValueEval[] operands) throws EvaluationException {
if (operands.length > getMaxNumOperands()) {
throw EvaluationException.invalidValue();
}
DoubleList retval = new DoubleList();
for (int i = 0, iSize = operands.length; i < iSize; i++) {
collectValues(operands[i], retval);
}
return retval.toArray();
}
/**
* Whether to count nested subtotals.
*/
public boolean isSubtotalCounted() {
return true;
}
/**
* Collects values from a single argument
*/
private void collectValues(ValueEval operand, DoubleList temp) throws EvaluationException {
/**
* Collects values from a single argument
*/
private void collectValues(ValueEval operand, DoubleList temp) throws EvaluationException {
if (operand instanceof ThreeDEval) {
ThreeDEval ae = (ThreeDEval) operand;
for (int sIx=ae.getFirstSheetIndex(); sIx <= ae.getLastSheetIndex(); sIx++) {
for (int sIx = ae.getFirstSheetIndex(); sIx <= ae.getLastSheetIndex(); sIx++) {
int width = ae.getWidth();
int height = ae.getHeight();
for (int rrIx=0; rrIx<height; rrIx++) {
for (int rcIx=0; rcIx<width; rcIx++) {
for (int rrIx = 0; rrIx < height; rrIx++) {
for (int rcIx = 0; rcIx < width; rcIx++) {
ValueEval ve = ae.getValue(sIx, rrIx, rcIx);
if(!isSubtotalCounted() && ae.isSubTotal(rrIx, rcIx)) continue;
if (!isSubtotalCounted() && ae.isSubTotal(rrIx, rcIx)) continue;
collectValue(ve, true, temp);
}
}
}
return;
}
if (operand instanceof TwoDEval) {
TwoDEval ae = (TwoDEval) operand;
int width = ae.getWidth();
int height = ae.getHeight();
for (int rrIx=0; rrIx<height; rrIx++) {
for (int rcIx=0; rcIx<width; rcIx++) {
ValueEval ve = ae.getValue(rrIx, rcIx);
if(!isSubtotalCounted() && ae.isSubTotal(rrIx, rcIx)) continue;
if (operand instanceof TwoDEval) {
TwoDEval ae = (TwoDEval) operand;
int width = ae.getWidth();
int height = ae.getHeight();
for (int rrIx = 0; rrIx < height; rrIx++) {
for (int rcIx = 0; rcIx < width; rcIx++) {
ValueEval ve = ae.getValue(rrIx, rcIx);
if (!isSubtotalCounted() && ae.isSubTotal(rrIx, rcIx)) continue;
collectValue(ve, true, temp);
}
}
return;
}
if (operand instanceof RefEval) {
RefEval re = (RefEval) operand;
for (int sIx = re.getFirstSheetIndex(); sIx <= re.getLastSheetIndex(); sIx++) {
collectValue(re.getInnerValueEval(sIx), true, temp);
}
return;
}
collectValue(operand, false, temp);
}
private void collectValue(ValueEval ve, boolean isViaReference, DoubleList temp) throws EvaluationException {
if (ve == null) {
throw new IllegalArgumentException("ve must not be null");
}
if (ve instanceof BoolEval) {
if (!isViaReference || _isReferenceBoolCounted) {
BoolEval boolEval = (BoolEval) ve;
temp.add(boolEval.getNumberValue());
}
return;
}
if (ve instanceof NumericValueEval) {
NumericValueEval ne = (NumericValueEval) ve;
temp.add(ne.getNumberValue());
return;
}
if (ve instanceof StringValueEval) {
if (isViaReference) {
// ignore all ref strings
return;
}
String s = ((StringValueEval) ve).getStringValue();
Double d = OperandResolver.parseDouble(s);
if(d == null) {
throw new EvaluationException(ErrorEval.VALUE_INVALID);
}
temp.add(d.doubleValue());
return;
}
if (ve instanceof ErrorEval) {
throw new EvaluationException((ErrorEval) ve);
}
if (ve == BlankEval.instance) {
if (_isBlankCounted) {
temp.add(0.0);
}
return;
}
if (ve == MissingArgEval.instance) {
temp.add(0.0);
return;
}
throw new RuntimeException("Invalid ValueEval type passed for conversion: ("
+ ve.getClass() + ")");
}
}
}
return;
}
if (operand instanceof RefEval) {
RefEval re = (RefEval) operand;
for (int sIx = re.getFirstSheetIndex(); sIx <= re.getLastSheetIndex(); sIx++) {
collectValue(re.getInnerValueEval(sIx), true, temp);
}
return;
}
collectValue(operand, false, temp);
}
private void collectValue(ValueEval ve, boolean isViaReference, DoubleList temp) throws EvaluationException {
if (ve == null) {
throw new IllegalArgumentException("ve must not be null");
}
if (ve instanceof BoolEval) {
if (!isViaReference || _isReferenceBoolCounted) {
BoolEval boolEval = (BoolEval) ve;
temp.add(boolEval.getNumberValue());
}
return;
}
if (ve instanceof NumericValueEval) {
NumericValueEval ne = (NumericValueEval) ve;
temp.add(ne.getNumberValue());
return;
}
if (ve instanceof StringValueEval) {
if (isViaReference) {
// ignore all ref strings
return;
}
String s = ((StringValueEval) ve).getStringValue();
Double d = OperandResolver.parseDouble(s);
if (d == null) {
throw new EvaluationException(ErrorEval.VALUE_INVALID);
}
temp.add(d.doubleValue());
return;
}
if (ve instanceof ErrorEval) {
throw new EvaluationException((ErrorEval) ve);
}
if (ve == BlankEval.instance) {
if (_isBlankCounted) {
temp.add(0.0);
}
return;
}
if (ve == MissingArgEval.instance) {
temp.add(0.0);
return;
}
throw new RuntimeException("Invalid ValueEval type passed for conversion: ("
+ ve.getClass() + ")");
}
}