poi-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From n...@apache.org
Subject svn commit: r690299 [2/4] - in /poi/branches/ooxml: ./ src/java/org/apache/poi/hssf/dev/ src/java/org/apache/poi/hssf/model/ src/java/org/apache/poi/hssf/record/ src/java/org/apache/poi/hssf/record/aggregates/ src/java/org/apache/poi/hssf/record/formul...
Date Fri, 29 Aug 2008 15:27:11 GMT
Modified: poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/functions/BooleanFunction.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/functions/BooleanFunction.java?rev=690299&r1=690298&r2=690299&view=diff
==============================================================================
--- poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/functions/BooleanFunction.java (original)
+++ poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/functions/BooleanFunction.java Fri Aug 29 08:27:07 2008
@@ -1,100 +1,108 @@
-/*
-* 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.
-*/
-/*
- * Created on May 15, 2005
- *
- */
+/* ====================================================================
+   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.poi.hssf.record.formula.functions;
 
-import org.apache.poi.hssf.record.formula.eval.BlankEval;
+import org.apache.poi.hssf.record.formula.eval.AreaEval;
 import org.apache.poi.hssf.record.formula.eval.BoolEval;
 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.NumericValueEval;
+import org.apache.poi.hssf.record.formula.eval.EvaluationException;
+import org.apache.poi.hssf.record.formula.eval.OperandResolver;
 import org.apache.poi.hssf.record.formula.eval.RefEval;
-import org.apache.poi.hssf.record.formula.eval.StringEval;
 import org.apache.poi.hssf.record.formula.eval.ValueEval;
 
-
 /**
- * @author Amol S. Deshmukh < amolweb at ya hoo dot com >
  * Here are the general rules concerning Boolean functions:
  * <ol>
- * <li> Blanks are not either true or false
- * <li> Strings are not either true or false (even strings "true" 
- * or "TRUE" or "0" etc.)
- * <li> Numbers: 0 is false. Any other number is TRUE.
- * <li> References are evaluated and above rules apply.
- * <li> Areas: Individual cells in area are evaluated and checked to 
- * see if they are blanks, strings etc.
+ * <li> Blanks are ignored (not either true or false) </li>
+ * <li> Strings are ignored if part of an area ref or cell ref, otherwise they must be 'true' or 'false'</li> 
+ * <li> Numbers: 0 is false. Any other number is TRUE </li>
+ * <li> Areas: *all* cells in area are evaluated according to the above rules</li>
  * </ol>
+ * 
+ * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
  */
 public abstract class BooleanFunction implements Function {
 
-    protected ValueEval singleOperandEvaluate(Eval eval, int srcRow, short srcCol, boolean stringsAreBlanks) {
-        ValueEval retval;
-        
-        if (eval instanceof RefEval) {
-            RefEval re = (RefEval) eval;
-            ValueEval ve = re.getInnerValueEval();
-            retval = internalResolve(ve, true);
-        }
-        else {
-            retval = internalResolve(eval, stringsAreBlanks);
-        }
-        
-        return retval;
-    }
-    
-    private ValueEval internalResolve(Eval ve, boolean stringsAreBlanks) {
-        ValueEval retval = null;
-        
-        // blankeval is returned as is
-        if (ve instanceof BlankEval) {
-            retval = BlankEval.INSTANCE;
-        }
-        
-        // stringeval
-        else if (ve instanceof StringEval) {
-            retval = stringsAreBlanks ? (ValueEval) BlankEval.INSTANCE : (StringEval) ve;
-        }
-        
-        // bools are bools :)
-        else if (ve instanceof BoolEval) {
-            retval = (BoolEval) ve;
-        }
-        
-        // convert numbers to bool
-        else if (ve instanceof NumericValueEval) {
-            NumericValueEval ne = (NumericValueEval) ve;
-            double d = ne.getNumberValue();
-            retval = Double.isNaN(d) 
-                    ? (ValueEval) ErrorEval.VALUE_INVALID
-                    : (d != 0) 
-                        ? BoolEval.TRUE
-                        : BoolEval.FALSE;
-        }
-        
-        // since refevals
-        else {
-            retval = ErrorEval.VALUE_INVALID;
-        }
-        
-        return retval;
-        
-    }
+	public final Eval evaluate(Eval[] args, int srcRow, short srcCol) {
+		if (args.length < 1) {
+			return ErrorEval.VALUE_INVALID;
+		}
+		boolean boolResult;
+		try {
+			boolResult = calculate(args);
+		} catch (EvaluationException e) {
+			return e.getErrorEval();
+		}
+		return BoolEval.valueOf(boolResult);
+	}
+
+	private boolean calculate(Eval[] args) throws EvaluationException {
+
+		boolean result = getInitialResultValue();
+		boolean atleastOneNonBlank = false;
+		
+		/*
+		 * Note: no short-circuit boolean loop exit because any ErrorEvals will override the result
+		 */
+		for (int i=0, iSize=args.length; i<iSize; i++) {
+			Eval arg = args[i];
+			if (arg instanceof AreaEval) {
+				AreaEval ae = (AreaEval) arg;
+				int height = ae.getHeight();
+				int width = ae.getWidth();
+				for (int rrIx=0; rrIx<height; rrIx++) {
+					for (int rcIx=0; rcIx<width; rcIx++) {
+						ValueEval ve = ae.getRelativeValue(rrIx, rcIx);
+						Boolean tempVe = OperandResolver.coerceValueToBoolean(ve, true);
+						if (tempVe != null) {
+							result = partialEvaluate(result, tempVe.booleanValue());
+							atleastOneNonBlank = true;
+						}
+					}
+				}
+				continue;
+			}
+			Boolean tempVe;
+			if (arg instanceof RefEval) {
+				ValueEval ve = ((RefEval) arg).getInnerValueEval();
+				tempVe = OperandResolver.coerceValueToBoolean(ve, true);
+			} else if (arg instanceof ValueEval) {
+				ValueEval ve = (ValueEval) arg;
+				tempVe = OperandResolver.coerceValueToBoolean(ve, false);
+			} else {
+				throw new RuntimeException("Unexpected eval (" + arg.getClass().getName() + ")");
+			}
+			
+			
+			if (tempVe != null) {
+				result = partialEvaluate(result, tempVe.booleanValue());
+				atleastOneNonBlank = true;
+			}
+		}
+		
+		if (!atleastOneNonBlank) {
+			throw new EvaluationException(ErrorEval.VALUE_INVALID);
+		}
+		return result;
+	}
+	
+	
+	protected abstract boolean getInitialResultValue();
+	protected abstract boolean partialEvaluate(boolean cumulativeResult, boolean currentValue);
 }

Modified: poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/functions/Count.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/functions/Count.java?rev=690299&r1=690298&r2=690299&view=diff
==============================================================================
--- poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/functions/Count.java (original)
+++ poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/functions/Count.java Fri Aug 29 08:27:07 2008
@@ -1,32 +1,26 @@
-/*
-* 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.
-*/
-/*
- * Created on May 15, 2005
- *
- */
+/* ====================================================================
+   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.poi.hssf.record.formula.functions;
 
-import org.apache.poi.hssf.record.formula.eval.AreaEval;
-import org.apache.poi.hssf.record.formula.eval.BlankEval;
 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.NumberEval;
-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.functions.CountUtils.I_MatchPredicate;
 
 /**
  * Counts the number of cells that contain numeric data within
@@ -39,7 +33,7 @@
  * TODO: Check this properly matches excel on edge cases
  *  like formula cells, error cells etc
  */
-public class Count implements Function {
+public final class Count implements Function {
 
 	public Eval evaluate(Eval[] args, int srcCellRow, short srcCellCol) {
 		int nArgs = args.length;
@@ -56,63 +50,23 @@
 		int temp = 0;
 		
 		for(int i=0; i<nArgs; i++) {
-			temp += countArg(args[i]);
+			temp += CountUtils.countArg(args[i], predicate);
 			
 		}
 		return new NumberEval(temp);
 	}
 
-	private static int countArg(Eval eval) {
-        if (eval instanceof AreaEval) {
-            AreaEval ae = (AreaEval) eval;
-            return countAreaEval(ae);
-        }
-        if (eval instanceof RefEval) {
-            RefEval refEval = (RefEval)eval;
-			return countValue(refEval.getInnerValueEval());
-        }
-        if (eval instanceof NumberEval) {
-            return 1;
-        }
-		
-		throw new RuntimeException("Unexpected eval type (" + eval.getClass().getName() + ")");
-	}
+	private static final I_MatchPredicate predicate = new I_MatchPredicate() {
 
-	private static int countAreaEval(AreaEval ae) {
-		
-		int temp = 0;
-		ValueEval[] values = ae.getValues();
-		for (int i = 0; i < values.length; i++) {
-			ValueEval val = values[i];
-			if(val == null) {
-				// seems to occur.  Really we would have expected BlankEval
-				continue;
-			}
-			temp += countValue(val);
-			
-		}
-		return temp;
-	}
+		public boolean matches(Eval valueEval) {
 
-	private static int countValue(ValueEval valueEval) {
-		
-		if(valueEval == BlankEval.INSTANCE) {
-			return 0;
-		}
-		
-		if(valueEval instanceof BlankEval) {
-			// wouldn't need this if BlankEval was final
-			return 0;
-		}
+			if(valueEval instanceof NumberEval) {
+				// only numbers are counted
+				return true;
+			}
 
-		if(valueEval instanceof ErrorEval) {
-			// note - error values not counted
-			return 0;
+			// error values and string values not counted
+			return false;
 		}
-		
-		if(valueEval instanceof NumberEval)
-			return 1;
-
-		return 0;
-	}
+	};
 }
\ No newline at end of file

Modified: poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/functions/Counta.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/functions/Counta.java?rev=690299&r1=690298&r2=690299&view=diff
==============================================================================
--- poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/functions/Counta.java (original)
+++ poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/functions/Counta.java Fri Aug 29 08:27:07 2008
@@ -1,31 +1,27 @@
-/*
-* 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.
-*/
-
+/* ====================================================================
+   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.poi.hssf.record.formula.functions;
 
-import org.apache.poi.hssf.record.formula.eval.AreaEval;
 import org.apache.poi.hssf.record.formula.eval.BlankEval;
 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.NumberEval;
-import org.apache.poi.hssf.record.formula.eval.RefEval;
-import org.apache.poi.hssf.record.formula.eval.StringEval;
-import org.apache.poi.hssf.record.formula.eval.ValueEval;
+import org.apache.poi.hssf.record.formula.functions.CountUtils.I_MatchPredicate;
 
 /**
  * Counts the number of cells that contain data within the list of arguments. 
@@ -51,70 +47,26 @@
 		}
 		
 		int temp = 0;
-		// Note - observed behavior of Excel:
-		// Error values like #VALUE!, #REF!, #DIV/0!, #NAME? etc don't cause this COUNTA to return an error
-		// in fact, they seem to get counted
 		
 		for(int i=0; i<nArgs; i++) {
-			temp += countArg(args[i]);
+			temp += CountUtils.countArg(args[i], predicate);
 			
 		}
 		return new NumberEval(temp);
 	}
 
-	private static int countArg(Eval eval) {
-        if (eval instanceof AreaEval) {
-            AreaEval ae = (AreaEval) eval;
-            return countAreaEval(ae);
-        }
-        if (eval instanceof RefEval) {
-            RefEval refEval = (RefEval)eval;
-			return countValue(refEval.getInnerValueEval());
-        }
-        if (eval instanceof NumberEval) {
-            return 1;
-        }
-        if (eval instanceof StringEval) {
-            return 1;
-        }
-        
-		
-		throw new RuntimeException("Unexpected eval type (" + eval.getClass().getName() + ")");
-	}
+	private static final I_MatchPredicate predicate = new I_MatchPredicate() {
 
-	private static int countAreaEval(AreaEval ae) {
-		
-		int temp = 0;
-		ValueEval[] values = ae.getValues();
-		for (int i = 0; i < values.length; i++) {
-			ValueEval val = values[i];
-			if(val == null) {
-				// seems to occur.  Really we would have expected BlankEval
-				continue;
-			}
-			temp += countValue(val);
-			
-		}
-		return temp;
-	}
+		public boolean matches(Eval valueEval) {
+			// Note - observed behavior of Excel:
+			// Error values like #VALUE!, #REF!, #DIV/0!, #NAME? etc don't cause this COUNTA to return an error
+			// in fact, they seem to get counted
 
-	private static int countValue(ValueEval valueEval) {
-		
-		if(valueEval == BlankEval.INSTANCE) {
-			return 0;
-		}
-		
-		if(valueEval instanceof BlankEval) {
-			// wouldn't need this if BlankEval was final
-			return 0;
-		}
-
-		if(valueEval instanceof ErrorEval) {
-			// note - error values are counted
-			return 1;
+			if(valueEval == BlankEval.INSTANCE) {
+				return false;
+			}
+			// Note - everything but BlankEval counts
+			return true;
 		}
-		// also empty strings and zeros are counted too
-
-		return 1;
-	}
+	};
 }

Modified: poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/functions/Countif.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/functions/Countif.java?rev=690299&r1=690298&r2=690299&view=diff
==============================================================================
--- poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/functions/Countif.java (original)
+++ poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/functions/Countif.java Fri Aug 29 08:27:07 2008
@@ -1,19 +1,19 @@
-/*
-* 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.
-*/
+/* ====================================================================
+   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.poi.hssf.record.formula.functions;
 
@@ -28,7 +28,7 @@
 import org.apache.poi.hssf.record.formula.eval.OperandResolver;
 import org.apache.poi.hssf.record.formula.eval.RefEval;
 import org.apache.poi.hssf.record.formula.eval.StringEval;
-import org.apache.poi.hssf.record.formula.eval.ValueEval;
+import org.apache.poi.hssf.record.formula.functions.CountUtils.I_MatchPredicate;
 
 /**
  * Implementation for the function COUNTIF<p/>
@@ -144,12 +144,6 @@
 		}
 	}
 
-	/**
-	 * Common interface for the matching criteria.
-	 */
-	/* package */ interface I_MatchPredicate {
-		boolean matches(Eval x);
-	}
 
 	private static final class NumberMatcher implements I_MatchPredicate {
 
@@ -360,21 +354,12 @@
 	 * @return the number of evaluated cells in the range that match the specified criteria
 	 */
 	private Eval countMatchingCellsInArea(Eval rangeArg, I_MatchPredicate criteriaPredicate) {
-		int result = 0;
+		
+		int result;
 		if (rangeArg instanceof RefEval) {
-			RefEval refEval = (RefEval) rangeArg;
-			if(criteriaPredicate.matches(refEval.getInnerValueEval())) {
-				result++;
-			}
+			result = CountUtils.countMatchingCell((RefEval) rangeArg, criteriaPredicate);
 		} else if (rangeArg instanceof AreaEval) {
-
-			AreaEval range = (AreaEval) rangeArg;
-			ValueEval[] values = range.getValues();
-			for (int i = 0; i < values.length; i++) {
-				if(criteriaPredicate.matches(values[i])) {
-					result++;
-				}
-			}
+			result = CountUtils.countMatchingCellsInArea((AreaEval) rangeArg, criteriaPredicate);
 		} else {
 			throw new IllegalArgumentException("Bad range arg type (" + rangeArg.getClass().getName() + ")");
 		}

Modified: poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/functions/Hlookup.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/functions/Hlookup.java?rev=690299&r1=690298&r2=690299&view=diff
==============================================================================
--- poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/functions/Hlookup.java (original)
+++ poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/functions/Hlookup.java Fri Aug 29 08:27:07 2008
@@ -42,40 +42,6 @@
  */
 public final class Hlookup implements Function {
 	
-	private static final class RowVector implements ValueVector {
-
-		private final AreaEval _tableArray;
-		private final int _size;
-		private final int _rowAbsoluteIndex;
-		private final int _firstColumnAbsoluteIndex;
-
-		public RowVector(AreaEval tableArray, int rowIndex) {
-			_rowAbsoluteIndex = tableArray.getFirstRow() + rowIndex;
-			if(!tableArray.containsRow(_rowAbsoluteIndex)) {
-				int lastRowIx =  tableArray.getLastRow() -  tableArray.getFirstRow();
-				throw new IllegalArgumentException("Specified row index (" + rowIndex 
-						+ ") is outside the allowed range (0.." + lastRowIx + ")");
-			}
-			_tableArray = tableArray;
-			_size = tableArray.getLastColumn() - tableArray.getFirstColumn() + 1;
-			if(_size < 1) {
-				throw new RuntimeException("bad table array size zero");
-			}
-			_firstColumnAbsoluteIndex = tableArray.getFirstColumn();
-		}
-
-		public ValueEval getItem(int index) {
-			if(index>_size) {
-				throw new ArrayIndexOutOfBoundsException("Specified index (" + index 
-						+ ") is outside the allowed range (0.." + (_size-1) + ")");
-			}
-			return _tableArray.getValueAt(_rowAbsoluteIndex, (short) (_firstColumnAbsoluteIndex + index));
-		}
-		public int getSize() {
-			return _size;
-		}
-	}
-
 	public Eval evaluate(Eval[] args, int srcCellRow, short srcCellCol) {
 		Eval arg3 = null;
 		switch(args.length) {
@@ -93,7 +59,7 @@
 			ValueEval lookupValue = OperandResolver.getSingleValue(args[0], srcCellRow, srcCellCol);
 			AreaEval tableArray = LookupUtils.resolveTableArrayArg(args[1]);
 			boolean isRangeLookup = LookupUtils.resolveRangeLookupArg(arg3, srcCellRow, srcCellCol);
-			int colIndex = LookupUtils.lookupIndexOfValue(lookupValue, new RowVector(tableArray, 0), isRangeLookup);
+			int colIndex = LookupUtils.lookupIndexOfValue(lookupValue, LookupUtils.createRowVector(tableArray, 0), isRangeLookup);
 			ValueEval veColIndex = OperandResolver.getSingleValue(args[2], srcCellRow, srcCellCol);
 			int rowIndex = LookupUtils.resolveRowOrColIndexArg(veColIndex);
 			ValueVector resultCol = createResultColumnVector(tableArray, rowIndex);
@@ -113,11 +79,9 @@
 		if(colIndex < 0) {
 			throw EvaluationException.invalidValue();
 		}
-		int nCols = tableArray.getLastColumn() - tableArray.getFirstRow() + 1;
-		
-		if(colIndex >= nCols) {
+		if(colIndex >= tableArray.getWidth()) {
 			throw EvaluationException.invalidRef();
 		}
-		return new RowVector(tableArray, colIndex);
+		return LookupUtils.createRowVector(tableArray, colIndex);
 	}
 }

Modified: poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/functions/Lookup.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/functions/Lookup.java?rev=690299&r1=690298&r2=690299&view=diff
==============================================================================
--- poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/functions/Lookup.java (original)
+++ poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/functions/Lookup.java Fri Aug 29 08:27:07 2008
@@ -40,19 +40,6 @@
  * @author Josh Micich
  */
 public final class Lookup implements Function {
-	private static final class SimpleValueVector implements ValueVector {
-		private final ValueEval[] _values;
-
-		public SimpleValueVector(ValueEval[] values) {
-			_values = values;
-		}
-		public ValueEval getItem(int index) {
-			return _values[index];
-		}
-		public int getSize() {
-			return _values.length;
-		}
-	}
 
 	public Eval evaluate(Eval[] args, int srcCellRow, short srcCellCol) {
 		switch(args.length) {
@@ -86,11 +73,11 @@
 	}
 
 	private static ValueVector createVector(AreaEval ae) {
-		
-		if(!ae.isRow() && !ae.isColumn()) {
-			// extra complexity required to emulate the way LOOKUP can handles these abnormal cases.
-			throw new RuntimeException("non-vector lookup or result areas not supported yet");
+		ValueVector result = LookupUtils.createVector(ae);
+		if (result != null) {
+			return result;
 		}
-		return new SimpleValueVector(ae.getValues());
+		// extra complexity required to emulate the way LOOKUP can handles these abnormal cases.
+		throw new RuntimeException("non-vector lookup or result areas not supported yet");
 	}
 }

Modified: poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/functions/LookupUtils.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/functions/LookupUtils.java?rev=690299&r1=690298&r2=690299&view=diff
==============================================================================
--- poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/functions/LookupUtils.java (original)
+++ poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/functions/LookupUtils.java Fri Aug 29 08:27:07 2008
@@ -34,11 +34,11 @@
 
 /**
  * Common functionality used by VLOOKUP, HLOOKUP, LOOKUP and MATCH
- * 
+ *
  * @author Josh Micich
  */
 final class LookupUtils {
-	
+
 	/**
 	 * Represents a single row or column within an <tt>AreaEval</tt>.
 	 */
@@ -46,14 +46,95 @@
 		ValueEval getItem(int index);
 		int getSize();
 	}
+
+
+	private static final class RowVector implements ValueVector {
+
+		private final AreaEval _tableArray;
+		private final int _size;
+		private final int _rowIndex;
+
+		public RowVector(AreaEval tableArray, int rowIndex) {
+			_rowIndex = rowIndex;
+			int _rowAbsoluteIndex = tableArray.getFirstRow() + rowIndex;
+			if(!tableArray.containsRow(_rowAbsoluteIndex)) {
+				int lastRowIx =  tableArray.getLastRow() -  tableArray.getFirstRow();
+				throw new IllegalArgumentException("Specified row index (" + rowIndex
+						+ ") is outside the allowed range (0.." + lastRowIx + ")");
+			}
+			_tableArray = tableArray;
+			_size = tableArray.getWidth();
+		}
+
+		public ValueEval getItem(int index) {
+			if(index > _size) {
+				throw new ArrayIndexOutOfBoundsException("Specified index (" + index
+						+ ") is outside the allowed range (0.." + (_size-1) + ")");
+			}
+			return _tableArray.getRelativeValue(_rowIndex, index);
+		}
+		public int getSize() {
+			return _size;
+		}
+	}
+
+	private static final class ColumnVector implements ValueVector {
+
+		private final AreaEval _tableArray;
+		private final int _size;
+		private final int _columnIndex;
+
+		public ColumnVector(AreaEval tableArray, int columnIndex) {
+			_columnIndex = columnIndex;
+			int _columnAbsoluteIndex = tableArray.getFirstColumn() + columnIndex;
+			if(!tableArray.containsColumn((short)_columnAbsoluteIndex)) {
+				int lastColIx =  tableArray.getLastColumn() -  tableArray.getFirstColumn();
+				throw new IllegalArgumentException("Specified column index (" + columnIndex
+						+ ") is outside the allowed range (0.." + lastColIx + ")");
+			}
+			_tableArray = tableArray;
+			_size = _tableArray.getHeight();
+		}
+
+		public ValueEval getItem(int index) {
+			if(index > _size) {
+				throw new ArrayIndexOutOfBoundsException("Specified index (" + index
+						+ ") is outside the allowed range (0.." + (_size-1) + ")");
+			}
+			return _tableArray.getRelativeValue(index, _columnIndex);
+		}
+		public int getSize() {
+			return _size;
+		}
+	}
+
+	public static ValueVector createRowVector(AreaEval tableArray, int relativeRowIndex) {
+		return new RowVector(tableArray, relativeRowIndex);
+	}
+	public static ValueVector createColumnVector(AreaEval tableArray, int relativeColumnIndex) {
+		return new ColumnVector(tableArray, relativeColumnIndex);
+	}
+	/**
+	 * @return <code>null</code> if the supplied area is neither a single row nor a single colum
+	 */
+	public static ValueVector createVector(AreaEval ae) {
+		if (ae.isColumn()) {
+			return createColumnVector(ae, 0);
+		}
+		if (ae.isRow()) {
+			return createRowVector(ae, 0);
+		}
+		return null;
+	}
+
 	/**
 	 * Enumeration to support <b>4</b> valued comparison results.<p/>
-	 * Excel lookup functions have complex behaviour in the case where the lookup array has mixed 
+	 * Excel lookup functions have complex behaviour in the case where the lookup array has mixed
 	 * types, and/or is unordered.  Contrary to suggestions in some Excel documentation, there
 	 * does not appear to be a universal ordering across types.  The binary search algorithm used
 	 * changes behaviour when the evaluated 'mid' value has a different type to the lookup value.<p/>
-	 * 
-	 * A simple int might have done the same job, but there is risk in confusion with the well 
+	 *
+	 * A simple int might have done the same job, but there is risk in confusion with the well
 	 * known <tt>Comparable.compareTo()</tt> and <tt>Comparator.compare()</tt> which both use
 	 * a ubiquitous 3 value result encoding.
 	 */
@@ -80,7 +161,7 @@
 		public static final CompareResult LESS_THAN = new CompareResult(false, -1);
 		public static final CompareResult EQUAL = new CompareResult(false, 0);
 		public static final CompareResult GREATER_THAN = new CompareResult(false, +1);
-		
+
 		public static final CompareResult valueOf(int simpleCompareResult) {
 			if(simpleCompareResult < 0) {
 				return LESS_THAN;
@@ -90,7 +171,7 @@
 			}
 			return EQUAL;
 		}
-		
+
 		public boolean isTypeMismatch() {
 			return _isTypeMismatch;
 		}
@@ -128,17 +209,17 @@
 			return "??error??";
 		}
 	}
-	
+
 	public interface LookupValueComparer {
 		/**
-		 * @return one of 4 instances or <tt>CompareResult</tt>: <tt>LESS_THAN</tt>, <tt>EQUAL</tt>, 
+		 * @return one of 4 instances or <tt>CompareResult</tt>: <tt>LESS_THAN</tt>, <tt>EQUAL</tt>,
 		 * <tt>GREATER_THAN</tt> or <tt>TYPE_MISMATCH</tt>
 		 */
 		CompareResult compareTo(ValueEval other);
 	}
-	
+
 	private static abstract class LookupValueComparerBase implements LookupValueComparer {
-		
+
 		private final Class _targetClass;
 		protected LookupValueComparerBase(ValueEval targetValue) {
 			if(targetValue == null) {
@@ -154,7 +235,7 @@
 				return CompareResult.TYPE_MISMATCH;
 			}
 			if (_targetClass == StringEval.class) {
-				
+
 			}
 			return compareSameType(other);
 		}
@@ -169,7 +250,7 @@
 		/** used only for debug purposes */
 		protected abstract String getValueAsString();
 	}
-	
+
 	private static final class StringLookupComparer extends LookupValueComparerBase {
 		private String _value;
 
@@ -223,9 +304,9 @@
 			return String.valueOf(_value);
 		}
 	}
-	
+
 	/**
-	 * Processes the third argument to VLOOKUP, or HLOOKUP (<b>col_index_num</b> 
+	 * Processes the third argument to VLOOKUP, or HLOOKUP (<b>col_index_num</b>
 	 * or <b>row_index_num</b> respectively).<br>
 	 * Sample behaviour:
 	 *    <table border="0" cellpadding="1" cellspacing="2" summary="Sample behaviour">
@@ -242,17 +323,17 @@
 	 *      <tr><td>""</td><td>&nbsp;</td><td>#REF!</td></tr>
 	 *      <tr><td>&lt;blank&gt;</td><td>&nbsp;</td><td>#VALUE!</td></tr>
 	 *    </table><br/>
-	 *    
-	 *  * Note - out of range errors (both too high and too low) are handled by the caller. 
+	 *
+	 *  * Note - out of range errors (both too high and too low) are handled by the caller.
 	 * @return column or row index as a zero-based value
-	 * 
+	 *
 	 */
 	public static int resolveRowOrColIndexArg(ValueEval veRowColIndexArg) throws EvaluationException {
 		if(veRowColIndexArg == null) {
 			throw new IllegalArgumentException("argument must not be null");
 		}
 		if(veRowColIndexArg instanceof BlankEval) {
-			throw EvaluationException.invalidValue(); 
+			throw EvaluationException.invalidValue();
 		}
 		if(veRowColIndexArg instanceof StringEval) {
 			StringEval se = (StringEval) veRowColIndexArg;
@@ -260,7 +341,7 @@
 			Double dVal = OperandResolver.parseDouble(strVal);
 			if(dVal == null) {
 				// String does not resolve to a number. Raise #VALUE! error.
-				throw EvaluationException.invalidRef(); 
+				throw EvaluationException.invalidRef();
 				// This includes text booleans "TRUE" and "FALSE".  They are not valid.
 			}
 			// else - numeric value parses OK
@@ -268,9 +349,9 @@
 		// actual BoolEval values get interpreted as FALSE->0 and TRUE->1
 		return OperandResolver.coerceValueToInt(veRowColIndexArg) - 1;
 	}
-	
-	
-	
+
+
+
 	/**
 	 * The second argument (table_array) should be an area ref, but can actually be a cell ref, in
 	 * which case it is interpreted as a 1x1 area ref.  Other scalar values cause #VALUE! error.
@@ -279,13 +360,13 @@
 		if (eval instanceof AreaEval) {
 			return (AreaEval) eval;
 		}
-		
+
 		if(eval instanceof RefEval) {
 			RefEval refEval = (RefEval) eval;
 			// Make this cell ref look like a 1x1 area ref.
-			
+
 			// It doesn't matter if eval is a 2D or 3D ref, because that detail is never asked of AreaEval.
-			// This code only requires the value array item. 
+			// This code only requires the value array item.
 			// anything would be ok for rowIx and colIx, but may as well get it right.
 			int rowIx = refEval.getRow();
 			int colIx = refEval.getColumn();
@@ -295,10 +376,10 @@
 		}
 		throw EvaluationException.invalidValue();
 	}
-	
+
 
 	/**
-	 * Resolves the last (optional) parameter (<b>range_lookup</b>) to the VLOOKUP and HLOOKUP functions. 
+	 * Resolves the last (optional) parameter (<b>range_lookup</b>) to the VLOOKUP and HLOOKUP functions.
 	 * @param rangeLookupArg
 	 * @param srcCellRow
 	 * @param srcCellCol
@@ -318,7 +399,7 @@
 			return false;
 		}
 		if(valEval instanceof BoolEval) {
-			// Happy day flow 
+			// Happy day flow
 			BoolEval boolEval = (BoolEval) valEval;
 			return boolEval.getBooleanValue();
 		}
@@ -327,7 +408,7 @@
 			String stringValue = ((StringEval) valEval).getStringValue();
 			if(stringValue.length() < 1) {
 				// More trickiness:
-				// Empty string is not the same as BlankEval.  It causes #VALUE! error 
+				// Empty string is not the same as BlankEval.  It causes #VALUE! error
 				throw EvaluationException.invalidValue();
 			}
 			// TODO move parseBoolean to OperandResolver
@@ -337,10 +418,10 @@
 				return b.booleanValue();
 			}
 			// Even more trickiness:
-			// Note - even if the StringEval represents a number value (for example "1"), 
-			// Excel does not resolve it to a boolean.  
+			// Note - even if the StringEval represents a number value (for example "1"),
+			// Excel does not resolve it to a boolean.
 			throw EvaluationException.invalidValue();
-			// This is in contrast to the code below,, where NumberEvals values (for 
+			// This is in contrast to the code below,, where NumberEvals values (for
 			// example 0.01) *do* resolve to equivalent boolean values.
 		}
 		if (valEval instanceof NumericValueEval) {
@@ -350,7 +431,7 @@
 		}
 		throw new RuntimeException("Unexpected eval type (" + valEval.getClass().getName() + ")");
 	}
-	
+
 	public static int lookupIndexOfValue(ValueEval lookupValue, ValueVector vector, boolean isRangeLookup) throws EvaluationException {
 		LookupValueComparer lookupComparer = createLookupComparer(lookupValue);
 		int result;
@@ -364,13 +445,13 @@
 		}
 		return result;
 	}
-	
-	
+
+
 	/**
 	 * Finds first (lowest index) exact occurrence of specified value.
 	 * @param lookupValue the value to be found in column or row vector
-	 * @param vector the values to be searched. For VLOOKUP this is the first column of the 
-	 * 	tableArray. For HLOOKUP this is the first row of the tableArray. 
+	 * @param vector the values to be searched. For VLOOKUP this is the first column of the
+	 * 	tableArray. For HLOOKUP this is the first row of the tableArray.
 	 * @return zero based index into the vector, -1 if value cannot be found
 	 */
 	private static int lookupIndexOfExactValue(LookupValueComparer lookupComparer, ValueVector vector) {
@@ -385,10 +466,10 @@
 		return -1;
 	}
 
-	
+
 	/**
 	 * Encapsulates some standard binary search functionality so the unusual Excel behaviour can
-	 * be clearly distinguished. 
+	 * be clearly distinguished.
 	 */
 	private static final class BinarySearchIndexes {
 
@@ -427,7 +508,7 @@
 	}
 	/**
 	 * Excel has funny behaviour when the some elements in the search vector are the wrong type.
-	 * 
+	 *
 	 */
 	private static int performBinarySearch(ValueVector vector, LookupValueComparer lookupComparer) {
 		// both low and high indexes point to values assumed too low and too high.
@@ -435,7 +516,7 @@
 
 		while(true) {
 			int midIx = bsi.getMidIx();
-			
+
 			if(midIx < 0) {
 				return bsi.getLowIx();
 			}
@@ -455,17 +536,17 @@
 		}
 	}
 	/**
-	 * Excel seems to handle mismatched types initially by just stepping 'mid' ix forward to the 
+	 * Excel seems to handle mismatched types initially by just stepping 'mid' ix forward to the
 	 * first compatible value.
 	 * @param midIx 'mid' index (value which has the wrong type)
-	 * @return usually -1, signifying that the BinarySearchIndex has been narrowed to the new mid 
+	 * @return usually -1, signifying that the BinarySearchIndex has been narrowed to the new mid
 	 * index.  Zero or greater signifies that an exact match for the lookup value was found
 	 */
 	private static int handleMidValueTypeMismatch(LookupValueComparer lookupComparer, ValueVector vector,
 			BinarySearchIndexes bsi, int midIx) {
 		int newMid = midIx;
 		int highIx = bsi.getHighIx();
-		
+
 		while(true) {
 			newMid++;
 			if(newMid == highIx) {
@@ -511,9 +592,9 @@
 	}
 
 	public static LookupValueComparer createLookupComparer(ValueEval lookupValue) throws EvaluationException {
-		
+
 		if (lookupValue instanceof BlankEval) {
-			// blank eval can never be found in a lookup array 
+			// blank eval can never be found in a lookup array
 			throw new EvaluationException(ErrorEval.NA);
 		}
 		if (lookupValue instanceof StringEval) {

Modified: poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/functions/Match.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/functions/Match.java?rev=690299&r1=690298&r2=690299&view=diff
==============================================================================
--- poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/functions/Match.java (original)
+++ poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/functions/Match.java Fri Aug 29 08:27:07 2008
@@ -29,18 +29,19 @@
 import org.apache.poi.hssf.record.formula.eval.ValueEval;
 import org.apache.poi.hssf.record.formula.functions.LookupUtils.CompareResult;
 import org.apache.poi.hssf.record.formula.functions.LookupUtils.LookupValueComparer;
+import org.apache.poi.hssf.record.formula.functions.LookupUtils.ValueVector;
 
 /**
  * Implementation for the MATCH() Excel function.<p/>
- * 
+ *
  * <b>Syntax:</b><br/>
  * <b>MATCH</b>(<b>lookup_value</b>, <b>lookup_array</b>, match_type)<p/>
- * 
- * Returns a 1-based index specifying at what position in the <b>lookup_array</b> the specified 
+ *
+ * Returns a 1-based index specifying at what position in the <b>lookup_array</b> the specified
  * <b>lookup_value</b> is found.<p/>
- * 
+ *
  * Specific matching behaviour can be modified with the optional <b>match_type</b> parameter.
- * 
+ *
  *    <table border="0" cellpadding="1" cellspacing="0" summary="match_type parameter description">
  *      <tr><th>Value</th><th>Matching Behaviour</th></tr>
  *      <tr><td>1</td><td>(default) find the largest value that is less than or equal to lookup_value.
@@ -50,26 +51,26 @@
  *      <tr><td>-1</td><td>find the smallest value that is greater than or equal to lookup_value.
  *        The lookup_array must be in descending <i>order</i>*.</td></tr>
  *    </table>
- * 
+ *
  * * Note regarding <i>order</i> - For the <b>match_type</b> cases that require the lookup_array to
  *  be ordered, MATCH() can produce incorrect results if this requirement is not met.  Observed
  *  behaviour in Excel is to return the lowest index value for which every item after that index
  *  breaks the match rule.<br>
  *  The (ascending) sort order expected by MATCH() is:<br/>
  *  numbers (low to high), strings (A to Z), boolean (FALSE to TRUE)<br/>
- *  MATCH() ignores all elements in the lookup_array with a different type to the lookup_value. 
+ *  MATCH() ignores all elements in the lookup_array with a different type to the lookup_value.
  *  Type conversion of the lookup_array elements is never performed.
- *  
- *  
+ *
+ *
  * @author Josh Micich
  */
 public final class Match implements Function {
-	
+
 
 	public Eval evaluate(Eval[] args, int srcCellRow, short srcCellCol) {
-		
+
 		double match_type = 1; // default
-		
+
 		switch(args.length) {
 			case 3:
 				try {
@@ -85,15 +86,15 @@
 			default:
 				return ErrorEval.VALUE_INVALID;
 		}
-		
+
 		boolean matchExact = match_type == 0;
 		// Note - Excel does not strictly require -1 and +1
 		boolean findLargestLessThanOrEqual = match_type > 0;
-		
-		
+
+
 		try {
 			ValueEval lookupValue = OperandResolver.getSingleValue(args[0], srcCellRow, srcCellCol);
-			ValueEval[] lookupRange = evaluateLookupRange(args[1]);
+			ValueVector lookupRange = evaluateLookupRange(args[1]);
 			int index = findIndexOfValue(lookupValue, lookupRange, matchExact, findLargestLessThanOrEqual);
 			return new NumberEval(index + 1); // +1 to convert to 1-based
 		} catch (EvaluationException e) {
@@ -101,19 +102,40 @@
 		}
 	}
 
-	private static ValueEval[] evaluateLookupRange(Eval eval) throws EvaluationException {
+	private static final class SingleValueVector implements ValueVector {
+
+		private final ValueEval _value;
+
+		public SingleValueVector(ValueEval value) {
+			_value = value;
+		}
+
+		public ValueEval getItem(int index) {
+			if (index != 0) {
+				throw new RuntimeException("Invalid index ("
+						+ index + ") only zero is allowed");
+			}
+			return _value;
+		}
+
+		public int getSize() {
+			return 1;
+		}
+	}
+
+	private static ValueVector evaluateLookupRange(Eval eval) throws EvaluationException {
 		if (eval instanceof RefEval) {
 			RefEval re = (RefEval) eval;
-			return new ValueEval[] { re.getInnerValueEval(), };
+			return new SingleValueVector(re.getInnerValueEval());
 		}
 		if (eval instanceof AreaEval) {
-			AreaEval ae = (AreaEval) eval;
-			if(!ae.isColumn() && !ae.isRow()) {
+			ValueVector result = LookupUtils.createVector((AreaEval)eval);
+			if (result == null) {
 				throw new EvaluationException(ErrorEval.NA);
 			}
-			return ae.getValues();
+			return result;
 		}
-		
+
 		// Error handling for lookup_range arg is also unusual
 		if(eval instanceof NumericValueEval) {
 			throw new EvaluationException(ErrorEval.NA);
@@ -133,7 +155,7 @@
 
 
 
-	private static double evaluateMatchTypeArg(Eval arg, int srcCellRow, short srcCellCol) 
+	private static double evaluateMatchTypeArg(Eval arg, int srcCellRow, short srcCellCol)
 			throws EvaluationException {
 		Eval match_type = OperandResolver.getSingleValue(arg, srcCellRow, srcCellCol);
 
@@ -156,28 +178,29 @@
 		}
 		throw new RuntimeException("Unexpected match_type type (" + match_type.getClass().getName() + ")");
 	}
-	
+
 	/**
 	 * @return zero based index
 	 */
-	private static int findIndexOfValue(ValueEval lookupValue, ValueEval[] lookupRange,
+	private static int findIndexOfValue(ValueEval lookupValue, ValueVector lookupRange,
 			boolean matchExact, boolean findLargestLessThanOrEqual) throws EvaluationException {
 
 		LookupValueComparer lookupComparer = createLookupComparer(lookupValue, matchExact);
-		
+
+		int size = lookupRange.getSize();
 		if(matchExact) {
-			for (int i = 0; i < lookupRange.length; i++) {
-				if(lookupComparer.compareTo(lookupRange[i]).isEqual()) {
+			for (int i = 0; i < size; i++) {
+				if(lookupComparer.compareTo(lookupRange.getItem(i)).isEqual()) {
 					return i;
 				}
 			}
 			throw new EvaluationException(ErrorEval.NA);
 		}
-		
+
 		if(findLargestLessThanOrEqual) {
 			// Note - backward iteration
-			for (int i = lookupRange.length - 1; i>=0;  i--) {
-				CompareResult cmp = lookupComparer.compareTo(lookupRange[i]);
+			for (int i = size - 1; i>=0;  i--) {
+				CompareResult cmp = lookupComparer.compareTo(lookupRange.getItem(i));
 				if(cmp.isTypeMismatch()) {
 					continue;
 				}
@@ -187,11 +210,11 @@
 			}
 			throw new EvaluationException(ErrorEval.NA);
 		}
-		
+
 		// else - find smallest greater than or equal to
 		// TODO - is binary search used for (match_type==+1) ?
-		for (int i = 0; i<lookupRange.length; i++) {
-			CompareResult cmp = lookupComparer.compareTo(lookupRange[i]);
+		for (int i = 0; i<size; i++) {
+			CompareResult cmp = lookupComparer.compareTo(lookupRange.getItem(i));
 			if(cmp.isEqual()) {
 				return i;
 			}
@@ -212,7 +235,7 @@
 			if(isLookupValueWild(stringValue)) {
 				throw new RuntimeException("Wildcard lookup values '" + stringValue + "' not supported yet");
 			}
-			
+
 		}
 		return LookupUtils.createLookupComparer(lookupValue);
 	}

Modified: poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/functions/Not.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/functions/Not.java?rev=690299&r1=690298&r2=690299&view=diff
==============================================================================
--- poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/functions/Not.java (original)
+++ poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/functions/Not.java Fri Aug 29 08:27:07 2008
@@ -1,33 +1,27 @@
-/*
-* 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.
-*/
-/*
- * Created on May 9, 2005
- *
- */
+/* ====================================================================
+   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.poi.hssf.record.formula.functions;
 
-import org.apache.poi.hssf.record.formula.eval.AreaEval;
-import org.apache.poi.hssf.record.formula.eval.BlankEval;
 import org.apache.poi.hssf.record.formula.eval.BoolEval;
 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.NumberEval;
-import org.apache.poi.hssf.record.formula.eval.RefEval;
-import org.apache.poi.hssf.record.formula.eval.StringEval;
+import org.apache.poi.hssf.record.formula.eval.EvaluationException;
+import org.apache.poi.hssf.record.formula.eval.OperandResolver;
 import org.apache.poi.hssf.record.formula.eval.ValueEval;
 
 
@@ -37,87 +31,21 @@
  * (treated as a boolean). If the specified arg is a number,
  * then it is true <=> 'number is non-zero'
  */
-public class Not extends BooleanFunction {
-    
-  
-    public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
-        ValueEval retval = null;
-        boolean b = true;
-        ValueEval tempVe = null;
-        
-        switch (operands.length) {
-        default:
-            retval = ErrorEval.VALUE_INVALID;
-            break;
-        case 1:
-            if (operands[0] instanceof AreaEval) {
-                AreaEval ae = (AreaEval) operands[0];
-                if (ae.isRow() && ae.containsColumn(srcCol)) {
-                    ValueEval ve = ae.getValueAt(ae.getFirstRow(), srcCol);
-                    tempVe = singleOperandEvaluate(ve);
-                } else if (ae.isColumn() && ae.containsRow(srcRow)) {
-                    ValueEval ve = ae.getValueAt(srcRow, ae.getFirstColumn());
-                    tempVe = singleOperandEvaluate(ve);
-                } else {
-                    retval = ErrorEval.VALUE_INVALID;
-                }            
-            }
-            else {
-                tempVe = singleOperandEvaluate(operands[0]);
-                if (tempVe instanceof StringEval) {
-                    retval = ErrorEval.VALUE_INVALID;
-                }
-                else if (tempVe instanceof ErrorEval) {
-                    retval = tempVe;
-                }
-            }
-        }
-        
-        if (retval == null) { // if no error
-            if (tempVe instanceof BoolEval) {
-                b = b && ((BoolEval) tempVe).getBooleanValue();
-            }
-            else if (tempVe instanceof StringEval) {
-                retval = ErrorEval.VALUE_INVALID;
-            }
-            else if (tempVe instanceof ErrorEval) {
-                retval = tempVe;
-            }
-            retval = b ? BoolEval.FALSE : BoolEval.TRUE;
-        }
-        
-        return retval;
-    }
-    
-    
-    protected ValueEval singleOperandEvaluate(Eval ve) {
-        ValueEval retval = ErrorEval.VALUE_INVALID;
-        if (ve instanceof RefEval) {
-            RefEval re = (RefEval) ve;
-            retval = singleOperandEvaluate(re.getInnerValueEval());
-        }
-        else if (ve instanceof BoolEval) {
-            retval = (BoolEval) ve;
-        }
-        else if (ve instanceof NumberEval) {
-            NumberEval ne = (NumberEval) ve;
-            retval = ne.getNumberValue() != 0 ? BoolEval.TRUE : BoolEval.FALSE;
-        }
-        else if (ve instanceof StringEval) {
-            StringEval se = (StringEval) ve;
-            String str = se.getStringValue();
-            retval = str.equalsIgnoreCase("true")
-                    ? BoolEval.TRUE
-                    : str.equalsIgnoreCase("false")
-                            ? BoolEval.FALSE
-                            : (ValueEval) ErrorEval.VALUE_INVALID;
-        }
-        else if (ve instanceof BlankEval) {
-            retval = BoolEval.FALSE;
-        }
-        else {
-            retval = ErrorEval.VALUE_INVALID;
-        }
-        return retval;
-    }
+public final class Not implements Function {
+
+	public Eval evaluate(Eval[] args, int srcCellRow, short srcCellCol) {
+		if (args.length != 1) {
+			return ErrorEval.VALUE_INVALID;
+		}
+		boolean boolArgVal;
+		try {
+			ValueEval ve = OperandResolver.getSingleValue(args[0], srcCellRow, srcCellCol);
+			Boolean b = OperandResolver.coerceValueToBoolean(ve, false);
+			boolArgVal = b == null ? false : b.booleanValue();
+		} catch (EvaluationException e) {
+			return e.getErrorEval();
+		}
+		
+		return BoolEval.valueOf(!boolArgVal);
+	}
 }

Modified: poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/functions/Or.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/functions/Or.java?rev=690299&r1=690298&r2=690299&view=diff
==============================================================================
--- poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/functions/Or.java (original)
+++ poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/functions/Or.java Fri Aug 29 08:27:07 2008
@@ -1,81 +1,32 @@
-/*
-* 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.
-*/
-/*
- * Created on May 9, 2005
- *
- */
+/* ====================================================================
+   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.poi.hssf.record.formula.functions;
 
-import org.apache.poi.hssf.record.formula.eval.AreaEval;
-import org.apache.poi.hssf.record.formula.eval.BoolEval;
-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.ValueEval;
-
-public class Or extends BooleanFunction {
-
-    public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
-        ValueEval retval = null;
-        boolean b = false;
-        boolean atleastOneNonBlank = false;
-        
-        /*
-         * Note: do not abort the loop if b is true, since we could be
-         * dealing with errorevals later. 
-         */
-        outer:
-        for (int i=0, iSize=operands.length; i<iSize; i++) {
-            if (operands[i] instanceof AreaEval) {
-                AreaEval ae = (AreaEval) operands[i];
-                ValueEval[] values = ae.getValues();
-                for (int j=0, jSize=values.length; j<jSize; j++) {
-                    ValueEval tempVe = singleOperandEvaluate(values[j], srcRow, srcCol, true);
-                    if (tempVe instanceof BoolEval) {
-                        b = b || ((BoolEval) tempVe).getBooleanValue();
-                        atleastOneNonBlank = true;
-                    }
-                    else if (tempVe instanceof ErrorEval) {
-                        retval = tempVe;
-                        break outer;
-                    }
-                }
-            }
-            else {
-                ValueEval tempVe = singleOperandEvaluate(operands[i], srcRow, srcCol, false);
-                if (tempVe instanceof BoolEval) {
-                    b = b || ((BoolEval) tempVe).getBooleanValue();
-                    atleastOneNonBlank = true;
-                }
-                else if (tempVe instanceof ErrorEval) {
-                    retval = tempVe;
-                    break outer;
-                }
-            }
-        }
-        
-        if (!atleastOneNonBlank) {
-            retval = ErrorEval.VALUE_INVALID;
-        }
-        
-        if (retval == null) { // if no error
-            retval = b ? BoolEval.TRUE : BoolEval.FALSE;
-        }
-        
-        return retval;
-    }
+/**
+ * 
+ */
+public final class Or extends BooleanFunction {
+
+	protected boolean getInitialResultValue() {
+		return false;
+	}
 
+	protected boolean partialEvaluate(boolean cumulativeResult, boolean currentValue) {
+		return cumulativeResult || currentValue;
+	}
 }

Modified: poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/functions/Sumproduct.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/functions/Sumproduct.java?rev=690299&r1=690298&r2=690299&view=diff
==============================================================================
--- poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/functions/Sumproduct.java (original)
+++ poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/functions/Sumproduct.java Fri Aug 29 08:27:07 2008
@@ -22,6 +22,7 @@
 import org.apache.poi.hssf.record.formula.eval.BlankEval;
 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.EvaluationException;
 import org.apache.poi.hssf.record.formula.eval.NumberEval;
 import org.apache.poi.hssf.record.formula.eval.NumericValueEval;
 import org.apache.poi.hssf.record.formula.eval.RefEval;
@@ -53,16 +54,6 @@
  */
 public final class Sumproduct implements Function {
 
-	private static final class EvalEx extends Exception {
-		private final ErrorEval _error;
-
-		public EvalEx(ErrorEval error) {
-			_error = error;
-		}
-		public ErrorEval getError() {
-			return _error;
-		}
-	}
 
 	public Eval evaluate(Eval[] args, int srcCellRow, short srcCellCol) {
 		
@@ -86,14 +77,14 @@
 				}
 				return evaluateAreaSumProduct(args);
 			}
-		} catch (EvalEx e) {
-			return e.getError();
+		} catch (EvaluationException e) {
+			return e.getErrorEval();
 		}
 		throw new RuntimeException("Invalid arg type for SUMPRODUCT: (" 
 				+ firstArg.getClass().getName() + ")");
 	}
 
-	private Eval evaluateSingleProduct(Eval[] evalArgs) throws EvalEx {
+	private static Eval evaluateSingleProduct(Eval[] evalArgs) throws EvaluationException {
 		int maxN = evalArgs.length;
 
 		double term = 1D;
@@ -104,7 +95,7 @@
 		return new NumberEval(term);
 	}
 
-	private double getScalarValue(Eval arg) throws EvalEx {
+	private static double getScalarValue(Eval arg) throws EvaluationException {
 		
 		Eval eval;
 		if (arg instanceof RefEval) {
@@ -121,9 +112,9 @@
 			AreaEval ae = (AreaEval) eval;
 			// an area ref can work as a scalar value if it is 1x1
 			if(!ae.isColumn() || !ae.isRow()) {
-				throw new EvalEx(ErrorEval.VALUE_INVALID);
+				throw new EvaluationException(ErrorEval.VALUE_INVALID);
 			}
-			eval = ae.getValues()[0];
+			eval = ae.getRelativeValue(0, 0);
 		}
 
 		if (!(eval instanceof ValueEval)) {
@@ -134,7 +125,7 @@
 		return getProductTerm((ValueEval) eval, true);
 	}
 
-	private Eval evaluateAreaSumProduct(Eval[] evalArgs) throws EvalEx {
+	private static Eval evaluateAreaSumProduct(Eval[] evalArgs) throws EvaluationException {
 		int maxN = evalArgs.length;
 		AreaEval[] args = new AreaEval[maxN];
 		try {
@@ -147,23 +138,27 @@
 		
 		AreaEval firstArg = args[0];
 		
-		int height = firstArg.getLastRow() - firstArg.getFirstRow() + 1;
-		int width = firstArg.getLastColumn() - firstArg.getFirstColumn() + 1; // TODO - junit
-		
+		int height = firstArg.getHeight();
+		int width = firstArg.getWidth(); // TODO - junit
 		
-
-		double[][][] elements = new double[maxN][][];
-		
-		for (int n = 0; n < maxN; n++) {
-			elements[n] = evaluateArea(args[n], height, width);
+		// first check dimensions
+		if (!areasAllSameSize(args, height, width)) {
+			// normally this results in #VALUE!, 
+			// but errors in individual cells take precedence
+			for (int i = 1; i < args.length; i++) {
+				throwFirstError(args[i]);
+			}
+			return ErrorEval.VALUE_INVALID;
 		}
+
 		double acc = 0;
 		
-		for(int r=0; r<height; r++) {
-			for(int c=0; c<width; c++) {
+		for (int rrIx=0; rrIx<height; rrIx++) {
+			for (int rcIx=0; rcIx<width; rcIx++) {
 				double term = 1D;
 				for(int n=0; n<maxN; n++) {
-					term *= elements[n][r][c];
+					double val = getProductTerm(args[n].getRelativeValue(rrIx, rcIx), false);
+					term *= val;
 				}
 				acc += term;
 			}
@@ -172,60 +167,61 @@
 		return new NumberEval(acc);
 	}
 
-	/**
-	 * @return a 2-D array of the specified height and width corresponding to the evaluated cell 
-	 *  values of the specified areaEval 
-	 * @throws EvalEx if any ErrorEval value was encountered while evaluating the area
-	 */
-	private static double[][] evaluateArea(AreaEval areaEval, int height, int width) throws EvalEx {
-		int fr =areaEval.getFirstRow();
-		int fc =areaEval.getFirstColumn();
-		
-		// check that height and width match
-		if(areaEval.getLastRow() - fr + 1 != height) {
-			throw new EvalEx(ErrorEval.VALUE_INVALID);
-		}
-		if(areaEval.getLastColumn() - fc + 1 != width) {
-			throw new EvalEx(ErrorEval.VALUE_INVALID);
-		}
-		ValueEval[] values = areaEval.getValues();
-		double[][] result = new double[height][width];
-		for(int r=0; r<height; r++) {
-			for(int c=0; c<width; c++) {
-				ValueEval ve = values[r*width + c];
-				result[r][c] = getProductTerm(ve, false);
+	private static void throwFirstError(AreaEval areaEval) throws EvaluationException {
+		int height = areaEval.getHeight();
+		int width = areaEval.getWidth();
+		for (int rrIx=0; rrIx<height; rrIx++) {
+			for (int rcIx=0; rcIx<width; rcIx++) {
+				ValueEval ve = areaEval.getRelativeValue(rrIx, rcIx);
+				if (ve instanceof ErrorEval) {
+					throw new EvaluationException((ErrorEval) ve);
+				}
 			}
 		}
-		return result;
 	}
 
+	private static boolean areasAllSameSize(AreaEval[] args, int height, int width) {
+		for (int i = 0; i < args.length; i++) {
+			AreaEval areaEval = args[i];
+			// check that height and width match
+			if(areaEval.getHeight() != height) {
+				return false;
+			}
+			if(areaEval.getWidth() != width) {
+				return false;
+			}
+		}
+		return true;
+	}
+
+
 	/**
 	 * Determines a <code>double</code> value for the specified <code>ValueEval</code>. 
 	 * @param isScalarProduct <code>false</code> for SUMPRODUCTs over area refs.
-	 * @throws EvalEx if <code>ve</code> represents an error value.
+	 * @throws EvaluationException if <code>ve</code> represents an error value.
 	 * <p/>
 	 * Note - string values and empty cells are interpreted differently depending on 
 	 * <code>isScalarProduct</code>.  For scalar products, if any term is blank or a string, the
 	 * error (#VALUE!) is raised.  For area (sum)products, if any term is blank or a string, the
 	 * result is zero.
 	 */
-	private static double getProductTerm(ValueEval ve, boolean isScalarProduct) throws EvalEx {
+	private static double getProductTerm(ValueEval ve, boolean isScalarProduct) throws EvaluationException {
 
 		if(ve instanceof BlankEval || ve == null) {
 			// TODO - shouldn't BlankEval.INSTANCE be used always instead of null?
 			// null seems to occur when the blank cell is part of an area ref (but not reliably)
 			if(isScalarProduct) {
-				throw new EvalEx(ErrorEval.VALUE_INVALID);
+				throw new EvaluationException(ErrorEval.VALUE_INVALID);
 			}
 			return 0;
 		}
 		
 		if(ve instanceof ErrorEval) {
-			throw new EvalEx((ErrorEval)ve);
+			throw new EvaluationException((ErrorEval)ve);
 		}
 		if(ve instanceof StringEval) {
 			if(isScalarProduct) {
-				throw new EvalEx(ErrorEval.VALUE_INVALID);
+				throw new EvaluationException(ErrorEval.VALUE_INVALID);
 			}
 			// Note for area SUMPRODUCTs, string values are interpreted as zero
 			// even if they would parse as valid numeric values

Modified: poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/functions/Vlookup.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/functions/Vlookup.java?rev=690299&r1=690298&r2=690299&view=diff
==============================================================================
--- poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/functions/Vlookup.java (original)
+++ poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/functions/Vlookup.java Fri Aug 29 08:27:07 2008
@@ -42,40 +42,6 @@
  */
 public final class Vlookup implements Function {
 	
-	private static final class ColumnVector implements ValueVector {
-
-		private final AreaEval _tableArray;
-		private final int _size;
-		private final int _columnAbsoluteIndex;
-		private final int _firstRowAbsoluteIndex;
-
-		public ColumnVector(AreaEval tableArray, int columnIndex) {
-			_columnAbsoluteIndex = tableArray.getFirstColumn() + columnIndex;
-			if(!tableArray.containsColumn((short)_columnAbsoluteIndex)) {
-				int lastColIx =  tableArray.getLastColumn() -  tableArray.getFirstColumn();
-				throw new IllegalArgumentException("Specified column index (" + columnIndex 
-						+ ") is outside the allowed range (0.." + lastColIx + ")");
-			}
-			_tableArray = tableArray;
-			_size = tableArray.getLastRow() - tableArray.getFirstRow() + 1;
-			if(_size < 1) {
-				throw new RuntimeException("bad table array size zero");
-			}
-			_firstRowAbsoluteIndex = tableArray.getFirstRow();
-		}
-
-		public ValueEval getItem(int index) {
-			if(index>_size) {
-				throw new ArrayIndexOutOfBoundsException("Specified index (" + index 
-						+ ") is outside the allowed range (0.." + (_size-1) + ")");
-			}
-			return _tableArray.getValueAt(_firstRowAbsoluteIndex + index, (short)_columnAbsoluteIndex);
-		}
-		public int getSize() {
-			return _size;
-		}
-	}
-
 	public Eval evaluate(Eval[] args, int srcCellRow, short srcCellCol) {
 		Eval arg3 = null;
 		switch(args.length) {
@@ -93,7 +59,7 @@
 			ValueEval lookupValue = OperandResolver.getSingleValue(args[0], srcCellRow, srcCellCol);
 			AreaEval tableArray = LookupUtils.resolveTableArrayArg(args[1]);
 			boolean isRangeLookup = LookupUtils.resolveRangeLookupArg(arg3, srcCellRow, srcCellCol);
-			int rowIndex = LookupUtils.lookupIndexOfValue(lookupValue, new ColumnVector(tableArray, 0), isRangeLookup);
+			int rowIndex = LookupUtils.lookupIndexOfValue(lookupValue, LookupUtils.createColumnVector(tableArray, 0), isRangeLookup);
 			ValueEval veColIndex = OperandResolver.getSingleValue(args[2], srcCellRow, srcCellCol);
 			int colIndex = LookupUtils.resolveRowOrColIndexArg(veColIndex);
 			ValueVector resultCol = createResultColumnVector(tableArray, colIndex);
@@ -113,11 +79,9 @@
 		if(colIndex < 0) {
 			throw EvaluationException.invalidValue();
 		}
-		int nCols = tableArray.getLastColumn() - tableArray.getFirstColumn() + 1;
-		
-		if(colIndex >= nCols) {
+		if(colIndex >= tableArray.getWidth()) {
 			throw EvaluationException.invalidRef();
 		}
-		return new ColumnVector(tableArray, colIndex);
+		return LookupUtils.createColumnVector(tableArray, colIndex);
 	}
 }

Modified: poi/branches/ooxml/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java?rev=690299&r1=690298&r2=690299&view=diff
==============================================================================
--- poi/branches/ooxml/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java (original)
+++ poi/branches/ooxml/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java Fri Aug 29 08:27:07 2008
@@ -296,7 +296,7 @@
 
                 if (cellType != this.cellType)
                 {
-                    frec = new FormulaRecordAggregate(new FormulaRecord(),null);
+                    frec = new FormulaRecordAggregate(new FormulaRecord());
                 }
                 else
                 {
@@ -592,41 +592,27 @@
         int row=record.getRow();
         short col=record.getColumn();
         short styleIndex=record.getXFIndex();
-        //Workbook.currentBook=book;
-        if (formula==null) {
-            setCellType(CELL_TYPE_BLANK,false,row,col,styleIndex);
-        } else {
-            setCellType(CELL_TYPE_FORMULA,false,row,col,styleIndex);
-            FormulaRecordAggregate rec = (FormulaRecordAggregate) record;
-            FormulaRecord frec = rec.getFormulaRecord();
-            frec.setOptions(( short ) 2);
-            frec.setValue(0);
-            
-            //only set to default if there is no extended format index already set
-            if (rec.getXFIndex() == (short)0) rec.setXFIndex(( short ) 0x0f);
-            Ptg[] ptgs = FormulaParser.parse(formula, book);
-            int   size = 0;
-
-            // clear the Ptg Stack
-            for (int i=0, iSize=frec.getNumberOfExpressionTokens(); i<iSize; i++) {
-                frec.popExpressionToken();
-            }
 
-            // fill the Ptg Stack with Ptgs of new formula
-            for (int k = 0; k < ptgs.length; k++) {
-                size += ptgs[ k ].getSize();
-                frec.pushExpressionToken(ptgs[ k ]);
-            }
-            rec.getFormulaRecord().setExpressionLength(( short ) size);
-            //Workbook.currentBook = null;
+        if (formula==null) {
+            setCellType(CELL_TYPE_BLANK, false, row, col, styleIndex);
+            return;
         }
+        setCellType(CELL_TYPE_FORMULA, false, row, col, styleIndex);
+        FormulaRecordAggregate rec = (FormulaRecordAggregate) record;
+        FormulaRecord frec = rec.getFormulaRecord();
+        frec.setOptions((short) 2);
+        frec.setValue(0);
+        
+        //only set to default if there is no extended format index already set
+        if (rec.getXFIndex() == (short)0) {
+			rec.setXFIndex((short) 0x0f);
+		}
+        Ptg[] ptgs = FormulaParser.parse(formula, book);
+        frec.setParsedExpression(ptgs);
     }
 
     public String getCellFormula() {
-        //Workbook.currentBook=book;
-        String retval = FormulaParser.toFormulaString(book, ((FormulaRecordAggregate)record).getFormulaRecord().getParsedExpression());
-        //Workbook.currentBook=null;
-        return retval;
+        return FormulaParser.toFormulaString(book, ((FormulaRecordAggregate)record).getFormulaRecord().getParsedExpression());
     }
 
 

Modified: poi/branches/ooxml/src/java/org/apache/poi/ss/usermodel/FormulaEvaluator.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/java/org/apache/poi/ss/usermodel/FormulaEvaluator.java?rev=690299&r1=690298&r2=690299&view=diff
==============================================================================
--- poi/branches/ooxml/src/java/org/apache/poi/ss/usermodel/FormulaEvaluator.java (original)
+++ poi/branches/ooxml/src/java/org/apache/poi/ss/usermodel/FormulaEvaluator.java Fri Aug 29 08:27:07 2008
@@ -102,7 +102,7 @@
     
     /**
      * Does nothing
-     * @deprecated - not needed, since the current row can be derived from the cell
+     * @deprecated (Aug 2008) - not needed, since the current row can be derived from the cell
      */
     public void setCurrentRow(Row row) {}
 
@@ -437,7 +437,7 @@
             AreaEval ae = (AreaEval) evaluationResult;
             if (ae.isRow()) {
                 if(ae.isColumn()) {
-                    return ae.getValues()[0];
+                    return ae.getRelativeValue(0, 0);
                 }
                 return ae.getValueAt(ae.getFirstRow(), srcColNum);
             }

Modified: poi/branches/ooxml/src/java/org/apache/poi/util/HexDump.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/java/org/apache/poi/util/HexDump.java?rev=690299&r1=690298&r2=690299&view=diff
==============================================================================
--- poi/branches/ooxml/src/java/org/apache/poi/util/HexDump.java (original)
+++ poi/branches/ooxml/src/java/org/apache/poi/util/HexDump.java Fri Aug 29 08:27:07 2008
@@ -1,4 +1,3 @@
-
 /* ====================================================================
    Licensed to the Apache Software Foundation (ASF) under one or more
    contributor license agreements.  See the NOTICE file distributed with
@@ -15,11 +14,17 @@
    See the License for the specific language governing permissions and
    limitations under the License.
 ==================================================================== */
-        
 
 package org.apache.poi.util;
 
-import java.io.*;
+import java.io.BufferedInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintStream;
 import java.text.DecimalFormat;
 
 /**
@@ -29,27 +34,16 @@
  * @author Marc Johnson
  * @author Glen Stampoultzis  (glens at apache.org)
  */
-
-public class HexDump
-{
-    public static final String        EOL         =
-        System.getProperty("line.separator");
-//    private static final StringBuffer _lbuffer    = new StringBuffer(8);
-//    private static final StringBuffer _cbuffer    = new StringBuffer(2);
-    private static final char         _hexcodes[] =
-    {
-        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D',
-        'E', 'F'
-    };
-    private static final int          _shifts[]   =
+public class HexDump {
+    public static final String EOL = System.getProperty("line.separator");
+    private static final char _hexcodes[] = "0123456789ABCDEF".toCharArray();
+    private static final int _shifts[]   =
     {
         60, 56, 52, 48, 44, 40, 36, 32, 28, 24, 20, 16, 12, 8, 4, 0
     };
 
-
-    // all static methods, so no need for a public constructor
-    private HexDump()
-    {
+    private HexDump() {
+        // all static methods, so no need for a public constructor
     }
 
     /**
@@ -69,7 +63,7 @@
      * @exception IllegalArgumentException if the output stream is
      *            null
      */
-    public synchronized static void dump(final byte [] data, final long offset,
+    public static void dump(final byte [] data, final long offset,
                             final OutputStream stream, final int index, final int length)
             throws IOException, ArrayIndexOutOfBoundsException,
                     IllegalArgumentException
@@ -413,6 +407,50 @@
         byte[] data = buf.toByteArray();
         dump(data, 0, out, start, data.length);
     }
+    /**
+     * @return char array of uppercase hex chars, zero padded and prefixed with '0x'
+     */
+    private static char[] toHexChars(long pValue, int nBytes) {
+        int charPos = 2 + nBytes*2;
+        // The return type is char array because most callers will probably append the value to a
+        // StringBuffer, or write it to a Stream / Writer so there is no need to create a String;
+        char[] result = new char[charPos];
+        
+        long value = pValue;
+        do {
+            result[--charPos] = _hexcodes[(int) (value & 0x0F)];
+            value >>>= 4;
+        } while (charPos > 1);
+    
+        // Prefix added to avoid ambiguity
+        result[0] = '0';
+        result[1] = 'x';
+        return result;
+    }
+    /**
+     * @return char array of 4 (zero padded) uppercase hex chars and prefixed with '0x'
+     */
+    public static char[] longToHex(long value) {
+        return toHexChars(value, 8);
+    }
+    /**
+     * @return char array of 4 (zero padded) uppercase hex chars and prefixed with '0x'
+     */
+    public static char[] intToHex(int value) {
+        return toHexChars(value, 4);
+    }
+    /**
+     * @return char array of 2 (zero padded) uppercase hex chars and prefixed with '0x'
+     */
+    public static char[] shortToHex(int value) {
+        return toHexChars(value, 2);
+    }
+    /**
+     * @return char array of 1 (zero padded) uppercase hex chars and prefixed with '0x'
+     */
+    public static char[] byteToHex(int value) {
+        return toHexChars(value, 1);
+    }
 
     public static void main(String[] args) throws Exception {
         File file = new File(args[0]);

Modified: poi/branches/ooxml/src/scratchpad/src/org/apache/poi/hslf/blip/WMF.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/scratchpad/src/org/apache/poi/hslf/blip/WMF.java?rev=690299&r1=690298&r2=690299&view=diff
==============================================================================
--- poi/branches/ooxml/src/scratchpad/src/org/apache/poi/hslf/blip/WMF.java (original)
+++ poi/branches/ooxml/src/scratchpad/src/org/apache/poi/hslf/blip/WMF.java Fri Aug 29 08:27:07 2008
@@ -17,6 +17,7 @@
 package org.apache.poi.hslf.blip;
 
 import org.apache.poi.util.LittleEndian;
+import org.apache.poi.util.POILogger;
 import org.apache.poi.hslf.model.Picture;
 import org.apache.poi.hslf.model.Shape;
 import org.apache.poi.hslf.exceptions.HSLFException;
@@ -76,7 +77,7 @@
         Header header = new Header();
         header.wmfsize = data.length - aldus.getSize();
         header.bounds = new java.awt.Rectangle((short)aldus.left, (short)aldus.top, (short)aldus.right-(short)aldus.left, (short)aldus.bottom-(short)aldus.top);
-        //coefficiaent to translate from WMF dpi to 96pdi
+        //coefficient to translate from WMF dpi to 96pdi
         int coeff = 96*Shape.EMU_PER_POINT/aldus.inch;
         header.size = new java.awt.Dimension(header.bounds.width*coeff, header.bounds.height*coeff);
         header.zipsize = compressed.length;
@@ -119,7 +120,7 @@
      *  <li>short  Checksum;       Checksum value for previous 10 shorts
      * </ul>
      */
-    public static class AldusHeader{
+    public class AldusHeader{
         public static final int APMHEADER_KEY = 0x9AC6CDD7;
 
         public int handle;
@@ -143,8 +144,9 @@
             reserved = LittleEndian.getInt(data, pos); pos += LittleEndian.INT_SIZE;
 
             checksum = LittleEndian.getShort(data, pos); pos += LittleEndian.SHORT_SIZE;
-            if (checksum != getChecksum())
-                throw new HSLFException("WMF checksum does not match the header data");
+            if (checksum != getChecksum()){
+                logger.log(POILogger.WARN, "WMF checksum does not match the header data");
+            }
         }
 
         /**

Modified: poi/branches/ooxml/src/scratchpad/src/org/apache/poi/hslf/dev/PPTXMLDump.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/scratchpad/src/org/apache/poi/hslf/dev/PPTXMLDump.java?rev=690299&r1=690298&r2=690299&view=diff
==============================================================================
--- poi/branches/ooxml/src/scratchpad/src/org/apache/poi/hslf/dev/PPTXMLDump.java (original)
+++ poi/branches/ooxml/src/scratchpad/src/org/apache/poi/hslf/dev/PPTXMLDump.java Fri Aug 29 08:27:07 2008
@@ -125,7 +125,7 @@
                 dump(data, pos, size, padding);
             } else {
                 //dump first 100 bytes of the atom data
-                dump(out, data, pos, Math.min(size, 100), padding, true);
+                dump(out, data, pos, size, padding, true);
             }
 			padding--;
             write(out, "</"+recname + ">" + CR, padding);

Modified: poi/branches/ooxml/src/scratchpad/src/org/apache/poi/hslf/model/ShapeFactory.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/scratchpad/src/org/apache/poi/hslf/model/ShapeFactory.java?rev=690299&r1=690298&r2=690299&view=diff
==============================================================================
--- poi/branches/ooxml/src/scratchpad/src/org/apache/poi/hslf/model/ShapeFactory.java (original)
+++ poi/branches/ooxml/src/scratchpad/src/org/apache/poi/hslf/model/ShapeFactory.java Fri Aug 29 08:27:07 2008
@@ -19,8 +19,10 @@
 import org.apache.poi.ddf.*;
 import org.apache.poi.util.POILogger;
 import org.apache.poi.util.POILogFactory;
+import org.apache.poi.hslf.record.*;
 
 import java.util.List;
+import java.util.Iterator;
 
 /**
  * Create a <code>Shape</code> object depending on its type
@@ -45,14 +47,14 @@
 
     public static ShapeGroup createShapeGroup(EscherContainerRecord spContainer, Shape parent){
         ShapeGroup group = null;
-        UnknownEscherRecord opt = (UnknownEscherRecord)Shape.getEscherChild((EscherContainerRecord)spContainer.getChild(0), (short)0xF122);
+        EscherRecord opt = Shape.getEscherChild((EscherContainerRecord)spContainer.getChild(0), (short)0xF122);
         if(opt != null){
             try {
                 EscherPropertyFactory f = new EscherPropertyFactory();
-                List props = f.createProperties( opt.getData(), 0, opt.getInstance() );
+                List props = f.createProperties( opt.serialize(), 8, opt.getInstance() );
                 EscherSimpleProperty p = (EscherSimpleProperty)props.get(0);
                 if(p.getPropertyNumber() == 0x39F && p.getPropertyValue() == 1){
-                    group = new ShapeGroup(spContainer, parent);
+                    group = new Table(spContainer, parent);
                 } else {
                     group = new ShapeGroup(spContainer, parent);
                 }
@@ -68,7 +70,7 @@
      }
 
     public static Shape createSimpeShape(EscherContainerRecord spContainer, Shape parent){
-        Shape shape;
+        Shape shape = null;
         EscherSpRecord spRecord = spContainer.getChildById(EscherSpRecord.RECORD_ID);
 
         int type = spRecord.getOptions() >> 4;
@@ -76,14 +78,26 @@
             case ShapeTypes.TextBox:
                 shape = new TextBox(spContainer, parent);
                 break;
-            case ShapeTypes.HostControl: 
+            case ShapeTypes.HostControl:
             case ShapeTypes.PictureFrame: {
-                EscherOptRecord opt = (EscherOptRecord)Shape.getEscherChild(spContainer, EscherOptRecord.RECORD_ID);
-                EscherProperty prop = Shape.getEscherProperty(opt, EscherProperties.BLIP__PICTUREID);
-                if(prop != null)
-                    shape = new OLEShape(spContainer, parent); //presence of BLIP__PICTUREID indicates it is an embedded object 
-                else
-                    shape = new Picture(spContainer, parent);
+                InteractiveInfo info = (InteractiveInfo)getClientDataRecord(spContainer, RecordTypes.InteractiveInfo.typeID);
+                OEShapeAtom oes = (OEShapeAtom)getClientDataRecord(spContainer, RecordTypes.OEShapeAtom.typeID);
+                if(info != null && info.getInteractiveInfoAtom() != null){
+                    switch(info.getInteractiveInfoAtom().getAction()){
+                        case InteractiveInfoAtom.ACTION_OLE:
+                            shape = new OLEShape(spContainer, parent);
+                            break;
+                        case InteractiveInfoAtom.ACTION_MEDIA:
+                            shape = new MovieShape(spContainer, parent);
+                            break;
+                        default:
+                            break;
+                    }
+                } else if (oes != null){
+                    shape = new OLEShape(spContainer, parent);
+                }
+                
+                if(shape == null) shape = new Picture(spContainer, parent);
                 break;
             }
             case ShapeTypes.Line:
@@ -108,4 +122,22 @@
         return shape;
 
     }
+
+    protected static Record getClientDataRecord(EscherContainerRecord spContainer, int recordType) {
+        Record oep = null;
+        for (Iterator it = spContainer.getChildRecords().iterator(); it.hasNext();) {
+            EscherRecord obj = (EscherRecord) it.next();
+            if (obj.getRecordId() == EscherClientDataRecord.RECORD_ID) {
+                byte[] data = obj.serialize();
+                Record[] records = Record.findChildRecords(data, 8, data.length - 8);
+                for (int j = 0; j < records.length; j++) {
+                    if (records[j].getRecordType() == recordType) {
+                        return records[j];
+                    }
+                }
+            }
+        }
+        return oep;
+    }
+
 }



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@poi.apache.org
For additional commands, e-mail: commits-help@poi.apache.org


Mime
View raw message