You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by ni...@apache.org on 2008/01/09 00:01:16 UTC

svn commit: r610216 - in /poi/trunk/src: documentation/content/xdocs/ java/org/apache/poi/hssf/record/ java/org/apache/poi/hssf/record/aggregates/ java/org/apache/poi/hssf/record/formula/ scratchpad/testcases/org/apache/poi/hssf/data/ scratchpad/testca...

Author: nick
Date: Tue Jan  8 15:01:12 2008
New Revision: 610216

URL: http://svn.apache.org/viewvc?rev=610216&view=rev
Log:
Finally fix bug #42464 - Expected ExpPtg to be converted from Shared to Non-Shared Formula - tracked down to a signed vs unsigned byte issue!

Added:
    poi/trunk/src/scratchpad/testcases/org/apache/poi/hssf/data/42464-ExpPtg-bad.xls   (with props)
    poi/trunk/src/scratchpad/testcases/org/apache/poi/hssf/data/42464-ExpPtg-ok.xls   (with props)
    poi/trunk/src/scratchpad/testcases/org/apache/poi/hssf/usermodel/TestBug42464.java   (with props)
    poi/trunk/src/testcases/org/apache/poi/hssf/data/42464-ExpPtg-bad.xls   (with props)
    poi/trunk/src/testcases/org/apache/poi/hssf/data/42464-ExpPtg-ok.xls   (with props)
Modified:
    poi/trunk/src/documentation/content/xdocs/changes.xml
    poi/trunk/src/documentation/content/xdocs/status.xml
    poi/trunk/src/java/org/apache/poi/hssf/record/FormulaRecord.java
    poi/trunk/src/java/org/apache/poi/hssf/record/RecordInputStream.java
    poi/trunk/src/java/org/apache/poi/hssf/record/SharedFormulaRecord.java
    poi/trunk/src/java/org/apache/poi/hssf/record/aggregates/FormulaRecordAggregate.java
    poi/trunk/src/java/org/apache/poi/hssf/record/aggregates/ValueRecordsAggregate.java
    poi/trunk/src/java/org/apache/poi/hssf/record/formula/ExpPtg.java

Modified: poi/trunk/src/documentation/content/xdocs/changes.xml
URL: http://svn.apache.org/viewvc/poi/trunk/src/documentation/content/xdocs/changes.xml?rev=610216&r1=610215&r2=610216&view=diff
==============================================================================
--- poi/trunk/src/documentation/content/xdocs/changes.xml (original)
+++ poi/trunk/src/documentation/content/xdocs/changes.xml Tue Jan  8 15:01:12 2008
@@ -36,6 +36,7 @@
 
 		<!-- Don't forget to update status.xml too! -->
         <release version="3.0.2-FINAL" date="2008-??-??">
+            <action dev="POI-DEVELOPERS" type="fix">42464 - Avoid "Expected ExpPtg to be converted from Shared to Non-Shared Formula" on large, formula heavy worksheets</action>
             <action dev="POI-DEVELOPERS" type="add">42033 - Add support for named ranges with unicode names</action>
             <action dev="POI-DEVELOPERS" type="add">34023 - When shifting rows, update formulas on that sheet to point to the new location of those rows</action>
             <action dev="POI-DEVELOPERS" type="add">Support getting all the cells referenced by an AreaReference, not just the corner ones</action>

Modified: poi/trunk/src/documentation/content/xdocs/status.xml
URL: http://svn.apache.org/viewvc/poi/trunk/src/documentation/content/xdocs/status.xml?rev=610216&r1=610215&r2=610216&view=diff
==============================================================================
--- poi/trunk/src/documentation/content/xdocs/status.xml (original)
+++ poi/trunk/src/documentation/content/xdocs/status.xml Tue Jan  8 15:01:12 2008
@@ -33,6 +33,7 @@
 	<!-- Don't forget to update changes.xml too! -->
     <changes>
         <release version="3.0.2-FINAL" date="2008-??-??">
+            <action dev="POI-DEVELOPERS" type="fix">42464 - Avoid "Expected ExpPtg to be converted from Shared to Non-Shared Formula" on large, formula heavy worksheets</action>
             <action dev="POI-DEVELOPERS" type="add">42033 - Add support for named ranges with unicode names</action>
             <action dev="POI-DEVELOPERS" type="add">34023 - When shifting rows, update formulas on that sheet to point to the new location of those rows</action>
             <action dev="POI-DEVELOPERS" type="add">Support getting all the cells referenced by an AreaReference, not just the corner ones</action>

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/FormulaRecord.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/FormulaRecord.java?rev=610216&r1=610215&r2=610216&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/FormulaRecord.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/FormulaRecord.java Tue Jan  8 15:01:12 2008
@@ -199,9 +199,22 @@
     public boolean isSharedFormula() {
         return sharedFormula.isSet(field_5_options);
     }
-    
     public void setSharedFormula(boolean flag) {
     	sharedFormula.setBoolean(field_5_options, flag);
+    }
+    
+    public boolean isAlwaysCalc() {
+    	return alwaysCalc.isSet(field_5_options);
+    }
+    public void setAlwaysCalc(boolean flag) {
+    	alwaysCalc.setBoolean(field_5_options, flag);
+    }
+    
+    public boolean isCalcOnLoad() {
+    	return calcOnLoad.isSet(field_5_options);
+    }
+    public void setCalcOnLoad(boolean flag) {
+    	calcOnLoad.setBoolean(field_5_options, flag);
     }
     
     /**

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/RecordInputStream.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/RecordInputStream.java?rev=610216&r1=610215&r2=610216&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/RecordInputStream.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/RecordInputStream.java Tue Jan  8 15:01:12 2008
@@ -133,6 +133,9 @@
     }    
   }
   
+  /**
+   * Reads an 8 bit, signed value
+   */
   public byte readByte() {
     checkRecordPosition();
     
@@ -141,7 +144,10 @@
     pos += 1;
     return result;
   }
-
+  
+  /**
+   * Reads a 16 bit, signed value
+   */
   public short readShort() {
     checkRecordPosition();
     
@@ -169,6 +175,21 @@
     return result;
   }
 
+  /**
+   * Reads an 8 bit, unsigned value
+   */
+  public short readUByte() {
+	  short s = readByte();
+	  if(s < 0) {
+		  s += 256;
+	  }
+	  return s;
+  }
+
+  /**
+   * Reads a 16 bit,un- signed value.
+   * @return
+   */
   public int readUShort() {
     checkRecordPosition();    
     

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/SharedFormulaRecord.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/SharedFormulaRecord.java?rev=610216&r1=610215&r2=610216&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/SharedFormulaRecord.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/SharedFormulaRecord.java Tue Jan  8 15:01:12 2008
@@ -20,10 +20,8 @@
 package org.apache.poi.hssf.record;
 
 import java.util.Stack;
-import java.util.List;
 
 import org.apache.poi.hssf.record.formula.*;
-import org.apache.poi.util.LittleEndian;
 
 /**
  * Title:        SharedFormulaRecord
@@ -156,15 +154,12 @@
         return sid;
     }
 
-	 /**
-	  * Shared formulas are to treated like unknown records, and as a result d
-	  */
     protected void fillFields(RecordInputStream in)
     {
       field_1_first_row       = in.readShort();
       field_2_last_row        = in.readShort();
-      field_3_first_column    = in.readByte();
-      field_4_last_column     = in.readByte();
+      field_3_first_column    = in.readUByte();
+      field_4_last_column     = in.readUByte();
       field_5_reserved        = in.readShort();
       field_6_expression_len = in.readShort();
       field_7_parsed_expr    = getParsedExpressionTokens(in);
@@ -181,6 +176,9 @@
         return stack;
     }
 
+    /**
+     * Are we shared by the supplied formula record?
+     */
     public boolean isFormulaInShared(FormulaRecord formula) {
       final int formulaRow = formula.getRow();
       final int formulaColumn = formula.getColumn();

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/aggregates/FormulaRecordAggregate.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/aggregates/FormulaRecordAggregate.java?rev=610216&r1=610215&r2=610216&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/aggregates/FormulaRecordAggregate.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/aggregates/FormulaRecordAggregate.java Tue Jan  8 15:01:12 2008
@@ -99,7 +99,7 @@
     {
         this.formulaRecord = formulaRecord;
     }
-
+    
     public FormulaRecord getFormulaRecord()
     {
         return formulaRecord;
@@ -109,7 +109,7 @@
     {
         return stringRecord;
     }
-
+    
     public boolean isEqual(CellValueRecordInterface i)
     {
         return formulaRecord.isEqual( i );

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/aggregates/ValueRecordsAggregate.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/aggregates/ValueRecordsAggregate.java?rev=610216&r1=610215&r2=610216&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/aggregates/ValueRecordsAggregate.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/aggregates/ValueRecordsAggregate.java Tue Jan  8 15:01:12 2008
@@ -127,8 +127,17 @@
 
         FormulaRecordAggregate lastFormulaAggregate = null;
         
+        // First up, locate all the shared formulas
         List sharedFormulas = new java.util.ArrayList();
+        for (k = offset; k < records.size(); k++)
+        {
+            Record rec = ( Record ) records.get(k);
+            if (rec instanceof SharedFormulaRecord) {
+            	sharedFormulas.add(rec);
+            }
+        }
 
+        // Now do the main processing sweep
         for (k = offset; k < records.size(); k++)
         {
             Record rec = ( Record ) records.get(k);
@@ -137,18 +146,14 @@
             {
                 break;
             } else if (rec instanceof SharedFormulaRecord) {
-            	sharedFormulas.add(rec);
+            	// Already handled, not to worry
             } else if (rec instanceof FormulaRecord)
             {
               FormulaRecord formula = (FormulaRecord)rec;
               if (formula.isSharedFormula()) {
-                Record nextRecord = (Record) records.get(k + 1);
-                if (nextRecord instanceof SharedFormulaRecord) {
-                	sharedFormulas.add(nextRecord);
-                	k++;
-                }
-                //traverse the list of shared formulas in reverse order, and try to find the correct one
-                //for us
+                // Traverse the list of shared formulas in
+            	//  reverse order, and try to find the correct one
+                //  for us
                 boolean found = false;
                 for (int i=sharedFormulas.size()-1;i>=0;i--) {
                 	SharedFormulaRecord shrd = (SharedFormulaRecord)sharedFormulas.get(i);

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/formula/ExpPtg.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/formula/ExpPtg.java?rev=610216&r1=610215&r2=610216&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/formula/ExpPtg.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/formula/ExpPtg.java Tue Jan  8 15:01:12 2008
@@ -75,7 +75,7 @@
 
     public String toFormulaString(Workbook book)
     {
-        throw new RecordFormatException("Coding Error: Expected ExpPtg to be converted from Shared to Non-Shared Formula");
+        throw new RecordFormatException("Coding Error: Expected ExpPtg to be converted from Shared to Non-Shared Formula by ValueRecordsAggregate, but it wasn't");
     }
     
     public String toString()

Added: poi/trunk/src/scratchpad/testcases/org/apache/poi/hssf/data/42464-ExpPtg-bad.xls
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/testcases/org/apache/poi/hssf/data/42464-ExpPtg-bad.xls?rev=610216&view=auto
==============================================================================
Binary file - no diff available.

Propchange: poi/trunk/src/scratchpad/testcases/org/apache/poi/hssf/data/42464-ExpPtg-bad.xls
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: poi/trunk/src/scratchpad/testcases/org/apache/poi/hssf/data/42464-ExpPtg-ok.xls
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/testcases/org/apache/poi/hssf/data/42464-ExpPtg-ok.xls?rev=610216&view=auto
==============================================================================
Binary file - no diff available.

Propchange: poi/trunk/src/scratchpad/testcases/org/apache/poi/hssf/data/42464-ExpPtg-ok.xls
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: poi/trunk/src/scratchpad/testcases/org/apache/poi/hssf/usermodel/TestBug42464.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/testcases/org/apache/poi/hssf/usermodel/TestBug42464.java?rev=610216&view=auto
==============================================================================
--- poi/trunk/src/scratchpad/testcases/org/apache/poi/hssf/usermodel/TestBug42464.java (added)
+++ poi/trunk/src/scratchpad/testcases/org/apache/poi/hssf/usermodel/TestBug42464.java Tue Jan  8 15:01:12 2008
@@ -0,0 +1,93 @@
+/* ====================================================================
+   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.usermodel;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.poi.hssf.record.FormulaRecord;
+import org.apache.poi.hssf.record.aggregates.FormulaRecordAggregate;
+import org.apache.poi.hssf.record.formula.ExpPtg;
+import org.apache.poi.hssf.util.CellReference;
+
+import junit.framework.TestCase;
+
+public class TestBug42464 extends TestCase {
+	String dirname;
+
+	protected void setUp() throws Exception {
+		super.setUp();
+		dirname = System.getProperty("HSSF.testdata.path");
+	}
+
+	public void testOKFile() throws Exception {
+		HSSFWorkbook wb = new HSSFWorkbook(
+				new FileInputStream(new File(dirname,"42464-ExpPtg-ok.xls"))
+		);
+		process(wb);
+	}
+	public void testExpSharedBadFile() throws Exception {
+		HSSFWorkbook wb = new HSSFWorkbook(
+				new FileInputStream(new File(dirname,"42464-ExpPtg-bad.xls"))
+		);
+		process(wb);
+	}
+	
+	protected void process(HSSFWorkbook wb) {
+		for(int i=0; i<wb.getNumberOfSheets(); i++) {
+			HSSFSheet s = wb.getSheetAt(i);
+			HSSFFormulaEvaluator eval =
+				new HSSFFormulaEvaluator(s, wb);
+			
+			Iterator it = s.rowIterator();
+			while(it.hasNext()) {
+				HSSFRow r = (HSSFRow)it.next();
+				eval.setCurrentRow(r);
+				process(r, eval);
+			}
+		}
+	}
+	
+	protected void process(HSSFRow row, HSSFFormulaEvaluator eval) {
+		Iterator it = row.cellIterator();
+		while(it.hasNext()) {
+			HSSFCell cell = (HSSFCell)it.next();
+			if(cell.getCellType() == HSSFCell.CELL_TYPE_FORMULA) {
+				FormulaRecordAggregate record = (FormulaRecordAggregate)
+					cell.getCellValueRecord();
+				FormulaRecord r = record.getFormulaRecord();
+				List ptgs = r.getParsedExpression();
+				
+				String cellRef = (new CellReference(row.getRowNum(), cell.getCellNum())).toString();
+				if(cellRef.equals("BP24")) {
+					System.out.print(cellRef);
+					System.out.println(" - has " + r.getNumberOfExpressionTokens() + " ptgs over " + r.getExpressionLength()  + " tokens:");
+					for(int i=0; i<ptgs.size(); i++) {
+						String c = ptgs.get(i).getClass().toString();
+						System.out.println("\t" + c.substring(c.lastIndexOf('.')+1) );
+					}
+					System.out.println("-> " + cell.getCellFormula());
+				}
+				
+				eval.evaluate(cell);
+				
+			}
+		}
+	}
+}

Propchange: poi/trunk/src/scratchpad/testcases/org/apache/poi/hssf/usermodel/TestBug42464.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: poi/trunk/src/testcases/org/apache/poi/hssf/data/42464-ExpPtg-bad.xls
URL: http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/hssf/data/42464-ExpPtg-bad.xls?rev=610216&view=auto
==============================================================================
Binary file - no diff available.

Propchange: poi/trunk/src/testcases/org/apache/poi/hssf/data/42464-ExpPtg-bad.xls
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: poi/trunk/src/testcases/org/apache/poi/hssf/data/42464-ExpPtg-ok.xls
URL: http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/hssf/data/42464-ExpPtg-ok.xls?rev=610216&view=auto
==============================================================================
Binary file - no diff available.

Propchange: poi/trunk/src/testcases/org/apache/poi/hssf/data/42464-ExpPtg-ok.xls
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream



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