Return-Path: Delivered-To: apmail-jakarta-poi-dev-archive@www.apache.org Received: (qmail 19670 invoked from network); 21 Jan 2006 05:42:06 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (209.237.227.199) by minotaur.apache.org with SMTP; 21 Jan 2006 05:42:06 -0000 Received: (qmail 48615 invoked by uid 500); 21 Jan 2006 05:42:05 -0000 Delivered-To: apmail-jakarta-poi-dev-archive@jakarta.apache.org Received: (qmail 48597 invoked by uid 500); 21 Jan 2006 05:42:05 -0000 Mailing-List: contact poi-dev-help@jakarta.apache.org; run by ezmlm Precedence: bulk List-Unsubscribe: List-Help: List-Post: List-Id: "POI Developers List" Reply-To: "POI Developers List" Delivered-To: mailing list poi-dev@jakarta.apache.org Received: (qmail 48585 invoked by uid 500); 21 Jan 2006 05:42:04 -0000 Received: (qmail 48580 invoked by uid 99); 21 Jan 2006 05:42:04 -0000 Received: from asf.osuosl.org (HELO asf.osuosl.org) (140.211.166.49) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 20 Jan 2006 21:42:04 -0800 X-ASF-Spam-Status: No, hits=-9.4 required=10.0 tests=ALL_TRUSTED,NO_REAL_NAME X-Spam-Check-By: apache.org Received: from [209.237.227.194] (HELO minotaur.apache.org) (209.237.227.194) by apache.org (qpsmtpd/0.29) with SMTP; Fri, 20 Jan 2006 21:42:03 -0800 Received: (qmail 19637 invoked by uid 65534); 21 Jan 2006 05:41:43 -0000 Message-ID: <20060121054143.19636.qmail@minotaur.apache.org> Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r370987 - in /jakarta/poi/trunk/src: java/org/apache/poi/hssf/record/ java/org/apache/poi/hssf/record/formula/ testcases/org/apache/poi/hssf/data/ testcases/org/apache/poi/hssf/usermodel/ Date: Sat, 21 Jan 2006 05:41:41 -0000 To: poi-cvs@jakarta.apache.org From: jheight@apache.org X-Mailer: svnmailer-1.0.5 X-Virus-Checked: Checked by ClamAV on apache.org X-Spam-Rating: minotaur.apache.org 1.6.2 0/1000/N Author: jheight Date: Fri Jan 20 21:40:07 2006 New Revision: 370987 URL: http://svn.apache.org/viewcvs?rev=370987&view=rev Log: Bug37630: SQUASHED! Array Ptgs now implemented (at least the read and write functionality. No means to modify (yet!)) Added: jakarta/poi/trunk/src/java/org/apache/poi/hssf/record/formula/ArrayPtg.java jakarta/poi/trunk/src/java/org/apache/poi/hssf/record/formula/ArrayPtgA.java jakarta/poi/trunk/src/java/org/apache/poi/hssf/record/formula/ArrayPtgV.java jakarta/poi/trunk/src/testcases/org/apache/poi/hssf/data/37630.xls (with props) Modified: jakarta/poi/trunk/src/java/org/apache/poi/hssf/record/FormulaRecord.java jakarta/poi/trunk/src/java/org/apache/poi/hssf/record/LinkedDataFormulaField.java jakarta/poi/trunk/src/java/org/apache/poi/hssf/record/NameRecord.java jakarta/poi/trunk/src/java/org/apache/poi/hssf/record/formula/Ptg.java jakarta/poi/trunk/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java Modified: jakarta/poi/trunk/src/java/org/apache/poi/hssf/record/FormulaRecord.java URL: http://svn.apache.org/viewcvs/jakarta/poi/trunk/src/java/org/apache/poi/hssf/record/FormulaRecord.java?rev=370987&r1=370986&r2=370987&view=diff ============================================================================== --- jakarta/poi/trunk/src/java/org/apache/poi/hssf/record/FormulaRecord.java (original) +++ jakarta/poi/trunk/src/java/org/apache/poi/hssf/record/FormulaRecord.java Fri Jan 20 21:40:07 2006 @@ -100,26 +100,12 @@ field_6_zero = in.readInt(); field_7_expression_len = in.readShort(); - field_8_parsed_expr = getParsedExpressionTokens(in, field_7_expression_len); + field_8_parsed_expr = Ptg.createParsedExpressionTokens(field_7_expression_len, in); } catch (java.lang.UnsupportedOperationException uoe) { throw new RecordFormatException(uoe.toString()); } } - private Stack getParsedExpressionTokens(RecordInputStream in, short size) - { - Stack stack = new Stack(); - int pos = 0; - - while (pos < size) - { - Ptg ptg = Ptg.createPtg(in); - pos += ptg.getSize(); - stack.push(ptg); - } - return stack; - } - //public void setRow(short row) public void setRow(int row) { @@ -330,7 +316,7 @@ //Microsoft Excel Developer's Kit Page 318 LittleEndian.putInt(data, 20 + offset, 0); LittleEndian.putShort(data, 24 + offset, getExpressionLength()); - serializePtgs(data, 26+offset); + Ptg.serializePtgStack(field_8_parsed_expr, data, 26+offset); } else { System.arraycopy(all_data,0,data,offset,all_data.length); } @@ -366,19 +352,6 @@ retval += ptg.getSize(); } return retval; - } - - private void serializePtgs(byte [] data, int offset) - { - int pos = offset; - - for (int k = 0; k < field_8_parsed_expr.size(); k++) - { - Ptg ptg = ( Ptg ) field_8_parsed_expr.get(k); - - ptg.writeBytes(data, pos); - pos += ptg.getSize(); - } } public boolean isBefore(CellValueRecordInterface i) Modified: jakarta/poi/trunk/src/java/org/apache/poi/hssf/record/LinkedDataFormulaField.java URL: http://svn.apache.org/viewcvs/jakarta/poi/trunk/src/java/org/apache/poi/hssf/record/LinkedDataFormulaField.java?rev=370987&r1=370986&r2=370987&view=diff ============================================================================== --- jakarta/poi/trunk/src/java/org/apache/poi/hssf/record/LinkedDataFormulaField.java (original) +++ jakarta/poi/trunk/src/java/org/apache/poi/hssf/record/LinkedDataFormulaField.java Fri Jan 20 21:40:07 2006 @@ -49,7 +49,7 @@ public int fillField( RecordInputStream in ) { short tokenSize = in.readShort(); - formulaTokens = getParsedExpressionTokens(tokenSize, in); + formulaTokens = Ptg.createParsedExpressionTokens(tokenSize, in); return tokenSize + 2; } @@ -80,12 +80,7 @@ int size = getSize(); LittleEndian.putShort(data, offset, (short)(size - 2)); int pos = offset + 2; - for ( Iterator iterator = formulaTokens.iterator(); iterator.hasNext(); ) - { - Ptg ptg = (Ptg) iterator.next(); - ptg.writeBytes(data, pos); - pos += ptg.getSize(); - } + pos += Ptg.serializePtgStack(formulaTokens, data, pos); return size; } @@ -101,19 +96,6 @@ // should not happen return null; } - } - - private Stack getParsedExpressionTokens(short size, RecordInputStream in ) - { - Stack stack = new Stack(); - int pos = 0; - while ( pos < size ) - { - Ptg ptg = Ptg.createPtg( in ); - pos += ptg.getSize(); - stack.push( ptg ); - } - return stack; } public void setFormulaTokens( Stack formulaTokens ) Modified: jakarta/poi/trunk/src/java/org/apache/poi/hssf/record/NameRecord.java URL: http://svn.apache.org/viewcvs/jakarta/poi/trunk/src/java/org/apache/poi/hssf/record/NameRecord.java?rev=370987&r1=370986&r2=370987&view=diff ============================================================================== --- jakarta/poi/trunk/src/java/org/apache/poi/hssf/record/NameRecord.java (original) +++ jakarta/poi/trunk/src/java/org/apache/poi/hssf/record/NameRecord.java Fri Jan 20 21:40:07 2006 @@ -331,7 +331,7 @@ /** get the definition length * @return definition length */ - public short getDefinitionTextLength(){ + public short getDefinitionLength(){ return field_4_length_name_definition; } @@ -488,7 +488,7 @@ throw new RecordFormatException("NOT A valid Name RECORD"); } } - + /** * called by the class that is responsible for writing this sucker. * Subclasses should implement this so that their data is passed back in a @@ -501,11 +501,13 @@ public int serialize( int offset, byte[] data ) { LittleEndian.putShort( data, 0 + offset, sid ); + short size = (short)( 15 + getTextsLength() + getNameDefinitionSize()); + LittleEndian.putShort( data, 2 + offset, size ); // size defined below LittleEndian.putShort( data, 4 + offset, getOptionFlag() ); data[6 + offset] = getKeyboardShortcut(); data[7 + offset] = getNameTextLength(); - LittleEndian.putShort( data, 8 + offset, getDefinitionTextLength() ); + LittleEndian.putShort( data, 8 + offset, getDefinitionLength() ); LittleEndian.putShort( data, 10 + offset, getUnused() ); LittleEndian.putShort( data, 12 + offset, getEqualsToIndexToSheet() ); data[14 + offset] = getCustomMenuLength(); @@ -525,8 +527,7 @@ return 20 + field_13_raw_name_definition.length; } else - { */ - LittleEndian.putShort( data, 2 + offset, (short) ( 15 + getTextsLength() ) ); + { */ int start_of_name_definition = 19 + field_3_length_name_text; @@ -539,7 +540,7 @@ } - serializePtgs( data, start_of_name_definition + offset ); + Ptg.serializePtgStack(field_13_name_definition, data, start_of_name_definition + offset ); int start_of_custom_menu_text = start_of_name_definition + field_4_length_name_definition; @@ -558,37 +559,39 @@ /* } */ } - private void serializePtgs(byte [] data, int offset) { - int pos = offset; - - for (int k = 0; k < field_13_name_definition.size(); k++) { - Ptg ptg = ( Ptg ) field_13_name_definition.get(k); - - ptg.writeBytes(data, pos); - pos += ptg.getSize(); - } - } - - /** gets the length of all texts * @return total length */ public int getTextsLength(){ int result; - result = getNameTextLength() + getDefinitionTextLength() + getDescriptionTextLength() + + result = getNameTextLength() + getDescriptionTextLength() + getHelpTopicLength() + getStatusBarLength(); return result; } + + private int getNameDefinitionSize() { + int result = 0; + List list = field_13_name_definition; + + for (int k = 0; k < list.size(); k++) + { + Ptg ptg = ( Ptg ) list.get(k); + + result += ptg.getSize(); + } + return result; + } /** returns the record size */ public int getRecordSize(){ int result; - result = 19 + getTextsLength(); + result = 19 + getTextsLength() + getNameDefinitionSize(); + return result; } @@ -733,7 +736,7 @@ } } - field_13_name_definition = getParsedExpressionTokens(in, field_4_length_name_definition); + field_13_name_definition = Ptg.createParsedExpressionTokens(field_4_length_name_definition, in); //Who says that this can only ever be compressed unicode??? field_14_custom_menu_text = in.readCompressedUnicode(LittleEndian.ubyteToInt(field_7_length_custom_menu)); @@ -745,23 +748,6 @@ field_17_status_bar_text = in.readCompressedUnicode(LittleEndian.ubyteToInt(field_10_length_status_bar_text)); /*} */ } - - private Stack getParsedExpressionTokens(RecordInputStream in, short size) { - Stack stack = new Stack(); - int sizeCounter = 0; - try { - while (sizeCounter < size) { - Ptg ptg = Ptg.createPtg(in); - - sizeCounter += ptg.getSize(); - stack.push(ptg); - } - } catch (java.lang.UnsupportedOperationException uoe) { - throw new RecordFormatException(uoe.toString()); - } - return stack; - } - /** * return the non static version of the id for this record. Added: jakarta/poi/trunk/src/java/org/apache/poi/hssf/record/formula/ArrayPtg.java URL: http://svn.apache.org/viewcvs/jakarta/poi/trunk/src/java/org/apache/poi/hssf/record/formula/ArrayPtg.java?rev=370987&view=auto ============================================================================== --- jakarta/poi/trunk/src/java/org/apache/poi/hssf/record/formula/ArrayPtg.java (added) +++ jakarta/poi/trunk/src/java/org/apache/poi/hssf/record/formula/ArrayPtg.java Fri Jan 20 21:40:07 2006 @@ -0,0 +1,246 @@ +/* ==================================================================== + Copyright 2003-2004 Apache Software Foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +package org.apache.poi.hssf.record.formula; + +import org.apache.poi.util.LittleEndian; +import org.apache.poi.util.BitField; +import org.apache.poi.util.BitFieldFactory; +import org.apache.poi.util.StringUtil; + +import org.apache.poi.hssf.util.CellReference; +import org.apache.poi.hssf.model.Workbook; +import org.apache.poi.hssf.record.RecordFormatException; +import org.apache.poi.hssf.record.RecordInputStream; +import org.apache.poi.hssf.record.SSTRecord; +import org.apache.poi.hssf.record.UnicodeString; + +/** + * ArrayPtg - handles arrays + * + * The ArrayPtg is a little wierd, the size of the Ptg when parsing initially only + * includes the Ptg sid and the reserved bytes. The next Ptg in the expression then follows. + * It is only after the "size" of all the Ptgs is met, that the ArrayPtg data is actually + * held after this. So Ptg.createParsedExpression keeps track of the number of + * ArrayPtg elements and need to parse the data upto the FORMULA record size. + * + * @author Jason Height (jheight at chariot dot net dot au) + */ + +public class ArrayPtg extends Ptg +{ + public final static byte sid = 0x20; + protected byte field_1_reserved; + protected byte field_2_reserved; + protected byte field_3_reserved; + protected byte field_4_reserved; + protected byte field_5_reserved; + protected byte field_6_reserved; + protected byte field_7_reserved; + + + protected short token_1_columns; + protected short token_2_rows; + protected Object[][] token_3_arrayValues; + + protected ArrayPtg() { + //Required for clone methods + } + + public ArrayPtg(RecordInputStream in) + { + field_1_reserved = in.readByte(); + field_2_reserved = in.readByte(); + field_3_reserved = in.readByte(); + field_4_reserved = in.readByte(); + field_5_reserved = in.readByte(); + field_6_reserved = in.readByte(); + field_7_reserved = in.readByte(); + } + + /** Read in the actual token (array) values. This occurs AFTER the last + * Ptg in the expression. + */ + public void readTokenValues(RecordInputStream in) { + token_1_columns = (short)(0x00ff & in.readByte()); + token_2_rows = in.readShort(); + + //The token_1_columns and token_2_rows do not follow the documentation. + //The number of physical rows and columns is actually +1 of these values. + //Which is not explicitly documented. + token_1_columns++; + token_2_rows++; + + token_3_arrayValues = new Object[token_1_columns][token_2_rows]; + + for (int x=0;x