You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by ye...@apache.org on 2008/06/21 14:03:49 UTC

svn commit: r670186 [2/7] - in /poi/tags/REL_3_1_FINAL: ./ legal/ src/documentation/content/xdocs/ src/examples/src/org/apache/poi/hslf/ src/examples/src/org/apache/poi/hslf/usermodel/ src/examples/src/org/apache/poi/hslf/usermodel/examples/ src/java/o...

Modified: poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/model/Sheet.java
URL: http://svn.apache.org/viewvc/poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/model/Sheet.java?rev=670186&r1=670185&r2=670186&view=diff
==============================================================================
--- poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/model/Sheet.java (original)
+++ poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/model/Sheet.java Sat Jun 21 05:03:44 2008
@@ -66,7 +66,7 @@
     protected ArrayList                  records           =     null;
               int                        preoffset         =     0;            // offset of the sheet in a new file
               int                        loc               =     0;
-    protected int                        dimsloc           =     0;
+    protected int                        dimsloc           =     -1;  // TODO - is it legal for dims record to be missing?
     protected DimensionsRecord           dims;
     protected DefaultColWidthRecord      defaultcolwidth   =     null;
     protected DefaultRowHeightRecord     defaultrowheight  =     null;
@@ -96,8 +96,8 @@
     protected List                       condFormatting    =     new ArrayList();
 
     /** Add an UncalcedRecord if not true indicating formulas have not been calculated */
-    protected boolean uncalced = false;
-	
+    protected boolean _isUncalced = false;
+    
     public static final byte PANE_LOWER_RIGHT = (byte)0;
     public static final byte PANE_UPPER_RIGHT = (byte)1;
     public static final byte PANE_LOWER_LEFT = (byte)2;
@@ -162,7 +162,7 @@
                 }
             }
             else if (rec.getSid() == UncalcedRecord.sid) {
-                retval.uncalced = true;
+                retval._isUncalced = true;
             }
             else if (rec.getSid() == DimensionsRecord.sid)
             {
@@ -295,6 +295,8 @@
             }
             else if ( rec.getSid() == IndexRecord.sid )
             {
+                // ignore INDEX record because it is only needed by Excel, 
+                // and POI always re-calculates its contents 
                 rec = null;
             }
 
@@ -329,16 +331,8 @@
             }
         }
         retval.records = records;
-//        if (retval.rows == null)
-//        {
-//            retval.rows = new RowRecordsAggregate();
-//        }
-        retval.checkCells();
         retval.checkRows();
-//        if (retval.cells == null)
-//        {
-//            retval.cells = new ValueRecordsAggregate();
-//        }
+        retval.checkCells();
         if (log.check( POILogger.DEBUG ))
             log.log(POILogger.DEBUG, "sheet createSheet (existing file) exited");
         return retval;
@@ -494,7 +488,15 @@
         if (cells == null)
         {
             cells = new ValueRecordsAggregate();
-            records.add(getDimsLoc() + 1, cells);
+            // In the worksheet stream, the row records always occur before the cell (value) 
+            // records. Therefore POI's aggregates (RowRecordsAggregate, ValueRecordsAggregate) 
+            // should follow suit. Some methods in this class tolerate either order, while 
+            // others have been found to fail (see bug 45145).
+            int rraIndex = getDimsLoc() + 1;
+            if (records.get(rraIndex).getClass() != RowRecordsAggregate.class) {
+                throw new IllegalStateException("Cannot create value records before row records exist");
+            }
+            records.add(rraIndex+1, cells);
         }
     }
 
@@ -816,17 +818,17 @@
             // Once the rows have been found in the list of records, start
             //  writing out the blocked row information. This includes the DBCell references
             if (record instanceof RowRecordsAggregate) {
-              pos += ((RowRecordsAggregate)record).serialize(pos, data, cells);   // rec.length;
+              pos += ((RowRecordsAggregate)record).serialize(pos, data, cells);
             } else if (record instanceof ValueRecordsAggregate) {
               //Do nothing here. The records were serialized during the RowRecordAggregate block serialization
             } else {
-              pos += record.serialize(pos, data );   // rec.length;
+              pos += record.serialize(pos, data );
             }
 
             // If the BOF record was just serialized then add the IndexRecord
             if (record.getSid() == BOFRecord.sid) {
               // Add an optional UncalcedRecord
-              if (uncalced) {
+              if (_isUncalced) {
                   UncalcedRecord rec = new UncalcedRecord();
                   pos += rec.serialize(pos, data);
               }
@@ -837,67 +839,68 @@
                 pos += serializeIndexRecord(k, pos, data);
               }
             }
-
-            //// uncomment to test record sizes ////
-//            System.out.println( record.getClass().getName() );
-//            byte[] data2 = new byte[record.getRecordSize()];
-//            record.serialize(0, data2 );   // rec.length;
-//            if (LittleEndian.getUShort(data2, 2) != record.getRecordSize() - 4
-//                    && record instanceof RowRecordsAggregate == false
-//                    && record instanceof ValueRecordsAggregate == false
-//                    && record instanceof EscherAggregate == false)
-//            {
-//                throw new RuntimeException("Blah!!!  Size off by " + ( LittleEndian.getUShort(data2, 2) - record.getRecordSize() - 4) + " records.");
-//            }
-
-//asd:            int len = record.serialize(pos + offset, data );
-
-            /////  DEBUG BEGIN /////
-//asd:            if (len != record.getRecordSize())
-//asd:                throw new IllegalStateException("Record size does not match serialized bytes.  Serialized size = " + len + " but getRecordSize() returns " + record.getRecordSize() + ". Record object is " + record.getClass());
-            /////  DEBUG END /////
-
-//asd:            pos += len;   // rec.length;
-
         }
-        if (log.check( POILogger.DEBUG ))
+        if (log.check( POILogger.DEBUG )) {
             log.log(POILogger.DEBUG, "Sheet.serialize returning ");
+        }
         return pos-offset;
     }
 
-    private int serializeIndexRecord(final int BOFRecordIndex, final int offset, byte[] data) {
-      IndexRecord index = new IndexRecord();
-      index.setFirstRow(rows.getFirstRowNum());
-      index.setLastRowAdd1(rows.getLastRowNum()+1);
-      //Calculate the size of the records from the end of the BOF
-      //and up to the RowRecordsAggregate...
-      int sheetRecSize = 0;
-      for (int j = BOFRecordIndex+1; j < records.size(); j++)
-      {
-        Record tmpRec = (( Record ) records.get(j));
-        if (tmpRec instanceof RowRecordsAggregate)
-          break;
-        sheetRecSize+= tmpRec.getRecordSize();
-      }
-      //Add the references to the DBCells in the IndexRecord (one for each block)
-      int blockCount = rows.getRowBlockCount();
-      //Calculate the size of this IndexRecord
-      int indexRecSize = IndexRecord.getRecordSizeForBlockCount(blockCount);
-
-      int rowBlockOffset = 0;
-      int cellBlockOffset = 0;
-      int dbCellOffset = 0;
-      for (int block=0;block<blockCount;block++) {
-        rowBlockOffset += rows.getRowBlockSize(block);
-        cellBlockOffset += null == cells ? 0 : cells.getRowCellBlockSize(rows.getStartRowNumberForBlock(block),
-                                                     rows.getEndRowNumberForBlock(block));
-        //Note: The offsets are relative to the Workbook BOF. Assume that this is
-        //0 for now.....
-        index.addDbcell(offset + indexRecSize + sheetRecSize + dbCellOffset + rowBlockOffset + cellBlockOffset);
-        //Add space required to write the dbcell record(s) (whose references were just added).
-        dbCellOffset += (8 + (rows.getRowCountForBlock(block) * 2));
-      }
-      return index.serialize(offset, data);
+    /**
+     * @param indexRecordOffset also happens to be the end of the BOF record
+     * @return the size of the serialized INDEX record
+     */
+    private int serializeIndexRecord(final int bofRecordIndex, final int indexRecordOffset,
+            byte[] data) {
+        IndexRecord index = new IndexRecord();
+        index.setFirstRow(rows.getFirstRowNum());
+        index.setLastRowAdd1(rows.getLastRowNum() + 1);
+        // Calculate the size of the records from the end of the BOF
+        // and up to the RowRecordsAggregate...
+
+        // 'initial sheet records' are between INDEX and first ROW record.
+        int sizeOfInitialSheetRecords = 0;
+        // start just after BOF record (INDEX is not present in this list)
+        for (int j = bofRecordIndex + 1; j < records.size(); j++) {
+            Record tmpRec = ((Record) records.get(j));
+            if (tmpRec instanceof UncalcedRecord) {
+                continue;
+            }
+            if (tmpRec instanceof RowRecordsAggregate) {
+                break;
+            }
+            sizeOfInitialSheetRecords += tmpRec.getRecordSize();
+        }
+        if (_isUncalced) {
+            sizeOfInitialSheetRecords += UncalcedRecord.getStaticRecordSize();
+        }
+
+        // Add the references to the DBCells in the IndexRecord (one for each block)
+        // Note: The offsets are relative to the Workbook BOF. Assume that this is
+        // 0 for now.....
+
+        int blockCount = rows.getRowBlockCount();
+        // Calculate the size of this IndexRecord
+        int indexRecSize = IndexRecord.getRecordSizeForBlockCount(blockCount);
+
+        int currentOffset = indexRecordOffset + indexRecSize + sizeOfInitialSheetRecords;
+
+        for (int block = 0; block < blockCount; block++) {
+            // each row-block has a DBCELL record.
+            // The offset of each DBCELL record needs to be updated in the INDEX record
+
+            // account for row records in this row-block
+            currentOffset += rows.getRowBlockSize(block);
+            // account for cell value records after those
+            currentOffset += null == cells ? 0 : cells.getRowCellBlockSize(rows
+                    .getStartRowNumberForBlock(block), rows.getEndRowNumberForBlock(block));
+
+            // currentOffset is now the location of the DBCELL record for this row-block
+            index.addDbcell(currentOffset);
+            // Add space required to write the DBCELL record (whose reference was just added).
+            currentOffset += (8 + (rows.getRowCountForBlock(block) * 2));
+        }
+        return index.serialize(indexRecordOffset, data);
     }
 
 
@@ -2017,31 +2020,33 @@
     {
         int retval = 0;
 
-        for ( int k = 0; k < records.size(); k++ )
-        {
-            retval += ( (Record) records.get( k ) ).getRecordSize();
+        for ( int k = 0; k < records.size(); k++) {
+            Record record = (Record) records.get(k);
+            if (record instanceof UncalcedRecord) {
+                // skip the UncalcedRecord if present, it's only encoded if the isUncalced flag is set
+                continue;
+            }
+            retval += record.getRecordSize();
         }
-        //Add space for the IndexRecord
         if (rows != null) {
-            final int blocks = rows.getRowBlockCount();
-            retval += IndexRecord.getRecordSizeForBlockCount(blocks);
-
-            //Add space for the DBCell records
-            //Once DBCell per block.
-            //8 bytes per DBCell (non variable section)
-            //2 bytes per row reference
-            retval += (8 * blocks);
-            for (Iterator itr = rows.getIterator(); itr.hasNext();) {
-                RowRecord row = (RowRecord)itr.next();
-                if (cells != null && cells.rowHasCells(row.getRowNumber()))
-                    retval += 2;
+            // Add space for the IndexRecord and DBCell records
+            final int nBlocks = rows.getRowBlockCount();
+            int nRows = 0;
+            if (cells != null) {
+                for (Iterator itr = rows.getIterator(); itr.hasNext();) {
+                    RowRecord row = (RowRecord)itr.next();
+                    if (cells.rowHasCells(row.getRowNumber())) {
+                        nRows++;
+                    }
+                }
             }
+            retval += IndexRecord.getRecordSizeForBlockCount(nBlocks);
+            retval += DBCellRecord.calculateSizeOfRecords(nBlocks, nRows);
         }
         // Add space for UncalcedRecord
-        if (uncalced) {
+        if (_isUncalced) {
             retval += UncalcedRecord.getStaticRecordSize();
         }
-
         return retval;
     }
 
@@ -2518,13 +2523,13 @@
      * @return whether an uncalced record must be inserted or not at generation
      */
     public boolean getUncalced() {
-        return uncalced;
+        return _isUncalced;
     }
     /**
      * @param uncalced whether an uncalced record must be inserted or not at generation
      */
     public void setUncalced(boolean uncalced) {
-        this.uncalced = uncalced;
+        this._isUncalced = uncalced;
     }
 
     /**

Modified: poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/model/Workbook.java
URL: http://svn.apache.org/viewvc/poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/model/Workbook.java?rev=670186&r1=670185&r2=670186&view=diff
==============================================================================
--- poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/model/Workbook.java (original)
+++ poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/model/Workbook.java Sat Jun 21 05:03:44 2008
@@ -191,12 +191,11 @@
                 case ExternSheetRecord.sid :
                     throw new RuntimeException("Extern sheet is part of LinkTable");
                 case NameRecord.sid :
-                    throw new RuntimeException("DEFINEDNAME is part of LinkTable");
                 case SupBookRecord.sid :
+                    // LinkTable can start with either of these
                     if (log.check( POILogger.DEBUG ))
                         log.log(DEBUG, "found SupBook record at " + k);
                     retval.linkTable = new LinkTable(recs, k, retval.records);
-                    //                    retval.records.supbookpos = k;
                     k+=retval.linkTable.getRecordCount() - 1;
                     continue;
                 case FormatRecord.sid :
@@ -604,6 +603,29 @@
             boundsheets.remove(sheetnum);
             fixTabIdRecord();
         }
+        
+        // Within NameRecords, it's ok to have the formula
+        //  part point at deleted sheets. It's also ok to
+        //  have the ExternSheetNumber point at deleted
+        //  sheets. 
+        // However, the sheet index must be adjusted, or
+        //  excel will break. (Sheet index is either 0 for
+        //  global, or 1 based index to sheet)
+        int sheetNum1Based = sheetnum + 1;
+        for(int i=0; i<getNumNames(); i++) {
+        	NameRecord nr = getNameRecord(i);
+        	
+        	if(nr.getIndexToSheet() == sheetNum1Based) {
+        		// Excel re-writes these to point to no sheet
+        		nr.setEqualsToIndexToSheet((short)0);
+        	} else if(nr.getIndexToSheet() > sheetNum1Based) {
+        		// Bump down by one, so still points
+        		//  at the same sheet
+        		nr.setEqualsToIndexToSheet((short)(
+        				nr.getEqualsToIndexToSheet()-1
+        		));
+        	}
+        }
     }
 
     /**

Modified: poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/CFRuleRecord.java
URL: http://svn.apache.org/viewvc/poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/CFRuleRecord.java?rev=670186&r1=670185&r2=670186&view=diff
==============================================================================
--- poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/CFRuleRecord.java (original)
+++ poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/CFRuleRecord.java Sat Jun 21 05:03:44 2008
@@ -14,14 +14,10 @@
    See the License for the specific language governing permissions and
    limitations under the License.
 ==================================================================== */
-        
 
 package org.apache.poi.hssf.record;
 
-import java.util.Stack;
-
 import org.apache.poi.hssf.model.FormulaParser;
-import org.apache.poi.hssf.model.Workbook;
 import org.apache.poi.hssf.record.cf.BorderFormatting;
 import org.apache.poi.hssf.record.cf.FontFormatting;
 import org.apache.poi.hssf.record.cf.PatternFormatting;
@@ -30,7 +26,6 @@
 import org.apache.poi.util.BitField;
 import org.apache.poi.util.BitFieldFactory;
 import org.apache.poi.util.LittleEndian;
-import org.apache.poi.util.StringUtil;
 
 /**
  * Conditional Formatting Rule Record.
@@ -59,9 +54,6 @@
 
 	private byte  field_2_comparison_operator;
 
-	private short field_3_formula1_len;
-	private short field_4_formula2_len;
-
 	private int   field_5_options;
 
 	private static final BitField modificationBits = bf(0x003FFFFF); // Bits: font,align,bord,patt,prot
@@ -121,8 +113,6 @@
 	{
 		field_1_condition_type=conditionType;
 		field_2_comparison_operator=comparisonOperation;
-		field_3_formula1_len = (short)0;
-		field_4_formula2_len = (short)0;
 
 		// Set modification flags to 1: by default options are not modified
 		field_5_options = modificationBits.setValue(field_5_options, -1);
@@ -147,8 +137,8 @@
 		this(conditionType, comparisonOperation); 
 		field_1_condition_type = CONDITION_TYPE_CELL_VALUE_IS;
 		field_2_comparison_operator = comparisonOperation;
-		setParsedExpression1(formula1);
-		setParsedExpression2(formula2);
+		field_17_formula1 = formula1;
+		field_18_formula2 = formula2;
 	}
 
 	/**
@@ -167,63 +157,38 @@
 		Ptg[] formula1 = parseFormula(formulaText1, workbook);
 		Ptg[] formula2 = parseFormula(formulaText2, workbook);
 		return new CFRuleRecord(CONDITION_TYPE_CELL_VALUE_IS, comparisonOperation, formula1, formula2);
-		
 	}
 
-	/**
-	 * Constructs a Formula record and sets its fields appropriately.
-	 * Note - id must be 0x06 (NOT 0x406 see MSKB #Q184647 for an 
-	 * "explanation of this bug in the documentation) or an exception
-	 *  will be throw upon validation
-	 *
-	 * @param in the RecordInputstream to read the record from
-	 */
-
-	public CFRuleRecord(RecordInputStream in)
-	{
+	public CFRuleRecord(RecordInputStream in) {
 		super(in);
 	}
 
+	protected void fillFields(RecordInputStream in) {
+		field_1_condition_type = in.readByte();
+		field_2_comparison_operator = in.readByte();
+		int field_3_formula1_len = in.readUShort();
+		int field_4_formula2_len = in.readUShort();
+		field_5_options = in.readInt();
+		field_6_not_used = in.readShort();
 
+		if (containsFontFormattingBlock()) {
+			fontFormatting = new FontFormatting(in);
+		}
 
-	protected void fillFields(RecordInputStream in) {
-		try {
-			field_1_condition_type = in.readByte();
-			field_2_comparison_operator = in.readByte();
-			field_3_formula1_len = in.readShort();
-			field_4_formula2_len = in.readShort();
-			field_5_options = in.readInt();
-			field_6_not_used = in.readShort();
-
-			if (containsFontFormattingBlock()) {
-				fontFormatting = new FontFormatting(in);
-			}
-
-			if (containsBorderFormattingBlock()) {
-				borderFormatting = new BorderFormatting(in);
-			}
-
-			if (containsPatternFormattingBlock()) {
-				patternFormatting = new PatternFormatting(in);
-			}
-
-			if (field_3_formula1_len > 0) {
-				Stack ptgs = Ptg.createParsedExpressionTokens(field_3_formula1_len, in);
-				// Now convert any fields as required
-				ptgs = SharedFormulaRecord.convertSharedFormulas(ptgs, 0, 0);
-				field_17_formula1 = toArray(ptgs);
-			}
-			if (field_4_formula2_len > 0) {
-				Stack ptgs = Ptg.createParsedExpressionTokens(field_4_formula2_len, in);
-
-				// Now convert any fields as required
-				ptgs = SharedFormulaRecord.convertSharedFormulas(ptgs, 0, 0);
-				field_18_formula2 = toArray(ptgs);
-			}
-		} catch (java.lang.UnsupportedOperationException uoe) {
-			throw new RecordFormatException(uoe);
+		if (containsBorderFormattingBlock()) {
+			borderFormatting = new BorderFormatting(in);
+		}
+
+		if (containsPatternFormattingBlock()) {
+			patternFormatting = new PatternFormatting(in);
 		}
 
+		if (field_3_formula1_len > 0) {
+			field_17_formula1 = Ptg.readTokens(field_3_formula1_len, in);
+		}
+		if (field_4_formula2_len > 0) {
+			field_18_formula2 = Ptg.readTokens(field_4_formula2_len, in);
+		}
 	}
 
 	public byte getConditionType()
@@ -324,24 +289,6 @@
 	
 
 	/**
-	 * get the length (in number of tokens) of the expression 1
-	 * @return  expression length
-	 */
-	private short getExpression1Length()
-	{
-		return field_3_formula1_len;
-	}
-	
-
-	/**
-	 * get the length (in number of tokens) of the expression 2
-	 * @return  expression length
-	 */
-	private short getExpression2Length()
-	{
-		return field_4_formula2_len;
-	}
-	/**
 	 * get the option flags
 	 *
 	 * @return bit mask
@@ -489,16 +436,6 @@
 		return field_18_formula2;
 	}
 	
-	private void setParsedExpression1(Ptg[] ptgs) {
-		short len = getTotalPtgSize(field_17_formula1 = ptgs);
-		field_3_formula1_len = len;
-	}
-
-	private void setParsedExpression2(Ptg[] ptgs) {
-		short len = getTotalPtgSize(field_18_formula2 = ptgs);
-		field_4_formula2_len = len;
-	}
-	
 	/**
 	 * called by constructor, should throw runtime exception in the event of a
 	 * record passed with a differing ID.
@@ -520,6 +457,17 @@
 	}
 
 	/**
+	 * @param ptgs may be <code>null</code>
+	 * @return encoded size of the formula
+	 */
+	private static int getFormulaSize(Ptg[] ptgs) {
+		if (ptgs == null) {
+			return 0;
+		}
+		return Ptg.getEncodedSize(ptgs);
+	}
+	
+	/**
 	 * called by the class that is responsible for writing this sucker.
 	 * Subclasses should implement this so that their data is passed back in a
 	 * byte array.
@@ -528,18 +476,20 @@
 	 * @param data byte array containing instance data
 	 * @return number of bytes written
 	 */
-
 	public int serialize(int pOffset, byte [] data)
 	{
 		
+		int formula1Len=getFormulaSize(field_17_formula1);
+		int formula2Len=getFormulaSize(field_18_formula2);
+		
 		int offset = pOffset;
 		int recordsize = getRecordSize();
 		LittleEndian.putShort(data, 0 + offset, sid);
 		LittleEndian.putShort(data, 2 + offset, (short)(recordsize-4));
 		data[4 + offset] = field_1_condition_type;
 		data[5 + offset] = field_2_comparison_operator;
-		LittleEndian.putShort(data, 6 + offset, field_3_formula1_len);
-		LittleEndian.putShort(data, 8 + offset, field_4_formula2_len);
+		LittleEndian.putUShort(data, 6 + offset, formula1Len);
+		LittleEndian.putUShort(data, 8 + offset, formula2Len);
 		LittleEndian.putInt(data,  10 + offset, field_5_options);
 		LittleEndian.putShort(data,14 + offset, field_6_not_used);
 		
@@ -562,16 +512,12 @@
 			offset += patternFormatting.serialize(offset, data);
 		}
 		
-		if (getExpression1Length()>0)
-		{
-			Ptg.serializePtgStack(convertToTokenStack(field_17_formula1), data, offset);
-			offset += getExpression1Length();
+		if (field_17_formula1 != null) {
+			offset += Ptg.serializePtgs(field_17_formula1, data, offset);
 		}
 
-		if (getExpression2Length()>0)
-		{
-			Ptg.serializePtgStack(convertToTokenStack(field_18_formula2), data, offset);
-			offset += getExpression2Length();
+		if (field_18_formula2 != null) {
+			offset += Ptg.serializePtgs(field_18_formula2, data, offset);
 		}
 		if(offset - pOffset != recordsize) {
 			throw new IllegalStateException("write mismatch (" + (offset - pOffset) + "!=" + recordsize + ")");
@@ -586,24 +532,12 @@
 					(containsFontFormattingBlock()?fontFormatting.getRawRecord().length:0)+
 					(containsBorderFormattingBlock()?8:0)+
 					(containsPatternFormattingBlock()?4:0)+
-					getExpression1Length()+
-					getExpression2Length()
+					getFormulaSize(field_17_formula1)+
+					getFormulaSize(field_18_formula2)
 					;
 		return retval;
 	}
 
-	private short getTotalPtgSize(Ptg[] ptgs)
-	{
-		if( ptgs == null) {
-			return 0;
-		}
-		short  retval = 0;
-		for (int i = 0; i < ptgs.length; i++)
-		{
-			retval += ptgs[i].getSize();
-		}
-		return retval;
-	}
 
 	public String toString()
 	{
@@ -629,8 +563,6 @@
 	
 	public Object clone() {
 		CFRuleRecord rec = new CFRuleRecord(field_1_condition_type, field_2_comparison_operator);
-		rec.field_3_formula1_len = field_3_formula1_len;
-		rec.field_4_formula2_len = field_4_formula2_len;
 		rec.field_5_options = field_5_options;
 		rec.field_6_not_used = field_6_not_used;
 		if (containsFontFormattingBlock()) {
@@ -642,10 +574,10 @@
 		if (containsPatternFormattingBlock()) {
 			rec.patternFormatting = (PatternFormatting) patternFormatting.clone();
 		}
-		if (field_3_formula1_len > 0) {
+		if (field_17_formula1 != null) {
 			rec.field_17_formula1 = (Ptg[]) field_17_formula1.clone();
 		}
-		if (field_4_formula2_len > 0) {
+		if (field_18_formula2 != null) {
 			rec.field_18_formula2 = (Ptg[]) field_18_formula2.clone();
 		}
 
@@ -653,30 +585,17 @@
 	}
 
 	/**
+	 * TODO - parse conditional format formulas properly i.e. produce tRefN and tAreaN instead of tRef and tArea
+	 * this call will produce the wrong results if the formula contains any cell references
+	 * One approach might be to apply the inverse of SharedFormulaRecord.convertSharedFormulas(Stack, int, int)
+	 * Note - two extra parameters (rowIx & colIx) will be required. They probably come from one of the Region objects.
+	 * 
 	 * @return <code>null</code> if <tt>formula</tt> was null.
 	 */
-	private static Ptg[] parseFormula(String formula, HSSFWorkbook workbook)
-	{
+	private static Ptg[] parseFormula(String formula, HSSFWorkbook workbook) {
 		if(formula == null) {
 			return null;
 		}
 		return FormulaParser.parse(formula, workbook);
 	}
-
-	// TODO - treat formulas as token arrays instead of Stacks throughout the rest of POI
-	private static Stack convertToTokenStack(Ptg[] ptgs)
-	{
-		Stack parsedExpression = new Stack();
-		// fill the Ptg Stack with Ptgs of new formula
-		for (int k = 0; k < ptgs.length; k++) 
-		{
-			parsedExpression.push(ptgs[ k ]);
-		}
-		return parsedExpression;
-	}
-	private static Ptg[] toArray(Stack ptgs) {
-		Ptg[] result = new Ptg[ptgs.size()];
-		ptgs.toArray(result);
-		return result;
-	}
 }

Modified: poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/DBCellRecord.java
URL: http://svn.apache.org/viewvc/poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/DBCellRecord.java?rev=670186&r1=670185&r2=670186&view=diff
==============================================================================
--- poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/DBCellRecord.java (original)
+++ poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/DBCellRecord.java Sat Jun 21 05:03:44 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,7 +14,6 @@
    See the License for the specific language governing permissions and
    limitations under the License.
 ==================================================================== */
-        
 
 package org.apache.poi.hssf.record;
 
@@ -29,10 +27,7 @@
  * @author Jason Height
  * @version 2.0-pre
  */
-
-public class DBCellRecord
-    extends Record
-{
+public final class DBCellRecord extends Record {
     public final static int BLOCK_SIZE = 32;
     public final static short sid = 0xd7;
     private int               field_1_row_offset;
@@ -46,7 +41,6 @@
      * Constructs a DBCellRecord and sets its fields appropriately
      * @param in the RecordInputstream to read the record from
      */
-
     public DBCellRecord(RecordInputStream in)
     {
         super(in);
@@ -78,7 +72,6 @@
      *
      * @param offset    offset to the start of the first cell in the next DBCell block
      */
-
     public void setRowOffset(int offset)
     {
         field_1_row_offset = offset;
@@ -108,7 +101,6 @@
      *
      * @return rowoffset to the start of the first cell in the next DBCell block
      */
-
     public int getRowOffset()
     {
         return field_1_row_offset;
@@ -120,7 +112,6 @@
      * @param index of the cell offset to retrieve
      * @return celloffset from the celloffset array
      */
-
     public short getCellOffsetAt(int index)
     {
         return field_2_cell_offsets[ index ];
@@ -131,7 +122,6 @@
      *
      * @return number of cell offsets
      */
-
     public int getNumCellOffsets()
     {
         return field_2_cell_offsets.length;
@@ -175,9 +165,15 @@
         return 8 + (getNumCellOffsets() * 2);
     }
     
-    /** Returns the size of a DBCellRecord when it needs to reference a certain number of rows*/
-    public static int getRecordSizeForRows(int rows) {
-      return 8 + (rows * 2);
+    /**
+     *  @returns the size of the group of <tt>DBCellRecord</tt>s needed to encode
+     *  the specified number of blocks and rows
+     */
+    public static int calculateSizeOfRecords(int nBlocks, int nRows) {
+        // One DBCell per block.
+        // 8 bytes per DBCell (non variable section)
+        // 2 bytes per row reference
+        return nBlocks * 8 + nRows * 2;
     }
 
     public short getSid()

Modified: poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/EmbeddedObjectRefSubRecord.java
URL: http://svn.apache.org/viewvc/poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/EmbeddedObjectRefSubRecord.java?rev=670186&r1=670185&r2=670186&view=diff
==============================================================================
--- poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/EmbeddedObjectRefSubRecord.java (original)
+++ poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/EmbeddedObjectRefSubRecord.java Sat Jun 21 05:03:44 2008
@@ -108,7 +108,10 @@
             in.readByte(); // discard
         }
 
-        field_6_stream_id              = in.readInt();
+        // Fetch the stream ID
+        field_6_stream_id = in.readInt();
+        
+        // Store what's left
         remainingBytes = in.readRemainder();
     }
 

Modified: poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/FormulaRecord.java
URL: http://svn.apache.org/viewvc/poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/FormulaRecord.java?rev=670186&r1=670185&r2=670186&view=diff
==============================================================================
--- poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/FormulaRecord.java (original)
+++ poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/FormulaRecord.java Sat Jun 21 05:03:44 2008
@@ -557,7 +557,7 @@
       if (field_8_parsed_expr != null)
         size = field_8_parsed_expr.size();
       for (int i=0; i< size; i++) {
-        Ptg ptg = (Ptg)((Ptg)field_8_parsed_expr.get(i)).clone();        
+        Ptg ptg = ((Ptg)field_8_parsed_expr.get(i)).copy();        
         rec.field_8_parsed_expr.add(i, ptg);
       }
       rec.value_data = value_data;

Modified: poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/NameRecord.java
URL: http://svn.apache.org/viewvc/poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/NameRecord.java?rev=670186&r1=670185&r2=670186&view=diff
==============================================================================
--- poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/NameRecord.java (original)
+++ poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/NameRecord.java Sat Jun 21 05:03:44 2008
@@ -14,7 +14,6 @@
    See the License for the specific language governing permissions and
    limitations under the License.
 ==================================================================== */
-        
 
 package org.apache.poi.hssf.record;
 
@@ -22,9 +21,8 @@
 import java.util.List;
 import java.util.Stack;
 
+import org.apache.poi.hssf.model.FormulaParser;
 import org.apache.poi.hssf.record.formula.Area3DPtg;
-import org.apache.poi.hssf.record.formula.DeletedArea3DPtg;
-import org.apache.poi.hssf.record.formula.DeletedRef3DPtg;
 import org.apache.poi.hssf.record.formula.Ptg;
 import org.apache.poi.hssf.record.formula.Ref3DPtg;
 import org.apache.poi.hssf.record.formula.UnionPtg;
@@ -44,8 +42,7 @@
  * @author Glen Stampoultzis (glens at apache.org)
  * @version 1.0-pre
  */
-
-public class NameRecord extends Record {
+public final class NameRecord extends Record {
     /**
      */
     public final static short sid = 0x18; //Docs says that it is 0x218
@@ -650,50 +647,9 @@
     /** gets the reference , the area only (range)
      * @return area reference
      */
-    public String getAreaReference(HSSFWorkbook book){
-        if (field_13_name_definition == null || field_13_name_definition.isEmpty()) return "Error";
-        Ptg ptg = (Ptg) field_13_name_definition.peek();
-        String result = "";
-
-        // If it's a union, descend in and process
-        if (ptg.getClass() == UnionPtg.class) {
-            Iterator it =field_13_name_definition.iterator();
-            while( it.hasNext() ) {
-                Ptg p = (Ptg)it.next();
-
-                String thisRes = getAreaRefString(p, book);
-                if(thisRes.length() > 0) {
-                    // Add a comma to the end if needed
-                    if(result.length() > 0 && !result.endsWith(",")) {
-                        result += ",";
-                    }
-                    // And add the string it corresponds to
-                    result += thisRes;
-                }
-            }
-        } else {
-            // Otherwise just get the string
-            result = getAreaRefString(ptg, book);
-        }
-
-        return result;
-    }
-
-    /**
-     * Turn the given ptg into a string, or
-     *  return an empty string if nothing is possible
-     *  for it.
-     */
-    private String getAreaRefString(Ptg ptg,HSSFWorkbook book) {
-        if (ptg.getClass() == Area3DPtg.class){
-            return ptg.toFormulaString(book);
-        } else if (ptg.getClass() == Ref3DPtg.class){
-            return ptg.toFormulaString(book);
-        } else if (ptg.getClass() == DeletedArea3DPtg.class || ptg.getClass() == DeletedRef3DPtg.class) {
-        	return "#REF!";
-        }
-        return "";
-    }
+	public String getAreaReference(HSSFWorkbook book){
+		return FormulaParser.toFormulaString(book, field_13_name_definition);
+	}
 
     /** sets the reference , the area only (range)
      * @param ref area reference
@@ -737,7 +693,7 @@
         	}
         	// And then a union if we had more than one area
         	if(refs.length > 1) {
-        		ptg = new UnionPtg();
+        		ptg = UnionPtg.instance;
                 field_13_name_definition.push(ptg);
 	            this.setDefinitionTextLength( (short)(getDefinitionLength() + ptg.getSize()) );
         	}

Modified: poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/ObjRecord.java
URL: http://svn.apache.org/viewvc/poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/ObjRecord.java?rev=670186&r1=670185&r2=670186&view=diff
==============================================================================
--- poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/ObjRecord.java (original)
+++ poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/ObjRecord.java Sat Jun 21 05:03:44 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
@@ -16,27 +15,21 @@
    limitations under the License.
 ==================================================================== */
         
-
-
 package org.apache.poi.hssf.record;
 
-
-
-import org.apache.poi.util.*;
-
 import java.io.ByteArrayInputStream;
-import java.util.List;
-import java.util.Iterator;
 import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.poi.util.LittleEndian;
 
 /**
  * The obj record is used to hold various graphic objects and controls.
  *
  * @author Glen Stampoultzis (glens at apache.org)
  */
-public class ObjRecord
-    extends Record
-{
+public final class ObjRecord extends Record {
     public final static short      sid                             = 0x5D;
     private List subrecords;
 
@@ -47,6 +40,7 @@
     public ObjRecord()
     {
         subrecords = new ArrayList(2);
+        // TODO - ensure 2 sub-records (ftCmo  15h, and ftEnd  00h) are always created
     }
 
     /**
@@ -80,6 +74,7 @@
         //following wont work properly
         int subSize = 0;
         byte[] subRecordData = in.readRemainder();
+
         RecordInputStream subRecStream = new RecordInputStream(new ByteArrayInputStream(subRecordData));
         while(subRecStream.hasNextRecord()) {
           subRecStream.nextRecord();
@@ -89,28 +84,19 @@
         }
 
         /**
-         * Check if the RecordInputStream skipped EndSubRecord,
-         * if it did then append it explicitly.
-         * See Bug 41242 for details.
+         * Add the EndSubRecord explicitly.
+         * 
+         * TODO - the reason the EndSubRecord is always skipped is because its 'sid' is zero and
+         * that causes subRecStream.hasNextRecord() to return false.
+         * There may be more than the size of EndSubRecord left-over, if there is any padding 
+         * after that record.  The content of the EndSubRecord and the padding is all zeros.
+         * So there's not much to look at past the last substantial record.
+         * 
+         * See Bugs 41242/45133 for details.
          */
-        if (subRecordData.length - subSize == 4){
+        if (subRecordData.length - subSize >= 4) {
             subrecords.add(new EndSubRecord());
         }
-
-        /* JMH the size present/not present in the code below
-           needs to be considered in the RecordInputStream??
-        int pos = offset;
-        while (pos - offset <= size-2) // atleast one "short" must be present
-        {
-            short subRecordSid = LittleEndian.getShort(data, pos);
-            short subRecordSize = -1; // set default to "< 0"
-            if (pos-offset <= size-4) { // see if size info is present, else default to -1
-                subRecordSize = LittleEndian.getShort(data, pos + 2);
-            }
-            Record subRecord = SubRecord.createSubRecord(subRecordSid, subRecordSize, data, pos + 4);
-            subrecords.add(subRecord);
-            pos += subRecord.getRecordSize();
-        }*/
     }
 
     public String toString()
@@ -140,6 +126,8 @@
             Record record = (Record) iterator.next();
             pos += record.serialize(pos, data);
         }
+        // assume padding (if present) does not need to be written.
+        // it is probably zero already, and it probably doesn't matter anyway
 
         return getRecordSize();
     }
@@ -155,7 +143,9 @@
             Record record = (Record) iterator.next();
             size += record.getRecordSize();
         }
-        return 4  + size;
+        int oddBytes = size & 0x03;
+        int padding = oddBytes == 0 ? 0 : 4 - oddBytes;
+        return 4  + size + padding;
     }
 
     public short getSid()
@@ -192,9 +182,4 @@
 
         return rec;
     }
-
-}  // END OF CLASS
-
-
-
-
+}

Modified: poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/SharedFormulaRecord.java
URL: http://svn.apache.org/viewvc/poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/SharedFormulaRecord.java?rev=670186&r1=670185&r2=670186&view=diff
==============================================================================
--- poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/SharedFormulaRecord.java (original)
+++ poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/SharedFormulaRecord.java Sat Jun 21 05:03:44 2008
@@ -201,24 +201,16 @@
         if (ptgs != null)
           for (int k = 0; k < ptgs.size(); k++) {
             Ptg ptg = (Ptg) ptgs.get(k);
+            byte originalOperandClass = -1;
+            if (!ptg.isBaseToken()) {
+                originalOperandClass = ptg.getPtgClass();
+            }
             if (ptg instanceof RefNPtg) {
               RefNPtg refNPtg = (RefNPtg)ptg;
-              ptg = new ReferencePtg(fixupRelativeRow(formulaRow,refNPtg.getRow(),refNPtg.isRowRelative()),
+              ptg = new RefPtg(fixupRelativeRow(formulaRow,refNPtg.getRow(),refNPtg.isRowRelative()),
                                      fixupRelativeColumn(formulaColumn,refNPtg.getColumn(),refNPtg.isColRelative()),
                                      refNPtg.isRowRelative(),
                                      refNPtg.isColRelative());
-            } else if (ptg instanceof RefNVPtg) {
-              RefNVPtg refNVPtg = (RefNVPtg)ptg;
-              ptg = new RefVPtg(fixupRelativeRow(formulaRow,refNVPtg.getRow(),refNVPtg.isRowRelative()),
-                                fixupRelativeColumn(formulaColumn,refNVPtg.getColumn(),refNVPtg.isColRelative()),
-                                refNVPtg.isRowRelative(),
-                                refNVPtg.isColRelative());
-            } else if (ptg instanceof RefNAPtg) {
-              RefNAPtg refNAPtg = (RefNAPtg)ptg;
-              ptg = new RefAPtg( fixupRelativeRow(formulaRow,refNAPtg.getRow(),refNAPtg.isRowRelative()),
-                                 fixupRelativeColumn(formulaColumn,refNAPtg.getColumn(),refNAPtg.isColRelative()),
-                                 refNAPtg.isRowRelative(),
-                                 refNAPtg.isColRelative());
             } else if (ptg instanceof AreaNPtg) {
               AreaNPtg areaNPtg = (AreaNPtg)ptg;
               ptg = new AreaPtg(fixupRelativeRow(formulaRow,areaNPtg.getFirstRow(),areaNPtg.isFirstRowRelative()),
@@ -229,27 +221,11 @@
                                 areaNPtg.isLastRowRelative(),
                                 areaNPtg.isFirstColRelative(),
                                 areaNPtg.isLastColRelative());
-            } else if (ptg instanceof AreaNVPtg) {
-              AreaNVPtg areaNVPtg = (AreaNVPtg)ptg;
-              ptg = new AreaVPtg(fixupRelativeRow(formulaRow,areaNVPtg.getFirstRow(),areaNVPtg.isFirstRowRelative()),
-                                fixupRelativeRow(formulaRow,areaNVPtg.getLastRow(),areaNVPtg.isLastRowRelative()),
-                                fixupRelativeColumn(formulaColumn,areaNVPtg.getFirstColumn(),areaNVPtg.isFirstColRelative()),
-                                fixupRelativeColumn(formulaColumn,areaNVPtg.getLastColumn(),areaNVPtg.isLastColRelative()),
-                                areaNVPtg.isFirstRowRelative(),
-                                areaNVPtg.isLastRowRelative(),
-                                areaNVPtg.isFirstColRelative(),
-                                areaNVPtg.isLastColRelative());
-            } else if (ptg instanceof AreaNAPtg) {
-              AreaNAPtg areaNAPtg = (AreaNAPtg)ptg;
-              ptg = new AreaAPtg(fixupRelativeRow(formulaRow,areaNAPtg.getFirstRow(),areaNAPtg.isFirstRowRelative()),
-                                fixupRelativeRow(formulaRow,areaNAPtg.getLastRow(),areaNAPtg.isLastRowRelative()),
-                                fixupRelativeColumn(formulaColumn,areaNAPtg.getFirstColumn(),areaNAPtg.isFirstColRelative()),
-                                fixupRelativeColumn(formulaColumn,areaNAPtg.getLastColumn(),areaNAPtg.isLastColRelative()),
-                                areaNAPtg.isFirstRowRelative(),
-                                areaNAPtg.isLastRowRelative(),
-                                areaNAPtg.isFirstColRelative(),
-                                areaNAPtg.isLastColRelative());
-            } 
+            }
+            if (!ptg.isBaseToken()) {
+                ptg.setClass(originalOperandClass);
+            }
+            
             newPtgStack.add(ptg);
         }
         return newPtgStack;

Modified: poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/aggregates/ValueRecordsAggregate.java
URL: http://svn.apache.org/viewvc/poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/aggregates/ValueRecordsAggregate.java?rev=670186&r1=670185&r2=670186&view=diff
==============================================================================
--- poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/aggregates/ValueRecordsAggregate.java (original)
+++ poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/aggregates/ValueRecordsAggregate.java Sat Jun 21 05:03:44 2008
@@ -37,7 +37,7 @@
 public final class ValueRecordsAggregate
     extends Record
 {
-    public final static short sid       = -1000;
+    public final static short sid       = -1001; // 1000 clashes with RowRecordsAggregate
     int                       firstcell = -1;
     int                       lastcell  = -1;
   CellValueRecordInterface[][] records;

Modified: poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/formula/AbstractFunctionPtg.java
URL: http://svn.apache.org/viewvc/poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/formula/AbstractFunctionPtg.java?rev=670186&r1=670185&r2=670186&view=diff
==============================================================================
--- poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/formula/AbstractFunctionPtg.java (original)
+++ poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/formula/AbstractFunctionPtg.java Sat Jun 21 05:03:44 2008
@@ -44,6 +44,10 @@
     protected byte field_1_num_args;
     protected short field_2_fnc_index;
 
+    public final boolean isBaseToken() {
+    	return false;
+    }
+    
     public String toString() {
         StringBuffer sb = new StringBuffer(64);
         sb.append(getClass().getName()).append(" [");
@@ -52,12 +56,6 @@
         return sb.toString();
     }
 
-    public int getType() {
-        return -1;
-    }
-
-
-
     public short getFunctionIndex() {
         return field_2_fnc_index;
     }

Modified: poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/formula/AddPtg.java
URL: http://svn.apache.org/viewvc/poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/formula/AddPtg.java?rev=670186&r1=670185&r2=670186&view=diff
==============================================================================
--- poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/formula/AddPtg.java (original)
+++ poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/formula/AddPtg.java Sat Jun 21 05:03:44 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
@@ -16,69 +15,32 @@
    limitations under the License.
 ==================================================================== */
 
-/*
- * AddPtg.java
- *
- * Created on October 29, 2001, 7:48 PM
- */
 package org.apache.poi.hssf.record.formula;
 
-import org.apache.poi.hssf.usermodel.HSSFWorkbook;
-import org.apache.poi.hssf.record.RecordInputStream;
-
 /**
  * Addition operator PTG the "+" binomial operator.  If you need more 
  * explanation than that then well...We really can't help you here.
  * @author  Andrew C. Oliver (acoliver@apache.org)
  * @author Jason Height (jheight at chariot dot net dot au)
  */
-
-public class AddPtg
-    extends OperationPtg
-{
-    public final static int  SIZE = 1;
+public final class AddPtg extends ValueOperatorPtg {
     public final static byte sid  = 0x03;
     
     private final static String ADD = "+";
 
-    /** Creates new AddPtg */
+    public static final ValueOperatorPtg instance = new AddPtg();
 
-    public AddPtg()
-    {
-    }
-
-    public AddPtg(RecordInputStream in)
-    {
-
-        // doesn't need anything
+    private AddPtg() {
+    	// enforce singleton
     }
     
-   
-    public void writeBytes(byte [] array, int offset)
-    {
-        array[ offset + 0 ] = sid;
-    }
-
-    public int getSize()
-    {
-        return SIZE;
-    }
-
-    public int getType()
-    {
-        return TYPE_BINARY;
+    protected byte getSid() {
+    	return sid;
     }
 
-    public int getNumberOfOperands()
-    {
+    public int getNumberOfOperands() {
         return 2;
     }
-    
-    /** Implementation of method from Ptg */
-    public String toFormulaString(HSSFWorkbook book)
-    {
-        return "+";
-    }
        
    /** implementation of method from OperationsPtg*/  
     public String toFormulaString(String[] operands) {
@@ -89,11 +51,4 @@
         buffer.append(operands[ 1 ]);
         return buffer.toString();
     }
-    
-    public byte getDefaultOperandClass() {return Ptg.CLASS_VALUE;}
-           
-    public Object clone() {
-      return new AddPtg();
-    }
-
 }

Modified: poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/formula/Area3DPtg.java
URL: http://svn.apache.org/viewvc/poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/formula/Area3DPtg.java?rev=670186&r1=670185&r2=670186&view=diff
==============================================================================
--- poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/formula/Area3DPtg.java (original)
+++ poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/formula/Area3DPtg.java Sat Jun 21 05:03:44 2008
@@ -27,7 +27,7 @@
 
 
 /**
- * Title:        Area 3D Ptg - 3D referecnce (Sheet + Area)<P>
+ * Title:        Area 3D Ptg - 3D reference (Sheet + Area)<P>
  * Description:  Defined a area in Extern Sheet. <P>
  * REFERENCE:  <P>
  * @author Libin Roman (Vista Portal LDT. Developer)
@@ -35,9 +35,7 @@
  * @author Jason Height (jheight at chariot dot net dot au)
  * @version 1.0-pre
  */
-
-public class Area3DPtg extends Ptg implements AreaI
-{
+public final class Area3DPtg extends OperandPtg 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;
@@ -84,28 +82,20 @@
 		  setExternSheetIndex(externalSheetIndex);
 	}
 
-	public String toString()
-	{
-		StringBuffer buffer = new StringBuffer();
-
-		buffer.append( "AreaPtg\n" );
-		buffer.append( "Index to Extern Sheet = " + getExternSheetIndex() ).append( "\n" );
-		buffer.append( "firstRow = " + getFirstRow() ).append( "\n" );
-		buffer.append( "lastRow  = " + getLastRow() ).append( "\n" );
-		buffer.append( "firstCol = " + getFirstColumn() ).append( "\n" );
-		buffer.append( "lastCol  = " + getLastColumn() ).append( "\n" );
-		buffer.append( "firstColRel= "
-				+ isFirstRowRelative() ).append( "\n" );
-		buffer.append( "lastColRowRel = "
-				+ isLastRowRelative() ).append( "\n" );
-		buffer.append( "firstColRel   = " + isFirstColRelative() ).append( "\n" );
-		buffer.append( "lastColRel	= " + isLastColRelative() ).append( "\n" );
-		return buffer.toString();
+	public String toString() {
+		StringBuffer sb = new StringBuffer();
+		sb.append(getClass().getName());
+		sb.append(" [");
+		sb.append("sheetIx=").append(getExternSheetIndex());
+		sb.append(" ! ");
+		sb.append(AreaReference.formatAsString(this));
+		sb.append("]");
+		return sb.toString();
 	}
 
 	public void writeBytes( byte[] array, int offset )
 	{
-		array[0 + offset] = (byte) ( sid + ptgClass );
+		array[0 + offset] = (byte) ( sid + getPtgClass() );
 		LittleEndian.putShort( array, 1 + offset, getExternSheetIndex() );
 		LittleEndian.putShort( array, 3 + offset, (short)getFirstRow() );
 		LittleEndian.putShort( array, 5 + offset, (short)getLastRow() );
@@ -279,35 +269,28 @@
 		StringBuffer retval = new StringBuffer();
 		String sheetName = Ref3DPtg.getSheetName(book, field_1_index_extern_sheet);
 		if(sheetName != null) {
-			SheetNameFormatter.appendFormat(retval, sheetName);
+			if(sheetName.length() == 0) {
+				// What excel does if sheet has been deleted
+				sheetName = "#REF";
+				retval.append(sheetName);
+			} else {
+				// Normal
+				SheetNameFormatter.appendFormat(retval, sheetName);
+			}
 			retval.append( '!' );
 		}
 		
 		// Now the normal area bit
-		retval.append( AreaPtg.toFormulaString(this, book) );
+		retval.append(AreaReference.formatAsString(this));
 		
 		// All done
 		return retval.toString();
 	}
 
-	public byte getDefaultOperandClass()
-	{
+	public byte getDefaultOperandClass() {
 		return Ptg.CLASS_REF;
 	}
-
-	public Object clone()
-	{
-		Area3DPtg ptg = new Area3DPtg();
-		ptg.field_1_index_extern_sheet = field_1_index_extern_sheet;
-		ptg.field_2_first_row = field_2_first_row;
-		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);
-		return ptg;
-	}
-
-
+	// TODO - one junit relies on this. remove
 	public boolean equals( Object o )
 	{
 		if ( this == o ) return true;
@@ -323,17 +306,4 @@
 
 		return true;
 	}
-
-	public int hashCode()
-	{
-		int result;
-		result = (int) field_1_index_extern_sheet;
-		result = 29 * result + (int) field_2_first_row;
-		result = 29 * result + (int) field_3_last_row;
-		result = 29 * result + (int) field_4_first_column;
-		result = 29 * result + (int) field_5_last_column;
-		return result;
-	}
-
-
 }

Modified: poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/formula/AreaErrPtg.java
URL: http://svn.apache.org/viewvc/poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/formula/AreaErrPtg.java?rev=670186&r1=670185&r2=670186&view=diff
==============================================================================
--- poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/formula/AreaErrPtg.java (original)
+++ poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/formula/AreaErrPtg.java Sat Jun 21 05:03:44 2008
@@ -17,73 +17,40 @@
 
 package org.apache.poi.hssf.record.formula;
 
-import org.apache.poi.util.LittleEndian;
-import org.apache.poi.util.BitField;
-
-import org.apache.poi.hssf.usermodel.HSSFWorkbook;
 import org.apache.poi.hssf.record.RecordInputStream;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.apache.poi.util.LittleEndian;
 
 /**
  * AreaErr - handles deleted cell area references.
  *
  * @author Daniel Noll (daniel at nuix dot com dot au)
  */
-public class AreaErrPtg extends AreaPtg
-{
+public final class AreaErrPtg extends OperandPtg {
     public final static byte sid  = 0x2b;
 
-    private AreaErrPtg()
-    {
-        //Required for clone methods
-        super();
-    }
-    
-    public AreaErrPtg(RecordInputStream in)
-    {
-        super(in);
-    }
-
-    public String toString()
-    {
-        StringBuffer buffer = new StringBuffer();
-
-        buffer.append("AreaErrPtg\n");
-        buffer.append("firstRow = " + getFirstRow()).append("\n");
-        buffer.append("lastRow  = " + getLastRow()).append("\n");
-        buffer.append("firstCol = " + getFirstColumn()).append("\n");
-        buffer.append("lastCol  = " + getLastColumn()).append("\n");
-        buffer.append("firstColRowRel= "
-                      + isFirstRowRelative()).append("\n");
-        buffer.append("lastColRowRel = "
-                      + isLastRowRelative()).append("\n");
-        buffer.append("firstColRel   = " + isFirstColRelative()).append("\n");
-        buffer.append("lastColRel    = " + isLastColRelative()).append("\n");
-        return buffer.toString();
+    public AreaErrPtg(RecordInputStream in) {
+    	// 8 bytes unused:
+        in.readInt();
+        in.readInt();
     }
 
     public void writeBytes(byte [] array, int offset) {
-        super.writeBytes(array, offset);
-        array[offset] = (byte) (sid + ptgClass);
+        array[offset] = (byte) (sid + getPtgClass());
+        LittleEndian.putInt(array, offset+1, 0);
+        LittleEndian.putInt(array, offset+5, 0);
     }
 
-    public String toFormulaString(HSSFWorkbook book)
-    {
+    public String toFormulaString(HSSFWorkbook book) {
         return "#REF!";
     }
-    
-    public Object clone()
-    {
-        AreaErrPtg ptg = new AreaErrPtg();
-        ptg.setFirstRow(getFirstRow());
-        ptg.setFirstColumn(getFirstColumn());
-        ptg.setLastRow(getLastRow());
-        ptg.setLastColumn(getLastColumn());
-        ptg.setFirstColRelative(isFirstColRelative());
-        ptg.setLastColRelative(isLastColRelative());
-        ptg.setFirstRowRelative(isFirstRowRelative());
-        ptg.setLastRowRelative(isLastRowRelative());
-        ptg.setClass(ptgClass);
-        return ptg;
-    }
+
+	public byte getDefaultOperandClass() {
+		return Ptg.CLASS_REF;
+	}
+
+	public int getSize() {
+		return 9;
+	}
 }
 

Modified: poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/formula/AreaNPtg.java
URL: http://svn.apache.org/viewvc/poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/formula/AreaNPtg.java?rev=670186&r1=670185&r2=670186&view=diff
==============================================================================
--- poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/formula/AreaNPtg.java (original)
+++ poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/formula/AreaNPtg.java Sat Jun 21 05:03:44 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
@@ -16,49 +15,22 @@
    limitations under the License.
 ==================================================================== */
 
-/*
- * AreaPtg.java
- *
- * Created on November 17, 2001, 9:30 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.AreaReference;
-import org.apache.poi.hssf.util.CellReference;
-import org.apache.poi.hssf.usermodel.HSSFWorkbook;
 
 /**
  * Specifies a rectangular area of cells A1:A4 for instance.
  * @author Jason Height (jheight at chariot dot net dot au)
  */
+public final class AreaNPtg extends AreaPtgBase {
+	public final static short sid = 0x2D;
 
-public final class AreaNPtg extends AreaPtg
-{
-  public final static short sid  = 0x2D;
-
-  protected AreaNPtg() {
-    //Required for clone methods
-  }
-
-  public AreaNPtg(RecordInputStream in)
-  {
-    super(in);
-  }
-
-  public String getAreaPtgName() {
-    return "AreaNPtg";
-  }
-
-  public String toFormulaString(HSSFWorkbook book)
-  {
-    throw notImplemented();
-  }
-
-  public Object clone() {
-    throw notImplemented();
-  }
+	public AreaNPtg(RecordInputStream in) {
+		super(in);
+	}
+
+	protected byte getSid() {
+		return sid;
+	}
 }

Modified: poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/formula/ArrayPtg.java
URL: http://svn.apache.org/viewvc/poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/formula/ArrayPtg.java?rev=670186&r1=670185&r2=670186&view=diff
==============================================================================
--- poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/formula/ArrayPtg.java (original)
+++ poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/formula/ArrayPtg.java Sat Jun 21 05:03:44 2008
@@ -35,29 +35,32 @@
  *  
  * @author Jason Height (jheight at chariot dot net dot au)
  */
-public class ArrayPtg extends Ptg {
+public final class ArrayPtg extends Ptg {
 	public static final byte sid  = 0x20;
 
 	private static final int RESERVED_FIELD_LEN = 7;
 	// TODO - fix up field visibility and subclasses
-	protected byte[] field_1_reserved;
+	private byte[] field_1_reserved;
+	
 	// data from these fields comes after the Ptg data of all tokens in current formula
-	protected short  token_1_columns;
-	protected short token_2_rows;
-	protected Object[] token_3_arrayValues;
-
-	protected ArrayPtg() {
-	  //Required for clone methods
-	}
+	private short  token_1_columns;
+	private short token_2_rows;
+	private Object[] token_3_arrayValues;
 
-	public ArrayPtg(RecordInputStream in)
-	{
+	public ArrayPtg(RecordInputStream in) {
 		field_1_reserved = new byte[RESERVED_FIELD_LEN];
 		// TODO - add readFully method to RecordInputStream
 		for(int i=0; i< RESERVED_FIELD_LEN; i++) {
 			field_1_reserved[i] = in.readByte();
 		}
 	}
+	public Object[] getTokenArrayValues() {
+		return (Object[]) token_3_arrayValues.clone();
+	}
+	
+	public boolean isBaseToken() {
+		return false;
+	}
 	
 	/** 
 	 * Read in the actual token (array) values. This occurs 
@@ -95,6 +98,10 @@
 		return buffer.toString();
 	}
 
+	/**
+	 * Note - (2D) array elements are stored column by column 
+	 * @return the index into the internal 1D array for the specified column and row
+	 */
 	/* package */ int getValueIndex(int colIx, int rowIx) {
 		if(colIx < 0 || colIx >= token_1_columns) {
 			throw new IllegalArgumentException("Specified colIx (" + colIx 
@@ -104,12 +111,12 @@
 			throw new IllegalArgumentException("Specified rowIx (" + rowIx 
 					+ ") is outside the allowed range (0.." + (token_2_rows-1) + ")");
 		}
-		return rowIx * token_1_columns + colIx;
+		return rowIx + token_2_rows * colIx;
 	}
 
 	public void writeBytes(byte[] data, int offset) {
 		
-		LittleEndian.putByte(data, offset + 0, sid + ptgClass);
+		LittleEndian.putByte(data, offset + 0, sid + getPtgClass());
 		System.arraycopy(field_1_reserved, 0, data, offset+1, RESERVED_FIELD_LEN);
 	}
 
@@ -182,13 +189,9 @@
 	}
 	
 	public Object clone() {
-	  ArrayPtg ptg = new ArrayPtg();
+	  ArrayPtg ptg = (ArrayPtg) super.clone();
 	  ptg.field_1_reserved = (byte[]) field_1_reserved.clone();
-	  
-	  ptg.token_1_columns = token_1_columns;
-	  ptg.token_2_rows = token_2_rows;
 	  ptg.token_3_arrayValues = (Object[]) token_3_arrayValues.clone();
-	  ptg.setClass(ptgClass);
 	  return ptg;
 	}
 }

Modified: poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/formula/AttrPtg.java
URL: http://svn.apache.org/viewvc/poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/formula/AttrPtg.java?rev=670186&r1=670185&r2=670186&view=diff
==============================================================================
--- poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/formula/AttrPtg.java (original)
+++ poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/formula/AttrPtg.java Sat Jun 21 05:03:44 2008
@@ -15,7 +15,6 @@
    limitations under the License.
 ==================================================================== */
 
-
 package org.apache.poi.hssf.record.formula;
 
 import org.apache.poi.hssf.usermodel.HSSFWorkbook;
@@ -32,8 +31,7 @@
  * @author  andy
  * @author Jason Height (jheight at chariot dot net dot au)
  */
-
-public final class AttrPtg extends OperationPtg {
+public final class AttrPtg extends ControlPtg {
     public final static byte sid  = 0x19;
     private final static int  SIZE = 4;
     private byte              field_1_options;
@@ -289,12 +287,6 @@
       }
       return "UNKNOWN ATTRIBUTE";
      }
-    
-    
- 
-    public byte getDefaultOperandClass() {
-        return Ptg.CLASS_VALUE;
-    }
 
     public Object clone() {
         int[] jt;

Modified: poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/formula/BoolPtg.java
URL: http://svn.apache.org/viewvc/poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/formula/BoolPtg.java?rev=670186&r1=670185&r2=670186&view=diff
==============================================================================
--- poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/formula/BoolPtg.java (original)
+++ poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/formula/BoolPtg.java Sat Jun 21 05:03:44 2008
@@ -27,17 +27,10 @@
  * @author Andrew C. Oliver (acoliver at apache dot org)
  * @author Jason Height (jheight at chariot dot net dot au)
  */
-
-public class BoolPtg
-    extends Ptg
-{
+public final class BoolPtg extends ScalarConstantPtg {
     public final static int  SIZE = 2;
     public final static byte sid  = 0x1d;
-    private boolean          field_1_value;
-
-    private BoolPtg() {
-      //Required for clone methods
-    }
+    private final boolean field_1_value;
 
     public BoolPtg(RecordInputStream in)
     {
@@ -49,11 +42,6 @@
         field_1_value = (formulaToken.equals("TRUE"));
     }
 
-    public void setValue(boolean value)
-    {
-        field_1_value = value;
-    }
-
     public boolean getValue()
     {
         return field_1_value;
@@ -74,12 +62,4 @@
     {
         return field_1_value ? "TRUE" : "FALSE";
     }
-
-    public byte getDefaultOperandClass() {return Ptg.CLASS_VALUE;}
-
-    public Object clone() {
-        BoolPtg ptg = new BoolPtg();
-        ptg.field_1_value = field_1_value;
-        return ptg;
-    }
 }

Modified: poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/formula/ConcatPtg.java
URL: http://svn.apache.org/viewvc/poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/formula/ConcatPtg.java?rev=670186&r1=670185&r2=670186&view=diff
==============================================================================
--- poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/formula/ConcatPtg.java (original)
+++ poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/formula/ConcatPtg.java Sat Jun 21 05:03:44 2008
@@ -15,60 +15,31 @@
    limitations under the License.
 ==================================================================== */
 
-
 package org.apache.poi.hssf.record.formula;
 
-import org.apache.poi.hssf.usermodel.HSSFWorkbook;
-import org.apache.poi.hssf.record.RecordInputStream;
-
 /**
  *
  * @author  andy
  * @author Jason Height (jheight at chariot dot net dot au)
  */
-
-public class ConcatPtg
-    extends OperationPtg
-{
-    public final static int  SIZE = 1;
+public final class ConcatPtg extends ValueOperatorPtg {
     public final static byte sid  = 0x08;
     
     private final static String CONCAT = "&";
     
-    public ConcatPtg(RecordInputStream in)
-    {
-    	// No contents
-    }
-    
-    public ConcatPtg() {
-        
-    }
-
-    public void writeBytes(byte [] array, int offset)
-    {
-        array[ offset + 0 ] = sid;
-    }
+    public static final ValueOperatorPtg instance = new ConcatPtg();
 
-    public int getSize()
-    {
-        return SIZE;
+    private ConcatPtg() {
+    	// enforce singleton
     }
-
-    public int getType()
-    {
-        return TYPE_BINARY;
+    
+    protected byte getSid() {
+    	return sid;
     }
 
-    public int getNumberOfOperands()
-    {
+    public int getNumberOfOperands() {
         return 2;
     }
-
-    public String toFormulaString(HSSFWorkbook book)
-    {
-        return CONCAT;
-    }    
-
        
     public String toFormulaString(String[] operands) {
         StringBuffer buffer = new StringBuffer();
@@ -78,9 +49,4 @@
         buffer.append(operands[ 1 ]);
         return buffer.toString();
     }
-           
-    public Object clone() {
-      return new ConcatPtg();
-    }
-
 }

Modified: poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/formula/ControlPtg.java
URL: http://svn.apache.org/viewvc/poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/formula/ControlPtg.java?rev=670186&r1=670185&r2=670186&view=diff
==============================================================================
--- poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/formula/ControlPtg.java (original)
+++ poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/formula/ControlPtg.java Sat Jun 21 05:03:44 2008
@@ -15,11 +15,24 @@
    limitations under the License.
 ==================================================================== */
 
-
 package org.apache.poi.hssf.record.formula;
 
-public abstract class ControlPtg
-        extends Ptg
-{
+/**
+ * Common superclass for 
+ * tExp
+ * tTbl
+ * tParen
+ * tNlr
+ * tAttr
+ * tSheet
+ * tEndSheet
+ */
+public abstract class ControlPtg extends Ptg {
 
+	public boolean isBaseToken() {
+		return true;
+	}
+	public final byte getDefaultOperandClass() {
+		throw new IllegalStateException("Control tokens are not classified");
+	}
 }

Modified: poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/formula/DeletedArea3DPtg.java
URL: http://svn.apache.org/viewvc/poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/formula/DeletedArea3DPtg.java?rev=670186&r1=670185&r2=670186&view=diff
==============================================================================
--- poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/formula/DeletedArea3DPtg.java (original)
+++ poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/formula/DeletedArea3DPtg.java Sat Jun 21 05:03:44 2008
@@ -18,6 +18,9 @@
 package org.apache.poi.hssf.record.formula;
 
 import org.apache.poi.hssf.record.RecordInputStream;
+import org.apache.poi.hssf.usermodel.HSSFErrorConstants;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.apache.poi.util.LittleEndian;
 
 /**
  * Title:        Deleted Area 3D Ptg - 3D referecnce (Sheet + Area)<P>
@@ -26,19 +29,30 @@
  * @author Patrick Luby
  * @version 1.0-pre
  */
-
-public class DeletedArea3DPtg extends Area3DPtg
-{
+public final class DeletedArea3DPtg extends OperandPtg {
 	public final static byte sid = 0x3d;
+	private final int field_1_index_extern_sheet;
+	private final int unused1;
+	private final int unused2;
 
-    /** Creates new DeletedArea3DPtg */
-    public DeletedArea3DPtg( String arearef, short externIdx )
-    {
-        super(arearef, externIdx);
-    }
-
-    public DeletedArea3DPtg( RecordInputStream in)
-    {
-        super(in);
-    }
+	public DeletedArea3DPtg( RecordInputStream in) {
+		field_1_index_extern_sheet = in.readUShort();
+		unused1 = in.readInt();
+		unused2 = in.readInt();
+	}
+	public String toFormulaString(HSSFWorkbook book) {
+		return HSSFErrorConstants.getText(HSSFErrorConstants.ERROR_REF);
+	}
+	public byte getDefaultOperandClass() {
+		return Ptg.CLASS_REF;
+	}
+	public int getSize() {
+		return 11;
+	}
+	public void writeBytes(byte[] data, int offset) {
+		LittleEndian.putByte(data, 0 + offset, sid + getPtgClass());
+		LittleEndian.putUShort(data, 1 + offset, field_1_index_extern_sheet);
+		LittleEndian.putInt(data, 3 + offset, unused1);
+		LittleEndian.putInt(data, 7 + offset, unused2);
+	}
 }

Modified: poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/formula/DeletedRef3DPtg.java
URL: http://svn.apache.org/viewvc/poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/formula/DeletedRef3DPtg.java?rev=670186&r1=670185&r2=670186&view=diff
==============================================================================
--- poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/formula/DeletedRef3DPtg.java (original)
+++ poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/formula/DeletedRef3DPtg.java Sat Jun 21 05:03:44 2008
@@ -15,11 +15,13 @@
    limitations under the License.
 ==================================================================== */
 
-
 package org.apache.poi.hssf.record.formula;
 
 
 import org.apache.poi.hssf.record.RecordInputStream;
+import org.apache.poi.hssf.usermodel.HSSFErrorConstants;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.apache.poi.util.LittleEndian;
 
 /**
  * Title:        Deleted Reference 3D Ptg <P>
@@ -28,16 +30,29 @@
  * @author Patrick Luby
  * @version 1.0-pre
  */
-
-public class DeletedRef3DPtg extends Ref3DPtg {
-    public final static byte sid  = 0x3c;
-
-    /** Creates new DeletedRef3DPtg */
-    public DeletedRef3DPtg(RecordInputStream in) {
-        super(in);
-    }
-
-    public DeletedRef3DPtg(String cellref, short externIdx ) {
-        super(cellref, externIdx);
-    }
+public final class DeletedRef3DPtg extends OperandPtg {
+	public final static byte sid  = 0x3c;
+	private final int field_1_index_extern_sheet;
+	private final int unused1;
+
+	/** Creates new DeletedRef3DPtg */
+	public DeletedRef3DPtg(RecordInputStream in) {
+		field_1_index_extern_sheet = in.readUShort();
+		unused1 = in.readInt();
+	}
+
+	public String toFormulaString(HSSFWorkbook book) {
+		return HSSFErrorConstants.getText(HSSFErrorConstants.ERROR_REF);
+	}
+	public byte getDefaultOperandClass() {
+		return Ptg.CLASS_REF;
+	}
+	public int getSize() {
+		return 7;
+	}
+	public void writeBytes(byte[] data, int offset) {
+		LittleEndian.putByte(data, 0 + offset, sid + getPtgClass());
+		LittleEndian.putUShort(data, 1 + offset, field_1_index_extern_sheet);
+		LittleEndian.putInt(data, 3 + offset, unused1);
+	}
 }

Modified: poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/formula/DividePtg.java
URL: http://svn.apache.org/viewvc/poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/formula/DividePtg.java?rev=670186&r1=670185&r2=670186&view=diff
==============================================================================
--- poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/formula/DividePtg.java (original)
+++ poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/formula/DividePtg.java Sat Jun 21 05:03:44 2008
@@ -15,72 +15,36 @@
    limitations under the License.
 ==================================================================== */
 
-
 package org.apache.poi.hssf.record.formula;
 
-import org.apache.poi.hssf.usermodel.HSSFWorkbook;
-import org.apache.poi.hssf.record.RecordInputStream;
-
 /**
  * This PTG implements the standard binomial divide "/"
  * @author  Andrew C. Oliver acoliver at apache dot org
  * @author Jason Height (jheight at chariot dot net dot au)
  */
-
-public class DividePtg
-    extends OperationPtg
-{
-    public final static int  SIZE = 1;
+public final class DividePtg extends ValueOperatorPtg {
     public final static byte sid  = 0x06;
 
-    /** Creates new AddPtg */
-
-    public DividePtg()
-    {
-    }
-
-    public DividePtg(RecordInputStream in)
-    {
+    public static final ValueOperatorPtg instance = new DividePtg();
 
-        // doesn't need anything
+    private DividePtg() {
+    	// enforce singleton
     }
-
-    public void writeBytes(byte [] array, int offset)
-    {
-        array[ offset + 0 ] = sid;
+    
+    protected byte getSid() {
+    	return sid;
     }
 
-    public int getSize()
-    {
-        return SIZE;
-    }
-
-    public int getType()
-    {
-        return TYPE_BINARY;
-    }
-
-    public int getNumberOfOperands()
-    {
+    public int getNumberOfOperands() {
         return 2;
     }
 
-    public String toFormulaString(HSSFWorkbook book)
-    {
-        return "/";
-    }
-
      public String toFormulaString(String[] operands) {
         StringBuffer buffer = new StringBuffer();
 
         buffer.append(operands[ 0 ]);
-        buffer.append(toFormulaString((HSSFWorkbook)null));
+        buffer.append("/");
         buffer.append(operands[ 1 ]);
         return buffer.toString();
     }      
-
-    public Object clone() {
-      DividePtg ptg = new DividePtg();
-      return ptg;
-    }
 }

Modified: poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/formula/EqualPtg.java
URL: http://svn.apache.org/viewvc/poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/formula/EqualPtg.java?rev=670186&r1=670185&r2=670186&view=diff
==============================================================================
--- poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/formula/EqualPtg.java (original)
+++ poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/formula/EqualPtg.java Sat Jun 21 05:03:44 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
@@ -18,70 +17,34 @@
 
 package org.apache.poi.hssf.record.formula;
 
-import org.apache.poi.hssf.usermodel.HSSFWorkbook;
-import org.apache.poi.hssf.record.RecordInputStream;
-
 /**
  *
  * @author  andy
  */
-
-public class EqualPtg
-    extends OperationPtg
-{
-    public final static int  SIZE = 1;
+public final class EqualPtg extends ValueOperatorPtg {
     public final static byte sid  = 0x0b;
 
-    /** Creates new AddPtg */
+    public static final ValueOperatorPtg instance = new EqualPtg();
 
-   public EqualPtg()
-    {
+    private EqualPtg() {
+    	// enforce singleton
     }
-
-    public EqualPtg(RecordInputStream in)
-    {
-
-        // doesn't need anything
-    }
-
-    public void writeBytes(byte [] array, int offset)
-    {
-        array[ offset + 0 ] = sid;
-    }
-
-    public int getSize()
-    {
-        return SIZE;
+    
+    protected byte getSid() {
+    	return sid;
     }
 
-    public int getType()
-    {
-        return TYPE_BINARY;
-    }
-
-    public int getNumberOfOperands()
-    {
+    public int getNumberOfOperands() {
         return 2;
     }
-
-    public String toFormulaString(HSSFWorkbook book)
-    {
-        return "=";
-    }
  
     public String toFormulaString(String[] operands) {
          StringBuffer buffer = new StringBuffer();
 
         
         buffer.append(operands[ 0 ]);
-        buffer.append(toFormulaString((HSSFWorkbook)null));
+        buffer.append("=");
         buffer.append(operands[ 1 ]);
         return buffer.toString();
     }       
-
-    public Object clone() {
-      return new EqualPtg();
-    }
-
-
 }

Modified: poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/formula/ErrPtg.java
URL: http://svn.apache.org/viewvc/poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/formula/ErrPtg.java?rev=670186&r1=670185&r2=670186&view=diff
==============================================================================
--- poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/formula/ErrPtg.java (original)
+++ poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/formula/ErrPtg.java Sat Jun 21 05:03:44 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
@@ -16,7 +15,6 @@
    limitations under the License.
 ==================================================================== */
 
-
 package org.apache.poi.hssf.record.formula;
 
 import org.apache.poi.hssf.usermodel.HSSFWorkbook;
@@ -26,7 +24,7 @@
 /**
  * @author Daniel Noll (daniel at nuix dot com dot au)
  */
-public final class ErrPtg extends Ptg {
+public final class ErrPtg extends ScalarConstantPtg {
     
     // convenient access to namespace
     private static final HSSFErrorConstants EC = null;
@@ -49,7 +47,7 @@
     
     public static final short sid  = 0x1c;
     private static final int  SIZE = 2;
-    private int              field_1_error_code;
+    private final int field_1_error_code;
 
     /** Creates new ErrPtg */
 
@@ -66,7 +64,7 @@
 
     public void writeBytes(byte [] array, int offset)
     {
-        array[offset] = (byte) (sid + ptgClass);
+        array[offset] = (byte) (sid + getPtgClass());
         array[offset + 1] = (byte)field_1_error_code;
     }
 
@@ -78,14 +76,6 @@
         return SIZE;
     }
 
-    public byte getDefaultOperandClass() {
-        return Ptg.CLASS_VALUE;
-    }
-
-    public Object clone() {
-        return new ErrPtg(field_1_error_code);
-    }
-
     public int getErrorCode() {
         return field_1_error_code;
     }

Modified: poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/formula/ExpPtg.java
URL: http://svn.apache.org/viewvc/poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/formula/ExpPtg.java?rev=670186&r1=670185&r2=670186&view=diff
==============================================================================
--- poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/formula/ExpPtg.java (original)
+++ poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/formula/ExpPtg.java Sat Jun 21 05:03:44 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
@@ -30,29 +29,18 @@
  * @author Jason Height (jheight at chariot dot net dot au)
  * @author dmui (save existing implementation)
  */
-
-public class ExpPtg
-    extends Ptg
-{
+public final class ExpPtg extends ControlPtg {
     private final static int  SIZE = 5;
     public final static short sid  = 0x1;
-    private short            field_1_first_row;
-    private short            field_2_first_col;
-
-    /** Creates new ExpPtg */
-
-    public ExpPtg()
-    {
-    }
-
-    /** Creates new ExpPtg */
+    private final short            field_1_first_row;
+    private final short            field_2_first_col;
 
     public ExpPtg(RecordInputStream in)
     {
       field_1_first_row = in.readShort();
       field_2_first_col = in.readShort();
     }
-
+    
     public void writeBytes(byte [] array, int offset)
     {
       array[offset+0]= (byte) (sid);
@@ -85,14 +73,4 @@
         buffer.append("col = ").append(getColumn()).append("\n");
         return buffer.toString();
     }    
-    
-    public byte getDefaultOperandClass() {return Ptg.CLASS_VALUE;}
-    
-    public Object clone() {
-	ExpPtg result = new ExpPtg();
-        result.field_1_first_row = field_1_first_row;
-        result.field_2_first_col = field_2_first_col;        
-        return result;
-    }
-
 }

Modified: poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/formula/FuncPtg.java
URL: http://svn.apache.org/viewvc/poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/formula/FuncPtg.java?rev=670186&r1=670185&r2=670186&view=diff
==============================================================================
--- poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/formula/FuncPtg.java (original)
+++ poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/formula/FuncPtg.java Sat Jun 21 05:03:44 2008
@@ -44,6 +44,8 @@
             throw new RuntimeException("Invalid built-in function index (" + field_2_fnc_index + ")");
         }
         numParams = fm.getMinParams();
+        returnClass = fm.getReturnClassCode();
+        paramClass = fm.getParameterClassCodes();
     }
     public FuncPtg(int functionIndex) {
         field_2_fnc_index = (short) functionIndex;
@@ -54,7 +56,7 @@
     }
 
     public void writeBytes(byte[] array, int offset) {
-        array[offset+0]= (byte) (sid + ptgClass);
+        array[offset+0]= (byte) (sid + getPtgClass());
         LittleEndian.putShort(array,offset+1,field_2_fnc_index);
     }
 
@@ -62,12 +64,6 @@
         return numParams;
     }
 
-    public Object clone() {
-        FuncPtg ptg = new FuncPtg(field_2_fnc_index);
-        ptg.setClass(ptgClass);
-        return ptg;
-    }
-
     public int getSize() {
         return SIZE;
     }

Modified: poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/formula/FuncVarPtg.java
URL: http://svn.apache.org/viewvc/poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/formula/FuncVarPtg.java?rev=670186&r1=670185&r2=670186&view=diff
==============================================================================
--- poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/formula/FuncVarPtg.java (original)
+++ poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/formula/FuncVarPtg.java Sat Jun 21 05:03:44 2008
@@ -30,16 +30,21 @@
     public final static byte sid  = 0x22;
     private final static int  SIZE = 4;
 
-    private FuncVarPtg() {
-      //Required for clone methods
-    }
-
- /**Creates new function pointer from a byte array
+    /**Creates new function pointer from a byte array
      * usually called while reading an excel file.
      */
     public FuncVarPtg(RecordInputStream in) {
         field_1_num_args = in.readByte();
         field_2_fnc_index  = in.readShort();
+        FunctionMetadata fm = FunctionMetadataRegistry.getFunctionByIndex(field_2_fnc_index);
+        if(fm == null) {
+            // Happens only as a result of a call to FormulaParser.parse(), with a non-built-in function name
+            returnClass = Ptg.CLASS_VALUE;
+            paramClass = new byte[] {Ptg.CLASS_VALUE};
+        } else {
+            returnClass = fm.getReturnClassCode();
+            paramClass = fm.getParameterClassCodes();
+        }
     }
 
     /**
@@ -60,7 +65,7 @@
     }
 
      public void writeBytes(byte[] array, int offset) {
-        array[offset+0]=(byte) (sid + ptgClass);
+        array[offset+0]=(byte) (sid + getPtgClass());
         array[offset+1]=field_1_num_args;
         LittleEndian.putShort(array,offset+2,field_2_fnc_index);
     }
@@ -69,14 +74,6 @@
         return field_1_num_args;
     }
 
-    public Object clone() {
-      FuncVarPtg ptg = new FuncVarPtg();
-      ptg.field_1_num_args = field_1_num_args;
-      ptg.field_2_fnc_index = field_2_fnc_index;
-      ptg.setClass(ptgClass);
-      return ptg;
-    }
-
     public int getSize() {
         return SIZE;
     }

Modified: poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/formula/GreaterEqualPtg.java
URL: http://svn.apache.org/viewvc/poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/formula/GreaterEqualPtg.java?rev=670186&r1=670185&r2=670186&view=diff
==============================================================================
--- poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/formula/GreaterEqualPtg.java (original)
+++ poi/tags/REL_3_1_FINAL/src/java/org/apache/poi/hssf/record/formula/GreaterEqualPtg.java Sat Jun 21 05:03:44 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
@@ -16,75 +15,40 @@
    limitations under the License.
 ==================================================================== */
 
-
 package org.apache.poi.hssf.record.formula;
 
-import org.apache.poi.hssf.usermodel.HSSFWorkbook;
-import org.apache.poi.hssf.record.RecordInputStream;
-
 
 /**
  * PTG class to implement greater or equal to
  *
  * @author  fred at stsci dot edu
  */
-
-public class GreaterEqualPtg
-    extends OperationPtg
-{
+public final class GreaterEqualPtg extends ValueOperatorPtg {
     public final static int  SIZE = 1;
     public final static byte sid  = 0x0c;
 
-    /** Creates new GreaterEqualPtg */
-
-   public GreaterEqualPtg()
-    {
-    }
-
-    public GreaterEqualPtg(RecordInputStream in)
-    {
-
-        // doesn't need anything
-    }
-
-    public void writeBytes(byte [] array, int offset)
-    {
-        array[ offset + 0 ] = sid;
-    }
+    public static final ValueOperatorPtg instance = new GreaterEqualPtg();
 
-    public int getSize()
-    {
-        return SIZE;
+    private GreaterEqualPtg() {
+    	// enforce singleton
     }
-
-    public int getType()
-    {
-        return TYPE_BINARY;
+    
+    protected byte getSid() {
+    	return sid;
     }
 
-    public int getNumberOfOperands()
-    {
+    public int getNumberOfOperands() {
         return 2;
     }
 
-    public String toFormulaString(HSSFWorkbook book)
-    {
-        return ">=";
-    }
-
     public String toFormulaString(String[] operands) {
          StringBuffer buffer = new StringBuffer();
 
         buffer.append(operands[ 0 ]);
 
-        buffer.append(toFormulaString((HSSFWorkbook)null));
+        buffer.append(">=");
         buffer.append(operands[ 1 ]);
 
         return buffer.toString();
     }
-
-    public Object clone() {
-      return new GreaterEqualPtg();
-    }
-
 }



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