]> source.dussan.org Git - poi.git/commitdiff
Patch largely from Josh from bug #44539 - Support for area references in formulas...
authorNick Burch <nick@apache.org>
Fri, 7 Mar 2008 12:06:18 +0000 (12:06 +0000)
committerNick Burch <nick@apache.org>
Fri, 7 Mar 2008 12:06:18 +0000 (12:06 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@634630 13f79535-47bb-0310-9956-ffa450edef68

27 files changed:
src/documentation/content/xdocs/changes.xml
src/documentation/content/xdocs/status.xml
src/java/org/apache/poi/hssf/record/SharedFormulaRecord.java
src/java/org/apache/poi/hssf/record/formula/Area3DPtg.java
src/java/org/apache/poi/hssf/record/formula/AreaAPtg.java
src/java/org/apache/poi/hssf/record/formula/AreaI.java
src/java/org/apache/poi/hssf/record/formula/AreaPtg.java
src/java/org/apache/poi/hssf/record/formula/AreaVPtg.java
src/java/org/apache/poi/hssf/record/formula/Ref3DPtg.java
src/java/org/apache/poi/hssf/record/formula/RefAPtg.java
src/java/org/apache/poi/hssf/record/formula/RefVPtg.java
src/java/org/apache/poi/hssf/record/formula/ReferencePtg.java
src/java/org/apache/poi/hssf/usermodel/HSSFRow.java
src/java/org/apache/poi/hssf/util/AreaReference.java
src/java/org/apache/poi/hssf/util/CellReference.java
src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/Area2DEval.java
src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/Area3DEval.java
src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/AreaEval.java
src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/Ref2DEval.java
src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/Ref3DEval.java
src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/RefEval.java
src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/LookupUtils.java
src/scratchpad/src/org/apache/poi/hssf/usermodel/HSSFFormulaEvaluator.java
src/scratchpad/testcases/org/apache/poi/hssf/model/TestFormulaParserSP.java
src/scratchpad/testcases/org/apache/poi/hssf/usermodel/TestBug44410.java
src/testcases/org/apache/poi/hssf/model/TestFormulaParser.java
src/testcases/org/apache/poi/hssf/record/formula/TestAreaPtg.java

index 9eb163fc8725c589c96275f03c6ed6f47e8ffb36..c355afd440bee9a3842bd28cdcd6e8bd7759e850 100644 (file)
@@ -36,6 +36,7 @@
 
                <!-- Don't forget to update status.xml too! -->
         <release version="3.1-beta1" date="2008-??-??">
+           <action dev="POI-DEVELOPERS" type="add">44539 - Support for area references in formulas of rows >= 32768</action>
            <action dev="POI-DEVELOPERS" type="add">44536 - Improved support for detecting read-only recommended files</action>
            <action dev="POI-DEVELOPERS" type="fix">43901 - Correctly update the internal last cell number when adding and removing cells (previously sometimes off-by-one)</action>
            <action dev="POI-DEVELOPERS" type="fix">28231 - For apparently truncated files, which are somehow still valid, now issue a truncation warning but carry on, rather than giving an exception as before</action>
index 201c4936d92995d70da800e71c2a8c2932481014..c59cae1a3da4b4ed1d9e1f03d2183e9b40a96bc1 100644 (file)
@@ -33,6 +33,7 @@
        <!-- Don't forget to update changes.xml too! -->
     <changes>
         <release version="3.1-beta1" date="2008-??-??">
+           <action dev="POI-DEVELOPERS" type="add">44539 - Support for area references in formulas of rows >= 32768</action>
            <action dev="POI-DEVELOPERS" type="add">44536 - Improved support for detecting read-only recommended files</action>
            <action dev="POI-DEVELOPERS" type="fix">43901 - Correctly update the internal last cell number when adding and removing cells (previously sometimes off-by-one)</action>
            <action dev="POI-DEVELOPERS" type="fix">44504 - Added initial support for recognising external functions like YEARFRAC and ISEVEN (using NameXPtg), via LinkTable support</action>
index ae250246d3a4e7b5141a366c3b1ffffa4886c43e..b2fd9ae4f55ea1a3349daeb03b143c0b312f9135 100755 (executable)
@@ -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,8 +14,7 @@
    See the License for the specific language governing permissions and
    limitations under the License.
 ==================================================================== */
-        
-
 package org.apache.poi.hssf.record;
 
 import java.util.Stack;
@@ -34,10 +32,7 @@ import org.apache.poi.hssf.record.formula.*;
  * record types.
  * @author Danny Mui at apache dot org
  */
-
-public class SharedFormulaRecord
-    extends Record
-{
+public final class SharedFormulaRecord extends Record {
         public final static short   sid = 0x4BC;
     
     private int               field_1_first_row;
@@ -58,15 +53,15 @@ public class SharedFormulaRecord
 
     public SharedFormulaRecord(RecordInputStream in)
     {
-         super(in);
+          super(in);
     }
     
     protected void validateSid(short id)
     {
-               if (id != this.sid)
-               {
-                       throw new RecordFormatException("Not a valid SharedFormula");
-               }        
+        if (id != this.sid)
+        {
+            throw new RecordFormatException("Not a valid SharedFormula");
+        }        
     }    
     
     public int getFirstRow() {
@@ -96,14 +91,14 @@ public class SharedFormulaRecord
 
     public int serialize(int offset, byte [] data)
     {
-       //Because this record is converted to individual Formula records, this method is not required.
-       throw new UnsupportedOperationException("Cannot serialize a SharedFormulaRecord");
+        //Because this record is converted to individual Formula records, this method is not required.
+        throw new UnsupportedOperationException("Cannot serialize a SharedFormulaRecord");
     }
 
     public int getRecordSize()
     {
-       //Because this record is converted to individual Formula records, this method is not required.
-       throw new UnsupportedOperationException("Cannot get the size for a SharedFormulaRecord");
+        //Because this record is converted to individual Formula records, this method is not required.
+        throw new UnsupportedOperationException("Cannot get the size for a SharedFormulaRecord");
 
     }
 
@@ -257,39 +252,40 @@ public class SharedFormulaRecord
       }
     }
     
-    private short fixupRelativeColumn(int currentcolumn, short column, boolean relative) {
-       if(relative) {
-               if((column&128)!=0) column=(short)(column-256);
-               column+=currentcolumn;
-       }
-       return column;
-       }
-
-       private short fixupRelativeRow(int currentrow, short row, boolean relative) {
-               if(relative) {
-                       row+=currentrow;
-               }
-               return row;
-       }
-
-       /**
-        * Mirroring formula records so it is registered in the ValueRecordsAggregate
-        */
-       public boolean isInValueSection()
-       {
-                return true;
-       }
-
-
-        /**
-         * Register it in the ValueRecordsAggregate so it can go into the FormulaRecordAggregate
-         */
-        public boolean isValue() {
-               return true;
-        }
+    private int fixupRelativeColumn(int currentcolumn, int column, boolean relative) {
+        if(relative) {
+            // mask out upper bits to produce 'wrapping' at column 256 ("IV")
+            return (column + currentcolumn) & 0x00FF;
+        }
+        return column;
+    }
+
+    private int fixupRelativeRow(int currentrow, int row, boolean relative) {
+        if(relative) {
+            // mask out upper bits to produce 'wrapping' at row 65536
+            return (row+currentrow) & 0x00FFFF;
+        }
+        return row;
+    }
+
+    /**
+     * Mirroring formula records so it is registered in the ValueRecordsAggregate
+     */
+    public boolean isInValueSection()
+    {
+         return true;
+    }
+
+
+     /**
+      * Register it in the ValueRecordsAggregate so it can go into the FormulaRecordAggregate
+      */
+     public boolean isValue() {
+         return true;
+     }
 
     public Object clone() {
-       //Because this record is converted to individual Formula records, this method is not required.
-       throw new UnsupportedOperationException("Cannot clone a SharedFormulaRecord");
+        //Because this record is converted to individual Formula records, this method is not required.
+        throw new UnsupportedOperationException("Cannot clone a SharedFormulaRecord");
     }
 }
index c3de3758f5f27cb7bb48ff0bcb4b89853efb9261..33278e25edceb844f78adbfbe9ac351cf8d7a904 100644 (file)
@@ -41,10 +41,10 @@ public class Area3DPtg extends Ptg implements AreaI
        public final static byte sid = 0x3b;
        private final static int SIZE = 11; // 10 + 1 for Ptg
        private short field_1_index_extern_sheet;
-       private short field_2_first_row;
-       private short field_3_last_row;
-       private short field_4_first_column;
-       private short field_5_last_column;
+       private int field_2_first_row;
+       private int field_3_last_row;
+       private int field_4_first_column;
+       private int field_5_last_column;
 
        private BitField rowRelative = BitFieldFactory.getInstance( 0x8000 );
        private BitField colRelative = BitFieldFactory.getInstance( 0x4000 );
@@ -64,27 +64,27 @@ public class Area3DPtg extends Ptg implements AreaI
        public Area3DPtg(RecordInputStream in)
        {
                field_1_index_extern_sheet = in.readShort();
-               field_2_first_row = in.readShort();
-               field_3_last_row = in.readShort();
-               field_4_first_column = in.readShort();
-               field_5_last_column = in.readShort();
+               field_2_first_row = in.readUShort();
+               field_3_last_row = in.readUShort();
+               field_4_first_column = in.readUShort();
+               field_5_last_column = in.readUShort();
        }
 
        public Area3DPtg(short firstRow, short lastRow, short firstColumn, short lastColumn,
-               boolean firstRowRelative, boolean lastRowRelative, boolean firstColRelative, boolean lastColRelative,
-               short externalSheetIndex) {
-             setFirstRow(firstRow);
-             setLastRow(lastRow);
-             setFirstColumn(firstColumn);
-             setLastColumn(lastColumn);
-             setFirstRowRelative(firstRowRelative);
-             setLastRowRelative(lastRowRelative);
-             setFirstColRelative(firstColRelative);
-             setLastColRelative(lastColRelative);
-             setExternSheetIndex(externalSheetIndex);
-    }
-
-    public String toString()
+                       boolean firstRowRelative, boolean lastRowRelative, boolean firstColRelative, boolean lastColRelative,
+                       short externalSheetIndex) {
+                 setFirstRow(firstRow);
+                 setLastRow(lastRow);
+                 setFirstColumn(firstColumn);
+                 setLastColumn(lastColumn);
+                 setFirstRowRelative(firstRowRelative);
+                 setLastRowRelative(lastRowRelative);
+                 setFirstColRelative(firstColRelative);
+                 setLastColRelative(lastColRelative);
+                 setExternSheetIndex(externalSheetIndex);
+       }
+
+       public String toString()
        {
                StringBuffer buffer = new StringBuffer();
 
@@ -99,7 +99,7 @@ public class Area3DPtg extends Ptg implements AreaI
                buffer.append( "lastColRowRel = "
                                + isLastRowRelative() ).append( "\n" );
                buffer.append( "firstColRel   = " + isFirstColRelative() ).append( "\n" );
-               buffer.append( "lastColRel    = " + isLastColRelative() ).append( "\n" );
+               buffer.append( "lastColRel      = " + isLastColRelative() ).append( "\n" );
                return buffer.toString();
        }
 
@@ -107,10 +107,10 @@ public class Area3DPtg extends Ptg implements AreaI
        {
                array[0 + offset] = (byte) ( sid + ptgClass );
                LittleEndian.putShort( array, 1 + offset, getExternSheetIndex() );
-               LittleEndian.putShort( array, 3 + offset, getFirstRow() );
-               LittleEndian.putShort( array, 5 + offset, getLastRow() );
-               LittleEndian.putShort( array, 7 + offset, getFirstColumnRaw() );
-               LittleEndian.putShort( array, 9 + offset, getLastColumnRaw() );
+               LittleEndian.putShort( array, 3 + offset, (short)getFirstRow() );
+               LittleEndian.putShort( array, 5 + offset, (short)getLastRow() );
+               LittleEndian.putShort( array, 7 + offset, (short)getFirstColumnRaw() );
+               LittleEndian.putShort( array, 9 + offset, (short)getLastColumnRaw() );
        }
 
        public int getSize()
@@ -128,32 +128,32 @@ public class Area3DPtg extends Ptg implements AreaI
                field_1_index_extern_sheet = index;
        }
 
-       public short getFirstRow()
+       public int getFirstRow()
        {
                return field_2_first_row;
        }
 
-       public void setFirstRow( short row )
+       public void setFirstRow( int row )
        {
                field_2_first_row = row;
        }
 
-       public short getLastRow()
+       public int getLastRow()
        {
                return field_3_last_row;
        }
 
-       public void setLastRow( short row )
+       public void setLastRow( int row )
        {
                field_3_last_row = row;
        }
 
-       public short getFirstColumn()
+       public int getFirstColumn()
        {
-               return (short) ( field_4_first_column & 0xFF );
+               return field_4_first_column & 0xFF;
        }
 
-       public short getFirstColumnRaw()
+       public int getFirstColumnRaw()
        {
                return field_4_first_column;
        }
@@ -179,12 +179,12 @@ public class Area3DPtg extends Ptg implements AreaI
                field_4_first_column = column;
        }
 
-       public short getLastColumn()
+       public int getLastColumn()
        {
-               return (short) ( field_5_last_column & 0xFF );
+               return field_5_last_column & 0xFF;
        }
 
-       public short getLastColumnRaw()
+       public int getLastColumnRaw()
        {
                return field_5_last_column;
        }
@@ -216,7 +216,7 @@ public class Area3DPtg extends Ptg implements AreaI
         */
        public void setFirstRowRelative( boolean rel )
        {
-               field_4_first_column = rowRelative.setShortBoolean( field_4_first_column, rel );
+               field_4_first_column = rowRelative.setBoolean( field_4_first_column, rel );
        }
 
        /**
@@ -224,7 +224,7 @@ public class Area3DPtg extends Ptg implements AreaI
         */
        public void setFirstColRelative( boolean rel )
        {
-               field_4_first_column = colRelative.setShortBoolean( field_4_first_column, rel );
+               field_4_first_column = colRelative.setBoolean( field_4_first_column, rel );
        }
 
        /**
@@ -233,7 +233,7 @@ public class Area3DPtg extends Ptg implements AreaI
         */
        public void setLastRowRelative( boolean rel )
        {
-               field_5_last_column = rowRelative.setShortBoolean( field_5_last_column, rel );
+               field_5_last_column = rowRelative.setBoolean( field_5_last_column, rel );
        }
 
        /**
@@ -241,7 +241,7 @@ public class Area3DPtg extends Ptg implements AreaI
         */
        public void setLastColRelative( boolean rel )
        {
-               field_5_last_column = colRelative.setShortBoolean( field_5_last_column, rel );
+               field_5_last_column = colRelative.setBoolean( field_5_last_column, rel );
        }
 
 
@@ -259,20 +259,20 @@ public class Area3DPtg extends Ptg implements AreaI
                CellReference frstCell = ar.getFirstCell();
                CellReference lastCell = ar.getLastCell();
 
-               setFirstRow(    (short) frstCell.getRow() );
-               setFirstColumn(         frstCell.getCol() );
-               setLastRow(     (short) lastCell.getRow() );
-               setLastColumn(          lastCell.getCol() );
+               setFirstRow(    (short) frstCell.getRow() );
+               setFirstColumn(          frstCell.getCol() );
+               setLastRow(      (short) lastCell.getRow() );
+               setLastColumn(            lastCell.getCol() );
                setFirstColRelative( !frstCell.isColAbsolute() );
                setLastColRelative(  !lastCell.isColAbsolute() );
                setFirstRowRelative( !frstCell.isRowAbsolute() );
                setLastRowRelative(  !lastCell.isRowAbsolute() );
        }
 
-    /**
-     * @return text representation of this area reference that can be used in text
-     *  formulas. The sheet name will get properly delimited if required.
-     */
+       /**
+        * @return text representation of this area reference that can be used in text
+        *  formulas. The sheet name will get properly delimited if required.
+        */
        public String toFormulaString(Workbook book)
        {
                // First do the sheet name
@@ -303,7 +303,7 @@ public class Area3DPtg extends Ptg implements AreaI
                ptg.field_3_last_row = field_3_last_row;
                ptg.field_4_first_column = field_4_first_column;
                ptg.field_5_last_column = field_5_last_column;
-            ptg.setClass(ptgClass);
+               ptg.setClass(ptgClass);
                return ptg;
        }
 
index 57628f19b8825178fdfab9d8324711dd98a8d85d..515d07dd41535e64601be7c90be6dfcadb8390eb 100644 (file)
@@ -36,16 +36,14 @@ import org.apache.poi.hssf.model.Workbook;
  * @author Jason Height (jheight at chariot dot net dot au)
  */
 
-public class AreaAPtg
-    extends AreaPtg
-{
+public final class AreaAPtg extends AreaPtg {
     public final static short sid  = 0x65;
 
     protected AreaAPtg() {
       //Required for clone methods
     }
 
-    public AreaAPtg(short firstRow, short lastRow, short firstColumn, short lastColumn, boolean firstRowRelative, boolean lastRowRelative, boolean firstColRelative, boolean lastColRelative) {
+    public AreaAPtg(int firstRow, int lastRow, int firstColumn, int lastColumn, boolean firstRowRelative, boolean lastRowRelative, boolean firstColRelative, boolean lastColRelative) {
       super(firstRow, lastRow, firstColumn, lastColumn, firstRowRelative, lastRowRelative, firstColRelative, lastColRelative);
     }
 
index 974ff95f062130963edd99249aa5f7411ec8e36f..5a0a21e861501abb318d144929c72e94e344cea7 100644 (file)
@@ -24,22 +24,22 @@ public interface AreaI {
     /**
      * @return the first row in the area
      */
-    public short getFirstRow();
+    public int getFirstRow();
 
     /**
      * @return last row in the range (x2 in x1,y1-x2,y2)
      */
-    public short getLastRow();
+    public int getLastRow();
     
     /**
      * @return the first column number in the area.
      */
-    public short getFirstColumn();
+    public int getFirstColumn();
     
     /**
      * @return lastcolumn in the area
      */
-    public short getLastColumn();
+    public int getLastColumn();
     
     /**
      * @return isrelative first column to relative or not
index ae408c34c7cffe1f3c9e7e3b0a67d919b9556f77..be34e0074a3139547467be6ac203d334535d4306 100644 (file)
@@ -38,10 +38,14 @@ public class AreaPtg
 {
     public final static short sid  = 0x25;
     private final static int  SIZE = 9;
-    private short             field_1_first_row;
-    private short             field_2_last_row;
-    private short             field_3_first_column;
-    private short             field_4_last_column;
+    /** zero based, unsigned 16 bit */
+    private int             field_1_first_row;
+    /** zero based, unsigned 16 bit */
+    private int             field_2_last_row;
+    /** zero based, unsigned 8 bit */
+    private int             field_3_first_column;
+    /** zero based, unsigned 8 bit */
+    private int             field_4_last_column;
     
     private final static BitField   rowRelative = BitFieldFactory.getInstance(0x8000);
     private final static BitField   colRelative = BitFieldFactory.getInstance(0x4000);
@@ -55,9 +59,9 @@ public class AreaPtg
         AreaReference ar = new AreaReference(arearef);
         CellReference firstCell = ar.getFirstCell();
         CellReference lastCell = ar.getLastCell();
-        setFirstRow((short)firstCell.getRow());
+        setFirstRow(firstCell.getRow());
         setFirstColumn(firstCell.getCol());
-        setLastRow((short)lastCell.getRow());
+        setLastRow(lastCell.getRow());
         setLastColumn(lastCell.getCol());
         setFirstColRelative(!firstCell.isColAbsolute());
         setLastColRelative(!lastCell.isColAbsolute());
@@ -65,7 +69,13 @@ public class AreaPtg
         setLastRowRelative(!lastCell.isRowAbsolute());        
     }
     
-    public AreaPtg(short firstRow, short lastRow, short firstColumn, short lastColumn, boolean firstRowRelative, boolean lastRowRelative, boolean firstColRelative, boolean lastColRelative) {
+    public AreaPtg(int firstRow, int lastRow, int firstColumn, int lastColumn,
+            boolean firstRowRelative, boolean lastRowRelative, boolean firstColRelative, boolean lastColRelative) {
+        
+        checkColumnBounds(firstColumn);
+        checkColumnBounds(lastColumn);
+        checkRowBounds(firstRow);
+        checkRowBounds(lastRow);
       setFirstRow(firstRow);
       setLastRow(lastRow);
       setFirstColumn(firstColumn);
@@ -76,12 +86,23 @@ public class AreaPtg
       setLastColRelative(lastColRelative);
     }    
 
+    private static void checkColumnBounds(int colIx) {
+        if((colIx & 0x0FF) != colIx) {
+            throw new IllegalArgumentException("colIx (" + colIx + ") is out of range");
+        }
+    }
+    private static void checkRowBounds(int rowIx) {
+        if((rowIx & 0x0FFFF) != rowIx) {
+            throw new IllegalArgumentException("rowIx (" + rowIx + ") is out of range");
+        }
+    }
+
     public AreaPtg(RecordInputStream in)
     {
-        field_1_first_row    = in.readShort();
-        field_2_last_row     = in.readShort();
-        field_3_first_column = in.readShort();
-        field_4_last_column  = in.readShort();
+        field_1_first_row    = in.readUShort();
+        field_2_last_row     = in.readUShort();
+        field_3_first_column = in.readUShort();
+        field_4_last_column  = in.readUShort();
         //System.out.println(toString());
     }
     
@@ -110,10 +131,10 @@ public class AreaPtg
 
     public void writeBytes(byte [] array, int offset) {
         array[offset] = (byte) (sid + ptgClass);
-        LittleEndian.putShort(array,offset+1,field_1_first_row);
-        LittleEndian.putShort(array,offset+3,field_2_last_row);
-        LittleEndian.putShort(array,offset+5,field_3_first_column);
-        LittleEndian.putShort(array,offset+7,field_4_last_column);        
+        LittleEndian.putShort(array,offset+1,(short)field_1_first_row);
+        LittleEndian.putShort(array,offset+3,(short)field_2_last_row);
+        LittleEndian.putShort(array,offset+5,(short)field_3_first_column);
+        LittleEndian.putShort(array,offset+7,(short)field_4_last_column);        
     }
 
     public int getSize()
@@ -124,42 +145,42 @@ public class AreaPtg
     /**
      * @return the first row in the area
      */
-    public short getFirstRow()
+    public int getFirstRow()
     {
         return field_1_first_row;
     }
 
     /**
      * sets the first row
-     * @param row number (0-based)
+     * @param rowIx number (0-based)
      */
-    public void setFirstRow(short row)
-    {
-        field_1_first_row = row;
+    public void setFirstRow(int rowIx) {
+        checkRowBounds(rowIx);
+        field_1_first_row = rowIx;
     }
 
     /**
      * @return last row in the range (x2 in x1,y1-x2,y2)
      */
-    public short getLastRow()
+    public int getLastRow()
     {
         return field_2_last_row;
     }
 
     /**
-     * @param row last row number in the area 
+     * @param rowIx last row number in the area 
      */
-    public void setLastRow(short row)
-    {
-        field_2_last_row = row;
+    public void setLastRow(int rowIx) {
+        checkRowBounds(rowIx);
+        field_2_last_row = rowIx;
     }
 
     /**
      * @return the first column number in the area.
      */
-    public short getFirstColumn()
+    public int getFirstColumn()
     {
-        return columnMask.getShortValue(field_3_first_column);
+        return columnMask.getValue(field_3_first_column);
     }
 
     /**
@@ -167,7 +188,7 @@ public class AreaPtg
      */
     public short getFirstColumnRaw()
     {
-        return field_3_first_column;
+        return (short) field_3_first_column; // TODO
     }
 
     /**
@@ -183,7 +204,7 @@ public class AreaPtg
      * @param rel is relative or not.
      */
     public void setFirstRowRelative(boolean rel) {
-        field_3_first_column=rowRelative.setShortBoolean(field_3_first_column,rel);
+        field_3_first_column=rowRelative.setBoolean(field_3_first_column,rel);
     }
 
     /**
@@ -198,21 +219,21 @@ public class AreaPtg
      * set whether the first column is relative 
      */
     public void setFirstColRelative(boolean rel) {
-        field_3_first_column=colRelative.setShortBoolean(field_3_first_column,rel);
+        field_3_first_column=colRelative.setBoolean(field_3_first_column,rel);
     }
 
     /**
      * set the first column in the area
      */
-    public void setFirstColumn(short column)
-    {
-       field_3_first_column=columnMask.setShortValue(field_3_first_column, column);
+    public void setFirstColumn(int colIx) {
+        checkColumnBounds(colIx);
+       field_3_first_column=columnMask.setValue(field_3_first_column, colIx);
     }
 
     /**
      * set the first column irespective of the bitmasks
      */
-    public void setFirstColumnRaw(short column)
+    public void setFirstColumnRaw(int column)
     {
         field_3_first_column = column;
     }
@@ -220,9 +241,9 @@ public class AreaPtg
     /**
      * @return lastcolumn in the area
      */
-    public short getLastColumn()
+    public int getLastColumn()
     {
-        return columnMask.getShortValue(field_4_last_column);
+        return columnMask.getValue(field_4_last_column);
     }
 
     /**
@@ -230,7 +251,7 @@ public class AreaPtg
      */
     public short getLastColumnRaw()
     {
-        return field_4_last_column;
+        return (short) field_4_last_column;
     }
 
     /**
@@ -247,7 +268,7 @@ public class AreaPtg
      * <code>false</code>
      */
     public void setLastRowRelative(boolean rel) {
-        field_4_last_column=rowRelative.setShortBoolean(field_4_last_column,rel);
+        field_4_last_column=rowRelative.setBoolean(field_4_last_column,rel);
     }
 
     /**
@@ -262,16 +283,16 @@ public class AreaPtg
      * set whether the last column should be relative or not
      */
     public void setLastColRelative(boolean rel) {
-        field_4_last_column=colRelative.setShortBoolean(field_4_last_column,rel);
+        field_4_last_column=colRelative.setBoolean(field_4_last_column,rel);
     }
     
 
     /**
      * set the last column in the area
      */
-    public void setLastColumn(short column)
-    {
-       field_4_last_column=columnMask.setShortValue(field_4_last_column, column);
+    public void setLastColumn(int colIx) {
+        checkColumnBounds(colIx);
+       field_4_last_column=columnMask.setValue(field_4_last_column, colIx);
     }
 
     /**
index 2974eec64ed7c128c5fdc604140eca08905cd85f..42dc11fa326772bb356b139681f6196983b9f930 100644 (file)
@@ -36,7 +36,7 @@ import org.apache.poi.hssf.model.Workbook;
  * @author Jason Height (jheight at chariot dot net dot au)
  */
 
-public class AreaVPtg
+public final class AreaVPtg
     extends AreaPtg
 {
     public final static short sid  = 0x45;
@@ -45,7 +45,7 @@ public class AreaVPtg
       //Required for clone methods
     }
 
-    public AreaVPtg(short firstRow, short lastRow, short firstColumn, short lastColumn, boolean firstRowRelative, boolean lastRowRelative, boolean firstColRelative, boolean lastColRelative) {
+    public AreaVPtg(int firstRow, int lastRow, int firstColumn, int lastColumn, boolean firstRowRelative, boolean lastRowRelative, boolean firstColRelative, boolean lastColRelative) {
       super(firstRow, lastRow, firstColumn, lastColumn, firstRowRelative, lastRowRelative, firstColRelative, lastColRelative);
     }
 
index ea4c742e2cd146201ce9b1766e751a45782564a9..84ff659b333de826d406de4210794d0df5dcf914 100644 (file)
 
 package org.apache.poi.hssf.record.formula;
 
-import org.apache.poi.util.LittleEndian;
-
-import org.apache.poi.hssf.util.RangeAddress;
+import org.apache.poi.hssf.model.Workbook;
+import org.apache.poi.hssf.record.RecordInputStream;
 import org.apache.poi.hssf.util.CellReference;
+import org.apache.poi.hssf.util.RangeAddress;
 import org.apache.poi.hssf.util.SheetReferences;
-import org.apache.poi.hssf.model.Workbook;
 import org.apache.poi.util.BitField;
 import org.apache.poi.util.BitFieldFactory;
-import org.apache.poi.hssf.model.Workbook;
-import org.apache.poi.hssf.record.RecordInputStream;
+import org.apache.poi.util.LittleEndian;
 
 /**
  * Title:        Reference 3D Ptg <P>
@@ -42,8 +40,14 @@ public class Ref3DPtg extends Ptg {
     public final static byte sid  = 0x3a;
     private final static int  SIZE = 7; // 6 + 1 for Ptg
     private short             field_1_index_extern_sheet;
-    private short             field_2_row;
-    private short             field_3_column;
+    /** The row index - zero based unsigned 16 bit value */
+    private int            field_2_row;
+    /** Field 2 
+     * - lower 8 bits is the zero based unsigned byte column index 
+     * - bit 16 - isRowRelative
+     * - bit 15 - isColumnRelative 
+     */
+    private int             field_3_column;
     private BitField         rowRelative = BitFieldFactory.getInstance(0x8000);
     private BitField         colRelative = BitFieldFactory.getInstance(0x4000);
 
@@ -58,8 +62,8 @@ public class Ref3DPtg extends Ptg {
     
     public Ref3DPtg(String cellref, short externIdx ) {
         CellReference c= new CellReference(cellref);
-        setRow((short) c.getRow());
-        setColumn((short) c.getCol());
+        setRow(c.getRow());
+        setColumn(c.getCol());
         setColRelative(!c.isColAbsolute());
         setRowRelative(!c.isRowAbsolute());   
         setExternSheetIndex(externIdx);
@@ -81,8 +85,8 @@ public class Ref3DPtg extends Ptg {
     public void writeBytes(byte [] array, int offset) {
         array[ 0 + offset ] = (byte) (sid + ptgClass);
         LittleEndian.putShort(array, 1 + offset , getExternSheetIndex());
-        LittleEndian.putShort(array, 3 + offset , getRow());
-        LittleEndian.putShort(array, 5 + offset , getColumnRaw());
+        LittleEndian.putShort(array, 3 + offset , (short)getRow());
+        LittleEndian.putShort(array, 5 + offset , (short)getColumnRaw());
     }
 
     public int getSize() {
@@ -97,19 +101,19 @@ public class Ref3DPtg extends Ptg {
         field_1_index_extern_sheet = index;
     }
 
-    public short getRow() {
+    public int getRow() {
         return field_2_row;
     }
 
-    public void setRow(short row) {
+    public void setRow(int row) {
         field_2_row = row;
     }
 
-    public short getColumn() {
-        return ( short ) (field_3_column & 0xFF);
+    public int getColumn() {
+        return field_3_column & 0xFF;
     }
 
-    public short getColumnRaw() {
+    public int getColumnRaw() {
         return field_3_column;
     }
 
@@ -119,7 +123,7 @@ public class Ref3DPtg extends Ptg {
     }
     
     public void setRowRelative(boolean rel) {
-        field_3_column=rowRelative.setShortBoolean(field_3_column,rel);
+        field_3_column=rowRelative.setBoolean(field_3_column,rel);
     }
     
     public boolean isColRelative()
@@ -128,7 +132,7 @@ public class Ref3DPtg extends Ptg {
     }
     
     public void setColRelative(boolean rel) {
-        field_3_column=colRelative.setShortBoolean(field_3_column,rel);
+        field_3_column=colRelative.setBoolean(field_3_column,rel);
     }
     public void setColumn(short column) {
         field_3_column &= 0xFF00;
@@ -197,5 +201,4 @@ public class Ref3DPtg extends Ptg {
      ptg.setClass(ptgClass);
      return ptg;
    }
-
 }
index 996f40e393229775db15c41e13525a8241e0d914..596b386235f0d165e38affda764b41b0eb8f5057 100644 (file)
@@ -1,4 +1,3 @@
-
 /* ====================================================================
    Licensed to the Apache Software Foundation (ASF) under one or more
    contributor license agreements.  See the NOTICE file distributed with
    limitations under the License.
 ==================================================================== */
 
-/*
- * ValueReferencePtg.java
- *
- * Created on November 21, 2001, 5:27 PM
- */
 package org.apache.poi.hssf.record.formula;
 
-import org.apache.poi.util.LittleEndian;
-import org.apache.poi.util.BitField;
-
 import org.apache.poi.hssf.record.RecordInputStream;
-import org.apache.poi.hssf.util.CellReference;
-import org.apache.poi.hssf.model.Workbook;
 
 /**
  * RefNAPtg
  * @author Jason Height (jheight at chariot dot net dot au)
  */
 
-public class RefAPtg extends ReferencePtg
-{
+public final class RefAPtg extends ReferencePtg {
     public final static byte sid  = 0x64;
 
     protected RefAPtg() {
       super();
     }
 
-    public RefAPtg(short row, short column, boolean isRowRelative, boolean isColumnRelative) {
+    public RefAPtg(int row, int column, boolean isRowRelative, boolean isColumnRelative) {
       super(row, column, isRowRelative, isColumnRelative);
     }
 
index b9d55a09ec18ee5125c7306431cd80336ae86473..8a6b2c03b4fa8352208c0c59117d8f0728bfce02 100644 (file)
@@ -1,4 +1,3 @@
-
 /* ====================================================================
    Licensed to the Apache Software Foundation (ASF) under one or more
    contributor license agreements.  See the NOTICE file distributed with
 
 package org.apache.poi.hssf.record.formula;
 
-import org.apache.poi.util.LittleEndian;
-import org.apache.poi.util.BitField;
-
 import org.apache.poi.hssf.record.RecordInputStream;
-import org.apache.poi.hssf.util.CellReference;
-import org.apache.poi.hssf.model.Workbook;
 
 /**
  * RefVPtg
  * @author Jason Height (jheight at chariot dot net dot au)
  */
-
-public class RefVPtg extends ReferencePtg
-{
+public final class RefVPtg extends ReferencePtg {
   public final static byte sid  = 0x44;
 
   protected RefVPtg() {
     super();
   }
 
-  public RefVPtg(short row, short column, boolean isRowRelative, boolean isColumnRelative) {
+  public RefVPtg(int row, int column, boolean isRowRelative, boolean isColumnRelative) {
     super(row, column, isRowRelative, isColumnRelative);
   }
 
index 3afd6419266cd1a03036193b6bd7f44151fd0137..4983c9d0706aabe0a4a71d5a087c9105c73e44af 100644 (file)
@@ -31,26 +31,22 @@ import org.apache.poi.hssf.record.RecordInputStream;
  * @author Jason Height (jheight at chariot dot net dot au)
  */
 
-public class ReferencePtg extends Ptg
-{
+public class ReferencePtg extends Ptg {
     private final static int SIZE = 5;
     public final static byte sid  = 0x24;
     private final static int MAX_ROW_NUMBER = 65536;             
-    //public final static byte sid = 0x44;
 
-   /** 
-     * The row number, between 0 and 65535, but stored as a signed
-     *  short between -32767 and 32768.
-     * Take care about which version you fetch back!
+   /** The row index - zero based unsigned 16 bit value */
+    private int            field_1_row;
+    /** Field 2 
+     * - lower 8 bits is the zero based unsigned byte column index 
+     * - bit 16 - isRowRelative
+     * - bit 15 - isColumnRelative 
      */
-    private short            field_1_row;
-    /**
-     * The column number, between 0 and ??
-     */
-    private short            field_2_col;
-    private BitField         rowRelative = BitFieldFactory.getInstance(0x8000);
-    private BitField         colRelative = BitFieldFactory.getInstance(0x4000);
-    private BitField         column      = BitFieldFactory.getInstance(0x3FFF);
+    private int            field_2_col;
+    private static final BitField         rowRelative = BitFieldFactory.getInstance(0x8000);
+    private static final BitField         colRelative = BitFieldFactory.getInstance(0x4000);
+    private static final BitField         column      = BitFieldFactory.getInstance(0x00FF);
 
     protected ReferencePtg() {
       //Required for clone methods
@@ -62,13 +58,13 @@ public class ReferencePtg extends Ptg
      */
     public ReferencePtg(String cellref) {
         CellReference c= new CellReference(cellref);
-        setRow((short) c.getRow());
-        setColumn((short) c.getCol());
+        setRow(c.getRow());
+        setColumn(c.getCol());
         setColRelative(!c.isColAbsolute());
         setRowRelative(!c.isRowAbsolute());
     }
     
-    public ReferencePtg(short row, short column, boolean isRowRelative, boolean isColumnRelative) {
+    public ReferencePtg(int row, int column, boolean isRowRelative, boolean isColumnRelative) {
       setRow(row);
       setColumn(column);
       setRowRelative(isRowRelative);
@@ -79,8 +75,8 @@ public class ReferencePtg extends Ptg
 
     public ReferencePtg(RecordInputStream in)
     {
-        field_1_row = in.readShort();
-        field_2_col = in.readShort();
+        field_1_row = in.readUShort();
+        field_2_col = in.readUShort();
     }
     
     public String getRefPtgName() {
@@ -104,33 +100,23 @@ public class ReferencePtg extends Ptg
     {
         array[offset] = (byte) (sid + ptgClass);
 
-        LittleEndian.putShort(array,offset+1,field_1_row);
-        LittleEndian.putShort(array,offset+3,field_2_col);
+        LittleEndian.putShort(array, offset+1, (short)field_1_row);
+        LittleEndian.putShort(array, offset+3, (short)field_2_col);
     }
 
-    public void setRow(short row)
-    {
-        field_1_row = row;
-    }
     public void setRow(int row)
     {
         if(row < 0 || row >= MAX_ROW_NUMBER) {
            throw new IllegalArgumentException("The row number, when specified as an integer, must be between 0 and " + MAX_ROW_NUMBER);
         }
-        
-        // Save, wrapping as needed
-        if(row > Short.MAX_VALUE) {
-               field_1_row = (short)(row - MAX_ROW_NUMBER);
-        } else {
-               field_1_row = (short)row;
-        }
+        field_1_row = row;
     }
 
     /**
      * Returns the row number as a short, which will be
      *  wrapped (negative) for values between 32769 and 65535
      */
-    public short getRow()
+    public int getRow()
     {
         return field_1_row;
     }
@@ -151,7 +137,7 @@ public class ReferencePtg extends Ptg
     }
     
     public void setRowRelative(boolean rel) {
-        field_2_col=rowRelative.setShortBoolean(field_2_col,rel);
+        field_2_col=rowRelative.setBoolean(field_2_col,rel);
     }
     
     public boolean isColRelative()
@@ -160,27 +146,29 @@ public class ReferencePtg extends Ptg
     }
     
     public void setColRelative(boolean rel) {
-        field_2_col=colRelative.setShortBoolean(field_2_col,rel);
+        field_2_col=colRelative.setBoolean(field_2_col,rel);
     }
 
-    public void setColumnRaw(short col)
+    public void setColumnRaw(int col)
     {
         field_2_col = col;
     }
 
-    public short getColumnRaw()
+    public int getColumnRaw()
     {
         return field_2_col;
     }
 
-    public void setColumn(short col)
+    public void setColumn(int col)
     {
-       field_2_col = column.setShortValue(field_2_col, col);
+        if(col < 0 || col > 0x100) {
+            throw new IllegalArgumentException("Specified colIx (" + col + ") is out of range");
+        }
+       field_2_col = column.setValue(field_2_col, col);
     }
 
-    public short getColumn()
-    {
-       return column.getShortValue(field_2_col);
+    public int getColumn() {
+       return column.getValue(field_2_col);
     }
 
     public int getSize()
index 30bdc01f513375ddacb2bff4ba78e80a4abfb30c..66f79ffd8ad289621f686d73cad3d8796163a368 100644 (file)
@@ -287,17 +287,30 @@ public final class HSSFRow implements Comparable {
     }
 
     /**
-     * get the hssfcell representing a given column (logical cell) 0-based.  If you
-     * ask for a cell that is not defined....you get a null.
+     * Get the hssfcell representing a given column (logical cell)
+     *  0-based.  If you ask for a cell that is not defined....
+     *  you get a null.
+     * Short method signature provided to retain binary
+     *  compatibility.
      *
      * @param cellnum  0 based column number
      * @return HSSFCell representing that column or null if undefined.
      */
-
     public HSSFCell getCell(short cellnum)
     {
-      if(cellnum<0||cellnum>=cells.length) return null;
-      return cells[cellnum];
+               return getCell((int)cellnum);
+    }
+    /**
+     * Get the hssfcell representing a given column (logical cell)
+     *  0-based.  If you ask for a cell that is not defined....
+     *  you get a null.
+     *
+     * @param cellnum  0 based column number
+     * @return HSSFCell representing that column or null if undefined.
+     */
+    public HSSFCell getCell(int cellnum) {
+        if(cellnum<0||cellnum>=cells.length) return null;
+        return cells[cellnum];
     }
 
     /**
index fbd128842de45883558f789627b521316405e83b..3f6b321a6e5fe8711cc13d3dfda7a314847584b5 100644 (file)
@@ -53,9 +53,10 @@ public final class AreaReference {
                        parts[1].length() == 1 && 
                        parts[0].charAt(0) >= 'A' && parts[0].charAt(0) <= 'Z' &&
                        parts[1].charAt(0) >= 'A' && parts[1].charAt(0) <= 'Z') {
-               // Represented internally as x$1 to x$0
+               // Represented internally as x$1 to x$65536
+               //  which is the maximum range of rows
                parts[0] = parts[0] + "$1";
-               parts[1] = parts[1] + "$0";
+               parts[1] = parts[1] + "$65536";
         }
         
         _firstCell = new CellReference(parts[0]);
@@ -98,10 +99,10 @@ public final class AreaReference {
      */
     public static boolean isWholeColumnReference(CellReference topLeft, CellReference botRight) {
        // These are represented as something like
-       //   C$1:C$0 or D$1:F$0
+       //   C$1:C$65535 or D$1:F$0
        // i.e. absolute from 1st row to 0th one
        if(topLeft.getRow() == 0 && topLeft.isRowAbsolute() &&
-               botRight.getRow() == -1 && botRight.isRowAbsolute()) {
+               botRight.getRow() == 65535 && botRight.isRowAbsolute()) {
                return true;
        }
        return false;
index cb8368772857842a6b538f79e21e45263cf949d0..47d579d94f8b509df44064c58247b2f3ecc4b90e 100644 (file)
@@ -71,6 +71,14 @@ public final class CellReference {
         this(null, pRow, pCol, pAbsRow, pAbsCol);
     }
     public CellReference(String pSheetName, int pRow, int pCol, boolean pAbsRow, boolean pAbsCol) {
+        // TODO - "-1" is a special value being temporarily used for whole row and whole column area references.
+        // so these checks are currently N.Q.R.
+        if(pRow < -1) {
+            throw new IllegalArgumentException("row index may not be negative");
+        }
+        if(pCol < -1) {
+            throw new IllegalArgumentException("column index may not be negative");
+        }
         _sheetName = pSheetName;
         _rowIndex=pRow;
         _colIndex=pCol;
index 179698dc8dcd83bfccccc89831c5346a9fc48ef3..4b9a64c1c0e0d78212d356b25b6dc552d9dd3154 100644 (file)
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
-/*
- * Created on May 8, 2005
- *
- */
+
 package org.apache.poi.hssf.record.formula.eval;
 
 import org.apache.poi.hssf.record.formula.AreaPtg;
@@ -27,48 +24,60 @@ import org.apache.poi.hssf.record.formula.Ptg;
  * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
  *   
  */
-public class Area2DEval implements AreaEval {
-
-    private AreaPtg delegate;
+public final class Area2DEval implements AreaEval {
+// TODO -refactor with Area3DEval
+    private final AreaPtg _delegate;
 
-    private ValueEval[] values;
+    private final ValueEval[] _values;
 
     public Area2DEval(Ptg ptg, ValueEval[] values) {
-        this.delegate = (AreaPtg) ptg;
-        this.values = values;
+        if(ptg == null) {
+            throw new IllegalArgumentException("ptg must not be null");
+        }
+        if(values == null) {
+            throw new IllegalArgumentException("values must not be null");
+        }
+        for(int i=values.length-1; i>=0; i--) {
+            if(values[i] == null) {
+                throw new IllegalArgumentException("value array elements must not be null");
+            }
+        }
+        // TODO - check size of array vs size of AreaPtg
+        _delegate = (AreaPtg) ptg;
+        _values = values;
     }
 
-    public short getFirstColumn() {
-        return delegate.getFirstColumn();
+    public int getFirstColumn() {
+        return _delegate.getFirstColumn();
     }
 
     public int getFirstRow() {
-        return delegate.getFirstRow();
+        return _delegate.getFirstRow();
     }
 
-    public short getLastColumn() {
-        return delegate.getLastColumn();
+    public int getLastColumn() {
+        return _delegate.getLastColumn();
     }
 
     public int getLastRow() {
-        return delegate.getLastRow();
+        return _delegate.getLastRow();
     }
 
     public ValueEval[] getValues() {
-        return values;
+        return _values;
     }
     
-    public ValueEval getValueAt(int row, short col) {
+    public ValueEval getValueAt(int row, int col) {
         ValueEval retval;
         int index = ((row-getFirstRow())*(getLastColumn()-getFirstColumn()+1))+(col-getFirstColumn());
-        if (index <0 || index >= values.length)
+        if (index <0 || index >= _values.length)
             retval = ErrorEval.VALUE_INVALID;
         else 
-            retval = values[index];
+            retval = _values[index];
         return retval;
     }
     
-    public boolean contains(int row, short col) {
+    public boolean contains(int row, int col) {
         return (getFirstRow() <= row) && (getLastRow() >= row) 
             && (getFirstColumn() <= col) && (getLastColumn() >= col);
     }
@@ -82,10 +91,10 @@ public class Area2DEval implements AreaEval {
     }
     
     public boolean isColumn() {
-        return delegate.getFirstColumn() == delegate.getLastColumn();
+        return _delegate.getFirstColumn() == _delegate.getLastColumn();
     }
 
     public boolean isRow() {
-        return delegate.getFirstRow() == delegate.getLastRow();
+        return _delegate.getFirstRow() == _delegate.getLastRow();
     }
 }
index b997b95c6da394519667c9a5a14316473abaf94c..2f539142d154e48677b40a836c79072b354c38f9 100644 (file)
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
-/*
- * Created on May 8, 2005
- *
- */
+
 package org.apache.poi.hssf.record.formula.eval;
 
 import org.apache.poi.hssf.record.formula.Area3DPtg;
@@ -28,47 +25,59 @@ import org.apache.poi.hssf.record.formula.Ptg;
  *  
  */
 public final class Area3DEval implements AreaEval {
+       // TODO -refactor with Area3DEval
+    private final Area3DPtg _delegate;
 
-    private Area3DPtg delegate;
-
-    private ValueEval[] values;
+    private final ValueEval[] _values;
 
     public Area3DEval(Ptg ptg, ValueEval[] values) {
-        this.values = values;
-        this.delegate = (Area3DPtg) ptg;
+        if(ptg == null) {
+            throw new IllegalArgumentException("ptg must not be null");
+        }
+        if(values == null) {
+            throw new IllegalArgumentException("values must not be null");
+        }
+        for(int i=values.length-1; i>=0; i--) {
+            if(values[i] == null) {
+                throw new IllegalArgumentException("value array elements must not be null");
+            }
+        }
+        // TODO - check size of array vs size of AreaPtg
+        _values = values;
+        _delegate = (Area3DPtg) ptg;
     }
 
-    public short getFirstColumn() {
-        return delegate.getFirstColumn();
+    public int getFirstColumn() {
+        return _delegate.getFirstColumn();
     }
 
     public int getFirstRow() {
-        return delegate.getFirstRow();
+        return _delegate.getFirstRow();
     }
 
-    public short getLastColumn() {
-        return delegate.getLastColumn();
+    public int getLastColumn() {
+        return (short) _delegate.getLastColumn();
     }
 
     public int getLastRow() {
-        return delegate.getLastRow();
+        return _delegate.getLastRow();
     }
 
     public ValueEval[] getValues() {
-        return values;
+        return _values;
     }
     
-    public ValueEval getValueAt(int row, short col) {
+    public ValueEval getValueAt(int row, int col) {
         ValueEval retval;
         int index = (row-getFirstRow())*(col-getFirstColumn());
-        if (index <0 || index >= values.length)
+        if (index <0 || index >= _values.length)
             retval = ErrorEval.VALUE_INVALID;
         else 
-            retval = values[index];
+            retval = _values[index];
         return retval;
     }
     
-    public boolean contains(int row, short col) {
+    public boolean contains(int row, int col) {
         return (getFirstRow() <= row) && (getLastRow() >= row) 
             && (getFirstColumn() <= col) && (getLastColumn() >= col);
     }
@@ -83,15 +92,14 @@ public final class Area3DEval implements AreaEval {
     
     
     public boolean isColumn() {
-        return delegate.getFirstColumn() == delegate.getLastColumn();
+        return _delegate.getFirstColumn() == _delegate.getLastColumn();
     }
 
     public boolean isRow() {
-        return delegate.getFirstRow() == delegate.getLastRow();
+        return _delegate.getFirstRow() == _delegate.getLastRow();
     }
 
     public int getExternSheetIndex() {
-        return delegate.getExternSheetIndex();
+        return _delegate.getExternSheetIndex();
     }
-
 }
index f60d63c131f50e30cd0ead767d7f1e983f469af1..82cc8a9b40d8957de83346b27e5d4bf57fcef317 100644 (file)
@@ -42,13 +42,13 @@ public interface AreaEval extends ValueEval {
      * returns the 0-based index of the first col in
      * this area.
      */
-    public short getFirstColumn();
+    public int getFirstColumn();
 
     /**
      * returns the 0-based index of the last col in
      * this area.
      */
-    public short getLastColumn();
+    public int getLastColumn();
     
     /**
      * returns true if the Area's start and end row indexes
@@ -80,7 +80,7 @@ public interface AreaEval extends ValueEval {
      * @param row
      * @param col
      */
-    public ValueEval getValueAt(int row, short col);
+    public ValueEval getValueAt(int row, int col);
     
     /**
      * returns true if the cell at row and col specified 
@@ -89,7 +89,7 @@ public interface AreaEval extends ValueEval {
      * @param row
      * @param col
      */
-    public boolean contains(int row, short col);
+    public boolean contains(int row, int col);
     
     /**
      * returns true if the specified col is in range
index 4dd055c6c070f4c50ab209a1b6510f06f5522e90..898d7a86186640d7c60b06dffd61d50ba1dd369d 100644 (file)
@@ -29,16 +29,22 @@ public final class Ref2DEval implements RefEval {
     private final ReferencePtg delegate;
     
     public Ref2DEval(ReferencePtg ptg, ValueEval ve) {
+        if(ve == null) {
+            throw new IllegalArgumentException("ve must not be null");
+        }
+        if(false && ptg == null) { // TODO - fix dodgy code in MultiOperandNumericFunction
+            throw new IllegalArgumentException("ptg must not be null");
+        }
         value = ve;
         delegate = ptg;
     }
     public ValueEval getInnerValueEval() {
         return value;
     }
-    public short getRow() {
+    public int getRow() {
         return delegate.getRow();
     }
-    public short getColumn() {
+    public int getColumn() {
         return delegate.getColumn();
     }
 }
index 7ecca26788e29d92458124976e5077d806495fb1..622d686329623331901803e537a3c45bc61c62a1 100644 (file)
@@ -29,16 +29,22 @@ public final class Ref3DEval implements RefEval {
     private final Ref3DPtg delegate;
 
     public Ref3DEval(Ref3DPtg ptg, ValueEval ve) {
+        if(ve == null) {
+            throw new IllegalArgumentException("ve must not be null");
+        }
+        if(ptg == null) {
+            throw new IllegalArgumentException("ptg must not be null");
+        }
         value = ve;
         delegate = ptg;
     }
     public ValueEval getInnerValueEval() {
         return value;
     }
-    public short getRow() {
+    public int getRow() {
         return delegate.getRow();
     }
-    public short getColumn() {
+    public int getColumn() {
         return delegate.getColumn();
     }
     public int getExternSheetIndex() {
index 48a94b024efc0dba5d4dd80927d9bbc7e33c5bc7..e462586d72480e1c3cdc31482fe05428e4028e0a 100644 (file)
@@ -40,12 +40,12 @@ public interface RefEval extends ValueEval {
     public ValueEval getInnerValueEval();
 
     /**
-     * returns the column index.
+     * returns the zero based column index.
      */
-    public short getColumn();
+    public int getColumn();
 
     /**
-     * returns the row index.
+     * returns the zero based row index.
      */
-    public short getRow();
+    public int getRow();
 }
index 66123b2985efd6fdc5cb38538fa170d0f68e2d26..d6a8489623ea8b73f11039a92f254ddc7084736c 100644 (file)
@@ -287,8 +287,8 @@ final class LookupUtils {
                        // 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. 
                        // anything would be ok for rowIx and colIx, but may as well get it right.
-                       short rowIx = refEval.getRow();
-                       short colIx = refEval.getColumn();
+                       int rowIx = refEval.getRow();
+                       int colIx = refEval.getColumn();
                        AreaPtg ap = new AreaPtg(rowIx, rowIx, colIx, colIx, false, false, false, false);
                        ValueEval value = refEval.getInnerValueEval();
                        return new Area2DEval(ap, new ValueEval[] { value, });
index 3cbec2e6d24b6bcf3c94c116e0156cd3cd0f92ce..3fce3065579b1a31aed726021a308cfc65f061e9 100644 (file)
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
-/*
- * Created on May 5, 2005
- *
- */
+
 package org.apache.poi.hssf.usermodel;
 
 import java.lang.reflect.Constructor;
@@ -420,20 +417,20 @@ public class HSSFFormulaEvaluator {
             }
             else if (ptg instanceof ReferencePtg) {
                 ReferencePtg refPtg = (ReferencePtg) ptg;
-                short colnum = refPtg.getColumn();
-                short rownum = refPtg.getRow();
-                HSSFRow row = sheet.getRow(rownum);
-                HSSFCell cell = (row != null) ? row.getCell(colnum) : null;
+                int colIx = refPtg.getColumn();
+                int rowIx = refPtg.getRow();
+                HSSFRow row = sheet.getRow(rowIx);
+                HSSFCell cell = (row != null) ? row.getCell(colIx) : null;
                 stack.push(createRef2DEval(refPtg, cell, row, sheet, workbook));
             }
             else if (ptg instanceof Ref3DPtg) {
                 Ref3DPtg refPtg = (Ref3DPtg) ptg;
-                short colnum = refPtg.getColumn();
-                short rownum = refPtg.getRow();
+                int colIx = refPtg.getColumn();
+                int rowIx = refPtg.getRow();
                 Workbook wb = workbook.getWorkbook();
                 HSSFSheet xsheet = workbook.getSheetAt(wb.getSheetIndexFromExternSheetIndex(refPtg.getExternSheetIndex()));
-                HSSFRow row = xsheet.getRow(rownum);
-                HSSFCell cell = (row != null) ? row.getCell(colnum) : null;
+                HSSFRow row = xsheet.getRow(rowIx);
+                HSSFCell cell = (row != null) ? row.getCell(colIx) : null;
                 stack.push(createRef3DEval(refPtg, cell, row, xsheet, workbook));
             }
             else if (ptg instanceof AreaPtg) {
@@ -506,10 +503,10 @@ public class HSSFFormulaEvaluator {
     }
     
     public static AreaEval evaluateAreaPtg(HSSFSheet sheet, HSSFWorkbook workbook, AreaPtg ap) {
-        short row0 = ap.getFirstRow();
-        short col0 = ap.getFirstColumn();
-        short row1 = ap.getLastRow();
-        short col1 = ap.getLastColumn();
+        int row0 = ap.getFirstRow();
+        int col0 = ap.getFirstColumn();
+        int row1 = ap.getLastRow();
+        int col1 = ap.getLastColumn();
         
         // If the last row is -1, then the
         //  reference is for the rest of the column
@@ -518,24 +515,15 @@ public class HSSFFormulaEvaluator {
         if(row1 == -1 && row0 >= 0) {
             row1 = (short)sheet.getLastRowNum();
         }
-        
-        ValueEval[] values = new ValueEval[(row1 - row0 + 1) * (col1 - col0 + 1)];
-        for (short x = row0; sheet != null && x < row1 + 1; x++) {
-            HSSFRow row = sheet.getRow(x);
-            for (short y = col0; row != null && y < col1 + 1; y++) {
-                values[(x - row0) * (col1 - col0 + 1) + (y - col0)] = 
-                    getEvalForCell(row.getCell(y), row, sheet, workbook);
-            }
-        }
-        AreaEval ae = new Area2DEval(ap, values);
-        return ae;
+        ValueEval[] values = evalArea(workbook, sheet, row0, col0, row1, col1);
+        return new Area2DEval(ap, values);
     }
 
     public static AreaEval evaluateArea3dPtg(HSSFWorkbook workbook, Area3DPtg a3dp) {
-        short row0 = a3dp.getFirstRow();
-        short col0 = a3dp.getFirstColumn();
-        short row1 = a3dp.getLastRow();
-        short col1 = a3dp.getLastColumn();
+       int row0 = a3dp.getFirstRow();
+       int col0 = a3dp.getFirstColumn();
+       int row1 = a3dp.getLastRow();
+       int col1 = a3dp.getLastColumn();
         Workbook wb = workbook.getWorkbook();
         HSSFSheet xsheet = workbook.getSheetAt(wb.getSheetIndexFromExternSheetIndex(a3dp.getExternSheetIndex()));
         
@@ -547,19 +535,28 @@ public class HSSFFormulaEvaluator {
             row1 = (short)xsheet.getLastRowNum();
         }
         
+        ValueEval[] values = evalArea(workbook, xsheet, row0, col0, row1, col1);
+        return new Area3DEval(a3dp, values);
+    }
+    
+    private static ValueEval[] evalArea(HSSFWorkbook workbook, HSSFSheet sheet, 
+               int row0, int col0, int row1, int col1) {
         ValueEval[] values = new ValueEval[(row1 - row0 + 1) * (col1 - col0 + 1)];
-        for (short x = row0; xsheet != null && x < row1 + 1; x++) {
-            HSSFRow row = xsheet.getRow(x);
-            for (short y = col0; row != null && y < col1 + 1; y++) {
-                values[(x - row0) * (col1 - col0 + 1) + (y - col0)] = 
-                    getEvalForCell(row.getCell(y), row, xsheet, workbook);
+        for (int x = row0; sheet != null && x < row1 + 1; x++) {
+            HSSFRow row = sheet.getRow(x);
+            for (int y = col0; y < col1 + 1; y++) {
+                ValueEval cellEval;
+                if(row == null) {
+                       cellEval = BlankEval.INSTANCE;
+                } else {
+                       cellEval = getEvalForCell(row.getCell(y), row, sheet, workbook);
+                }
+                               values[(x - row0) * (col1 - col0 + 1) + (y - col0)] = cellEval;
             }
         }
-        AreaEval ae = new Area3DEval(a3dp, values);
-        return ae;
+        return values;
     }
 
-
     /**
      * returns the OperationEval concrete impl instance corresponding
      * to the suplied operationPtg
index aa73714a0fe8bb185ab962b19798aa8bb1b5a1b3..0141e1b2a4611836508cd113d908fb51518e8b3b 100644 (file)
@@ -1,4 +1,3 @@
-
 /* ====================================================================
    Licensed to the Apache Software Foundation (ASF) under one or more
    contributor license agreements.  See the NOTICE file distributed with
    See the License for the specific language governing permissions and
    limitations under the License.
 ==================================================================== */
-        
+
 package org.apache.poi.hssf.model;
 
 import junit.framework.TestCase;
 
+import org.apache.poi.hssf.model.FormulaParser.FormulaParseException;
 import org.apache.poi.hssf.record.formula.FuncVarPtg;
 import org.apache.poi.hssf.record.formula.NamePtg;
 import org.apache.poi.hssf.record.formula.Ptg;
+import org.apache.poi.hssf.usermodel.HSSFCell;
 import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator;
 import org.apache.poi.hssf.usermodel.HSSFName;
+import org.apache.poi.hssf.usermodel.HSSFRow;
 import org.apache.poi.hssf.usermodel.HSSFSheet;
 import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator.CellValue;
 
 /**
  * Test the low level formula parser functionality,
  *  but using parts which need to use the
  *  HSSFFormulaEvaluator, which is in scratchpad 
  */
-public class TestFormulaParserSP extends TestCase {
+public final class TestFormulaParserSP extends TestCase {
 
-    public TestFormulaParserSP(String name) {
-        super(name);
-    }
-       
        public void testWithNamedRange() throws Exception {
                HSSFWorkbook workbook = new HSSFWorkbook();
                FormulaParser fp;
@@ -80,4 +79,32 @@ public class TestFormulaParserSP extends TestCase {
                assertEquals(FuncVarPtg.class, ptgs[1].getClass());
        }
 
+       public void testEvaluateFormulaWithRowBeyond32768_Bug44539() {
+               
+               HSSFWorkbook wb = new HSSFWorkbook();
+               HSSFSheet sheet = wb.createSheet();
+               wb.setSheetName(0, "Sheet1");
+               
+               HSSFRow row = sheet.createRow(0);
+               HSSFCell cell = row.createCell((short)0);
+               cell.setCellFormula("SUM(A32769:A32770)");
+
+               // put some values in the cells to make the evaluation more interesting
+               sheet.createRow(32768).createCell((short)0).setCellValue(31);
+               sheet.createRow(32769).createCell((short)0).setCellValue(11);
+               
+               HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(sheet, wb);
+               fe.setCurrentRow(row);
+               CellValue result;
+               try {
+                       result = fe.evaluate(cell);
+               } catch (FormulaParseException e) {
+                       if(e.getMessage().equals("Found reference to named range \"A\", but that named range wasn't defined!")) {
+                               fail("Identifed bug 44539");
+                       }
+                       throw new RuntimeException(e);
+               }
+               assertEquals(HSSFCell.CELL_TYPE_NUMERIC, result.getCellType());
+               assertEquals(42.0, result.getNumberValue(), 0.0);
+       }
 }
index 03e35e6af29826e6a883025b7b8a62619456b702..27c3bdc3870533eb593c2700eb7fd95155503f3a 100644 (file)
@@ -63,12 +63,13 @@ public class TestBug44410 extends TestCase {
         assertEquals(AreaPtg.class, ops.get(0).getClass());
         assertEquals(FuncVarPtg.class, ops.get(1).getClass());
 
-        // Actually stored as C1 to C0 (last row is -1)
+        // Actually stored as C1 to C65536 
+        //  (last row is -1 === 65535)
         AreaPtg ptg = (AreaPtg)ops.get(0);
         assertEquals(2, ptg.getFirstColumn());
         assertEquals(2, ptg.getLastColumn());
         assertEquals(0, ptg.getFirstRow());
-        assertEquals(-1, ptg.getLastRow());
+        assertEquals(65535, ptg.getLastRow());
         assertEquals("C:C", ptg.toFormulaString(wb.getWorkbook()));
         
         // Will show as C:C, but won't know how many
index 7b42bf333f690f7dc67a1560e8470c63a3583c53..f922e75d8280aeacdee06f9479a404f9530a6e62 100644 (file)
@@ -1,4 +1,3 @@
-
 /* ====================================================================
    Licensed to the Apache Software Foundation (ASF) under one or more
    contributor license agreements.  See the NOTICE file distributed with
@@ -21,6 +20,7 @@ package org.apache.poi.hssf.model;
 import junit.framework.AssertionFailedError;
 import junit.framework.TestCase;
 
+import org.apache.poi.hssf.model.FormulaParser.FormulaParseException;
 import org.apache.poi.hssf.record.formula.AbstractFunctionPtg;
 import org.apache.poi.hssf.record.formula.AddPtg;
 import org.apache.poi.hssf.record.formula.AreaPtg;
@@ -59,18 +59,8 @@ import org.apache.poi.hssf.usermodel.HSSFWorkbook;
  * Some tests are also done in scratchpad, if they need
  *  HSSFFormulaEvaluator, which is there
  */
-public class TestFormulaParser extends TestCase {
+public final class TestFormulaParser extends TestCase {
 
-    public TestFormulaParser(String name) {
-        super(name);
-    }
-    public void setUp(){
-        
-    }
-    
-    public void tearDown() {
-        
-    }
     /**
      * @return parsed token array already confirmed not <code>null</code>
      */
@@ -831,10 +821,27 @@ public class TestFormulaParser extends TestCase {
         try {
             parseFormula(formula);
             throw new AssertionFailedError("expected parse exception");
-        } catch (RuntimeException e) {
-            // TODO - catch more specific exception
+        } catch (FormulaParseException e) {
             // expected during successful test
-            return;
+            assertNotNull(e.getMessage());
+        } catch (RuntimeException e) {
+            e.printStackTrace();
+            fail("Wrong exception:" + e.getMessage());
+        }
+    }
+
+    public void testSetFormulaWithRowBeyond32768_Bug44539() {
+        
+        HSSFWorkbook wb = new HSSFWorkbook();
+        HSSFSheet sheet = wb.createSheet();
+        wb.setSheetName(0, "Sheet1");
+        
+        HSSFRow row = sheet.createRow(0);
+        HSSFCell cell = row.createCell((short)0);
+        cell.setCellFormula("SUM(A32769:A32770)");
+        if("SUM(A-32767:A-32766)".equals(cell.getCellFormula())) {
+            fail("Identified bug 44539");
         }
+        assertEquals("SUM(A32769:A32770)", cell.getCellFormula());
     }
 }
index 522a5bcf2853f10d1f5b4c44c07e36c0e3ffea93..3a7f2f29a418c14abbb94c089bb7971e2ab9db74 100644 (file)
@@ -27,15 +27,12 @@ import org.apache.poi.hssf.model.FormulaParser;
  *
  * @author Dmitriy Kumshayev
  */
-public class TestAreaPtg extends TestCase
-{
+public final class TestAreaPtg extends TestCase {
 
        AreaPtg relative;
        AreaPtg absolute;
        
-       protected void setUp() throws Exception
-       {
-               super.setUp();
+       protected void setUp() {
                short firstRow=5;
                short lastRow=13;
                short firstCol=7;
@@ -64,10 +61,9 @@ public class TestAreaPtg extends TestCase
        }
 
 
-       public void resetColumns(AreaPtg aptg)
-       {
-               short fc = aptg.getFirstColumn();
-               short lc = aptg.getLastColumn();
+       private static void resetColumns(AreaPtg aptg) {
+               int fc = aptg.getFirstColumn();
+               int lc = aptg.getLastColumn();
                aptg.setFirstColumn(fc);
                aptg.setLastColumn(lc);
                assertEquals(fc , aptg.getFirstColumn() );