Return-Path: Mailing-List: contact poi-dev-help@jakarta.apache.org; run by ezmlm Delivered-To: mailing list poi-dev@jakarta.apache.org Received: (qmail 10791 invoked by uid 500); 8 May 2003 00:01:59 -0000 Received: (qmail 10785 invoked from network); 8 May 2003 00:01:59 -0000 Received: from icarus.apache.org (208.185.179.13) by daedalus.apache.org with SMTP; 8 May 2003 00:01:59 -0000 Received: (qmail 59719 invoked by uid 1639); 8 May 2003 00:02:03 -0000 Date: 8 May 2003 00:02:03 -0000 Message-ID: <20030508000203.59718.qmail@icarus.apache.org> From: dmui@apache.org To: jakarta-poi-cvs@apache.org Subject: cvs commit: jakarta-poi/src/testcases/org/apache/poi/hssf/record/aggregates TestValueRecordsAggregate.java X-Spam-Rating: daedalus.apache.org 1.6.2 0/1000/N dmui 2003/05/07 17:02:03 Modified: src/java/org/apache/poi/hssf/dev BiffViewer.java src/java/org/apache/poi/hssf/eventmodel EventRecordFactory.java src/java/org/apache/poi/hssf/record RecordFactory.java src/java/org/apache/poi/hssf/record/aggregates FormulaRecordAggregate.java ValueRecordsAggregate.java src/java/org/apache/poi/hssf/record/formula ExpPtg.java src/testcases/org/apache/poi/hssf/record TestFormulaRecord.java Added: src/java/org/apache/poi/hssf/record SharedFormulaRecord.java src/testcases/org/apache/poi/hssf/record/aggregates TestValueRecordsAggregate.java Log: Patch to support reading in Shared Formulas 1) Added new Record: SharedFormulaRecord that is basically a storage area 2) Enabled ExpPtg to store and serialize data for repeating formulas 3) Updated the aggregates to store the SharedFormulaRecord appropriately Revision Changes Path 1.31 +3 -0 jakarta-poi/src/java/org/apache/poi/hssf/dev/BiffViewer.java Index: BiffViewer.java =================================================================== RCS file: /home/cvs/jakarta-poi/src/java/org/apache/poi/hssf/dev/BiffViewer.java,v retrieving revision 1.30 retrieving revision 1.31 diff -u -r1.30 -r1.31 --- BiffViewer.java 30 Apr 2003 04:39:11 -0000 1.30 +++ BiffViewer.java 8 May 2003 00:02:03 -0000 1.31 @@ -630,6 +630,9 @@ case PaneRecord.sid: retval = new PaneRecord( rectype, size, data ); break; + case SharedFormulaRecord.sid: + retval = new SharedFormulaRecord( rectype, size, data); + break; default: retval = new UnknownRecord( rectype, size, data ); } 1.5 +8 -5 jakarta-poi/src/java/org/apache/poi/hssf/eventmodel/EventRecordFactory.java Index: EventRecordFactory.java =================================================================== RCS file: /home/cvs/jakarta-poi/src/java/org/apache/poi/hssf/eventmodel/EventRecordFactory.java,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- EventRecordFactory.java 30 Apr 2003 04:39:19 -0000 1.4 +++ EventRecordFactory.java 8 May 2003 00:02:03 -0000 1.5 @@ -54,12 +54,14 @@ */ package org.apache.poi.hssf.eventmodel; -import java.io.InputStream; import java.io.IOException; - -import java.util.*; - +import java.io.InputStream; import java.lang.reflect.Constructor; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; import org.apache.poi.hssf.record.BOFRecord; import org.apache.poi.hssf.record.BackupRecord; @@ -126,6 +128,7 @@ import org.apache.poi.hssf.record.SSTRecord; import org.apache.poi.hssf.record.SaveRecalcRecord; import org.apache.poi.hssf.record.SelectionRecord; +import org.apache.poi.hssf.record.SharedFormulaRecord; import org.apache.poi.hssf.record.StringRecord; import org.apache.poi.hssf.record.StyleRecord; import org.apache.poi.hssf.record.TabIdRecord; @@ -189,7 +192,7 @@ BoolErrRecord.class, ExternSheetRecord.class, NameRecord.class, LeftMarginRecord.class, RightMarginRecord.class, TopMarginRecord.class, BottomMarginRecord.class, - PaletteRecord.class, StringRecord.class + PaletteRecord.class, StringRecord.class, SharedFormulaRecord.class }; } 1.16 +2 -2 jakarta-poi/src/java/org/apache/poi/hssf/record/RecordFactory.java Index: RecordFactory.java =================================================================== RCS file: /home/cvs/jakarta-poi/src/java/org/apache/poi/hssf/record/RecordFactory.java,v retrieving revision 1.15 retrieving revision 1.16 diff -u -r1.15 -r1.16 --- RecordFactory.java 30 Apr 2003 04:38:47 -0000 1.15 +++ RecordFactory.java 8 May 2003 00:02:03 -0000 1.16 @@ -112,7 +112,7 @@ FormulaRecord.class, BoolErrRecord.class, ExternSheetRecord.class, NameRecord.class, LeftMarginRecord.class, RightMarginRecord.class, TopMarginRecord.class, BottomMarginRecord.class, - PaletteRecord.class, StringRecord.class, RecalcIdRecord.class + PaletteRecord.class, StringRecord.class, RecalcIdRecord.class, SharedFormulaRecord.class }; } else { records = new Class[] @@ -143,7 +143,7 @@ BoolErrRecord.class, ExternSheetRecord.class, NameRecord.class, LeftMarginRecord.class, RightMarginRecord.class, TopMarginRecord.class, BottomMarginRecord.class, - PaletteRecord.class, StringRecord.class, RecalcIdRecord.class + PaletteRecord.class, StringRecord.class, RecalcIdRecord.class, SharedFormulaRecord.class }; } 1.1 jakarta-poi/src/java/org/apache/poi/hssf/record/SharedFormulaRecord.java Index: SharedFormulaRecord.java =================================================================== /* ==================================================================== * The Apache Software License, Version 1.1 * * Copyright (c) 2003 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "Apache" and "Apache Software Foundation" and * "Apache POI" must not be used to endorse or promote products * derived from this software without prior written permission. For * written permission, please contact apache@apache.org. * * 5. Products derived from this software may not be called "Apache", * "Apache POI", nor may "Apache" appear in their name, without * prior written permission of the Apache Software Foundation. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . */ package org.apache.poi.hssf.record; import org.apache.poi.util.LittleEndian; /** * Title: SharedFormulaRecord * Description: Primarily used as an excel optimization so that multiple similar formulas * are not written out too many times. We should recognize this record and * serialize as is since this is used when reading templates. *

* Note: the documentation says that the SID is BC where biffviewer reports 4BC. The hex dump shows * that the two byte sid representation to be 'BC 04' that is consistent with the other high byte * record types. * @author Danny Mui at apache dot org */ public class SharedFormulaRecord extends Record { public final static short sid = 0x4BC; private short size = 0; private byte[] thedata = null; int offset = 0; public SharedFormulaRecord() { } /** * construct the sharedformula record, save all the information * @param id id of the record -not validated, just stored for serialization * @param size size of the data * @param data the data */ public SharedFormulaRecord(short id, short size, byte [] data) { super(id, size, data); this.fillFields(data, size, 0); } /** * spit the record out AS IS. no interperatation or identification */ public int serialize(int offset, byte [] data) { if (thedata == null) { thedata = new byte[ 0 ]; } LittleEndian.putShort(data, 0 + offset, sid); LittleEndian.putShort(data, 2 + offset, ( short ) (thedata.length)); if (thedata.length > 0) { System.arraycopy(thedata, 0, data, 4 + offset, thedata.length); } return getRecordSize(); } public int getRecordSize() { int retval = 4; if (thedata != null) { retval += thedata.length; } return retval; } protected void validateSid(short id) { if (id != this.sid) { throw new RecordFormatException("Not a valid SharedFormula"); } } /** * print a sort of string representation ([SHARED FORMULA RECORD] id = x [/SHARED FORMULA RECORD]) */ public String toString() { StringBuffer buffer = new StringBuffer(); buffer.append("[SHARED FORMULA RECORD:" + Integer.toHexString(sid) + "]\n"); buffer.append(" .id = ").append(Integer.toHexString(sid)) .append("\n"); buffer.append("[/SHARED FORMULA RECORD]\n"); return buffer.toString(); } public short getSid() { return this.sid; } /** * Shared formulas are to treated like unknown records, and as a result d */ protected void fillFields(byte [] data, short size, int offset) { thedata = new byte[size]; System.arraycopy(data, 0, thedata, 0, size); } /** * 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() { SharedFormulaRecord rec = new SharedFormulaRecord(); rec.offset = offset; rec.size = size; rec.thedata = thedata; return rec; } } 1.4 +27 -1 jakarta-poi/src/java/org/apache/poi/hssf/record/aggregates/FormulaRecordAggregate.java Index: FormulaRecordAggregate.java =================================================================== RCS file: /home/cvs/jakarta-poi/src/java/org/apache/poi/hssf/record/aggregates/FormulaRecordAggregate.java,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- FormulaRecordAggregate.java 30 Apr 2003 04:39:20 -0000 1.3 +++ FormulaRecordAggregate.java 8 May 2003 00:02:03 -0000 1.4 @@ -58,7 +58,7 @@ /** * The formula record aggregate is used to join together the formula record and it's - * (optional) string record. + * (optional) string record and (optional) Shared Formula Record (template reads, excel optimization). * * @author Glen Stampoultzis (glens at apache.org) */ @@ -70,6 +70,11 @@ private FormulaRecord formulaRecord; private StringRecord stringRecord; + + /** + * will only be set through the RecordFactory + */ + private SharedFormulaRecord sharedFormulaRecord; public FormulaRecordAggregate( FormulaRecord formulaRecord, StringRecord stringRecord ) { @@ -105,7 +110,12 @@ { pos += stringRecord.serialize(pos, data); } + if (this.getSharedFormulaRecord() != null) + { + pos += getSharedFormulaRecord().serialize(pos, data); + } return pos - offset; + } /** @@ -114,6 +124,7 @@ public int getRecordSize() { int size = formulaRecord.getRecordSize() + (stringRecord == null ? 0 : stringRecord.getRecordSize()); + size += (getSharedFormulaRecord() == null) ? 0 : getSharedFormulaRecord().getRecordSize(); return size; } @@ -214,5 +225,20 @@ } + + /** + * @return SharedFormulaRecord + */ + public SharedFormulaRecord getSharedFormulaRecord() { + return sharedFormulaRecord; + } + + /** + * Sets the sharedFormulaRecord, only set from RecordFactory since they are not generated by POI and are an Excel optimization + * @param sharedFormulaRecord The sharedFormulaRecord to set + */ + public void setSharedFormulaRecord(SharedFormulaRecord sharedFormulaRecord) { + this.sharedFormulaRecord = sharedFormulaRecord; + } } 1.8 +5 -0 jakarta-poi/src/java/org/apache/poi/hssf/record/aggregates/ValueRecordsAggregate.java Index: ValueRecordsAggregate.java =================================================================== RCS file: /home/cvs/jakarta-poi/src/java/org/apache/poi/hssf/record/aggregates/ValueRecordsAggregate.java,v retrieving revision 1.7 retrieving revision 1.8 diff -u -r1.7 -r1.8 --- ValueRecordsAggregate.java 30 Apr 2003 04:39:20 -0000 1.7 +++ ValueRecordsAggregate.java 8 May 2003 00:02:03 -0000 1.8 @@ -157,6 +157,11 @@ { lastFormulaAggregate.setStringRecord((StringRecord)rec); } + else if (rec instanceof SharedFormulaRecord) + { + //these follow the first formula in a group + lastFormulaAggregate.setSharedFormulaRecord((SharedFormulaRecord)rec); + } else if (rec.isValue()) { insertCell(( CellValueRecordInterface ) rec); 1.7 +7 -0 jakarta-poi/src/java/org/apache/poi/hssf/record/formula/ExpPtg.java Index: ExpPtg.java =================================================================== RCS file: /home/cvs/jakarta-poi/src/java/org/apache/poi/hssf/record/formula/ExpPtg.java,v retrieving revision 1.6 retrieving revision 1.7 diff -u -r1.6 -r1.7 --- ExpPtg.java 30 Apr 2003 04:39:02 -0000 1.6 +++ ExpPtg.java 8 May 2003 00:02:03 -0000 1.7 @@ -66,6 +66,7 @@ * * @author andy * @author Jason Height (jheight at chariot dot net dot au) + * @author dmui (save existing implementation) */ public class ExpPtg @@ -73,6 +74,7 @@ { private final static int SIZE = 5; public final static short sid = 0x1; + private byte[] existing = null; /** Creates new ExpPtg */ @@ -84,10 +86,15 @@ public ExpPtg(byte [] array, int offset) { + existing = new byte[this.getSize()]; + System.arraycopy(array, offset, existing, 0, this.getSize()); } public void writeBytes(byte [] array, int offset) { + if (existing != null) { + System.arraycopy(existing, 0, array, offset, existing.length); + } } public int getSize() 1.5 +24 -0 jakarta-poi/src/testcases/org/apache/poi/hssf/record/TestFormulaRecord.java Index: TestFormulaRecord.java =================================================================== RCS file: /home/cvs/jakarta-poi/src/testcases/org/apache/poi/hssf/record/TestFormulaRecord.java,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- TestFormulaRecord.java 30 Apr 2003 04:39:04 -0000 1.4 +++ TestFormulaRecord.java 8 May 2003 00:02:03 -0000 1.5 @@ -121,6 +121,30 @@ } + /** + * Tests to see if the shared formula cells properly reserialize the expPtg + * + */ + public void testExpFormula() { + byte[] formulaByte = new byte[27]; + + for (int i = 0; i < formulaByte.length; i++) formulaByte[i] = (byte)0; + + formulaByte[4] =(byte)0x0F; + formulaByte[14]=(byte)0x08; + formulaByte[18]=(byte)0xE0; + formulaByte[19]=(byte)0xFD; + formulaByte[20]=(byte)0x05; + formulaByte[22]=(byte)0x01; + FormulaRecord record = new FormulaRecord(FormulaRecord.sid, (short)27, formulaByte); + assertEquals("Row", 0, record.getRow()); + assertEquals("Column", 0, record.getColumn()); + byte[] output = record.serialize(); + assertEquals("Output size", 31, output.length); //includes sid+recordlength + assertEquals("Offset 22", 1, output[26]); + } + + public static void main(String [] ignored_args) { String filename = System.getProperty("HSSF.testdata.path"); 1.1 jakarta-poi/src/testcases/org/apache/poi/hssf/record/aggregates/TestValueRecordsAggregate.java Index: TestValueRecordsAggregate.java =================================================================== /* ==================================================================== * The Apache Software License, Version 1.1 * * Copyright (c) 2003 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "Apache" and "Apache Software Foundation" and * "Apache POI" must not be used to endorse or promote products * derived from this software without prior written permission. For * written permission, please contact apache@apache.org. * * 5. Products derived from this software may not be called "Apache", * "Apache POI", nor may "Apache" appear in their name, without * prior written permission of the Apache Software Foundation. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . */ package org.apache.poi.hssf.record.aggregates; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.apache.poi.hssf.record.FormulaRecord; import org.apache.poi.hssf.record.Record; import org.apache.poi.hssf.record.SharedFormulaRecord; public class TestValueRecordsAggregate extends junit.framework.TestCase { public TestValueRecordsAggregate(String name) { super (name); } /** * Make sure the shared formula makes it to the FormulaRecordAggregate when being parsed * as part of the value records * */ public void testSharedFormula() { List records = new ArrayList(); records.add(new FormulaRecord()); records.add(new SharedFormulaRecord()); ValueRecordsAggregate valueRecord = new ValueRecordsAggregate(); valueRecord.construct(0, records); Iterator iterator = valueRecord.getIterator(); Record record = (Record)iterator.next(); assertNotNull("Row contains a value", record); assertTrue("First record is a FormulaRecordsAggregate", (record instanceof FormulaRecordAggregate)); FormulaRecordAggregate aggregate = (FormulaRecordAggregate)record; assertNotNull("SharedFormulaRecord is null", aggregate.getSharedFormulaRecord()); } public static void main(String [] args) { System.out .println("Testing org.apache.poi.hssf.record.aggregates.TestValueRecordAggregate"); junit.textui.TestRunner.run(TestValueRecordsAggregate.class); } }