mirror of
https://github.com/apache/poi.git
synced 2026-02-27 20:40:08 +08:00
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:
parent
458b9e3aed
commit
9f7520e86f
@ -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() + ")");
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user