aboutsummaryrefslogtreecommitdiffstats
path: root/src/java
diff options
context:
space:
mode:
authorJason Height <jheight@apache.org>2006-01-21 05:40:07 +0000
committerJason Height <jheight@apache.org>2006-01-21 05:40:07 +0000
commit33484b31f980955de0b791ac448c77fe36a6c0a8 (patch)
treea40bdbaa80f72034d87321b8efb2916cc6847ba2 /src/java
parent26c0e71d744515fc38aabd6a2bb768b8655c2cd7 (diff)
downloadpoi-33484b31f980955de0b791ac448c77fe36a6c0a8.tar.gz
poi-33484b31f980955de0b791ac448c77fe36a6c0a8.zip
Bug37630: SQUASHED! Array Ptgs now implemented (at least the read and write functionality. No means to modify (yet!))
git-svn-id: https://svn.apache.org/repos/asf/jakarta/poi/trunk@370987 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src/java')
-rw-r--r--src/java/org/apache/poi/hssf/record/FormulaRecord.java31
-rw-r--r--src/java/org/apache/poi/hssf/record/LinkedDataFormulaField.java22
-rw-r--r--src/java/org/apache/poi/hssf/record/NameRecord.java62
-rw-r--r--src/java/org/apache/poi/hssf/record/formula/ArrayPtg.java246
-rw-r--r--src/java/org/apache/poi/hssf/record/formula/ArrayPtgA.java72
-rw-r--r--src/java/org/apache/poi/hssf/record/formula/ArrayPtgV.java77
-rw-r--r--src/java/org/apache/poi/hssf/record/formula/Ptg.java66
7 files changed, 488 insertions, 88 deletions
diff --git a/src/java/org/apache/poi/hssf/record/FormulaRecord.java b/src/java/org/apache/poi/hssf/record/FormulaRecord.java
index 11c7165562..a3b189d47f 100644
--- a/src/java/org/apache/poi/hssf/record/FormulaRecord.java
+++ b/src/java/org/apache/poi/hssf/record/FormulaRecord.java
@@ -100,26 +100,12 @@ public class FormulaRecord
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 @@ public class FormulaRecord
//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);
}
@@ -368,19 +354,6 @@ public class FormulaRecord
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)
{
if (this.getRow() > i.getRow())
diff --git a/src/java/org/apache/poi/hssf/record/LinkedDataFormulaField.java b/src/java/org/apache/poi/hssf/record/LinkedDataFormulaField.java
index c16f254586..45921f86ce 100644
--- a/src/java/org/apache/poi/hssf/record/LinkedDataFormulaField.java
+++ b/src/java/org/apache/poi/hssf/record/LinkedDataFormulaField.java
@@ -49,7 +49,7 @@ public class LinkedDataFormulaField
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 @@ public class LinkedDataFormulaField
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;
}
@@ -103,19 +98,6 @@ public class LinkedDataFormulaField
}
}
- 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 )
{
this.formulaTokens = (Stack) formulaTokens.clone();
diff --git a/src/java/org/apache/poi/hssf/record/NameRecord.java b/src/java/org/apache/poi/hssf/record/NameRecord.java
index 576385cfb8..9217a71b67 100644
--- a/src/java/org/apache/poi/hssf/record/NameRecord.java
+++ b/src/java/org/apache/poi/hssf/record/NameRecord.java
@@ -331,7 +331,7 @@ public class NameRecord extends Record {
/** get the definition length
* @return definition length
*/
- public short getDefinitionTextLength(){
+ public short getDefinitionLength(){
return field_4_length_name_definition;
}
@@ -488,7 +488,7 @@ public class NameRecord extends Record {
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 class NameRecord extends Record {
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 @@ public class NameRecord extends Record {
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 @@ public class NameRecord extends Record {
}
- 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 @@ public class NameRecord extends Record {
/* } */
}
- 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 @@ public class NameRecord extends Record {
}
}
- 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));
@@ -746,23 +749,6 @@ public class NameRecord extends Record {
/*} */
}
- 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.
*/
diff --git a/src/java/org/apache/poi/hssf/record/formula/ArrayPtg.java b/src/java/org/apache/poi/hssf/record/formula/ArrayPtg.java
new file mode 100644
index 0000000000..568b3a3cb4
--- /dev/null
+++ b/src/java/org/apache/poi/hssf/record/formula/ArrayPtg.java
@@ -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<token_1_columns;x++) {
+ for (int y=0;y<token_2_rows;y++) {
+ byte grbit = in.readByte();
+ if (grbit == 0x01) {
+ token_3_arrayValues[x][y] = Double.valueOf(in.readDouble());
+ } else if (grbit == 0x02) {
+ //Ignore the doco, it is actually a unicode string with all the
+ //trimmings ie 16 bit size, option byte etc
+ token_3_arrayValues[x][y] = in.readUnicodeString();
+ } else throw new RecordFormatException("Unknown grbit '"+grbit+"'");
+ }
+ }
+
+ }
+
+ public String toString()
+ {
+ StringBuffer buffer = new StringBuffer("[ArrayPtg]\n");
+
+ buffer.append("columns = ").append(getColumnCount()).append("\n");
+ buffer.append("rows = ").append(getRowCount()).append("\n");
+ for (int x=0;x<getColumnCount();x++) {
+ for (int y=0;y<getRowCount();y++) {
+ Object o = token_3_arrayValues[x][y];
+ buffer.append("[").append(x).append("][").append(y).append("] = ").append(o).append("\n");
+ }
+ }
+ return buffer.toString();
+ }
+
+ public void writeBytes(byte [] array, int offset)
+ {
+ array[offset++] = (byte) (sid + ptgClass);
+ array[offset++] = field_1_reserved;
+ array[offset++] = field_2_reserved;
+ array[offset++] = field_3_reserved;
+ array[offset++] = field_4_reserved;
+ array[offset++] = field_5_reserved;
+ array[offset++] = field_6_reserved;
+ array[offset++] = field_7_reserved;
+
+ }
+ public int writeTokenValueBytes(byte [] array, int offset) {
+ int pos = 0;
+ array[pos + offset] = (byte)(token_1_columns-1);
+ pos++;
+ LittleEndian.putShort(array, pos+offset, (short)(token_2_rows-1));
+ pos += 2;
+ for (int x=0;x<getColumnCount();x++) {
+ for (int y=0;y<getRowCount();y++) {
+ Object o = token_3_arrayValues[x][y];
+ if (o instanceof Double) {
+ array[pos+offset] = 0x01;
+ pos++;
+ LittleEndian.putDouble(array, pos+offset, ((Double)o).doubleValue());
+ pos+=8;
+ } else if (o instanceof UnicodeString) {
+ array[pos+offset] = 0x02;
+ pos++;
+ UnicodeString s = (UnicodeString)o;
+ //JMH TBD Handle string continuation. Id do it now but its 4am.
+ UnicodeString.UnicodeRecordStats stats = new UnicodeString.UnicodeRecordStats();
+ s.serialize(stats, pos + offset, array);
+ pos += stats.recordSize;
+ } else throw new RuntimeException("Coding error");
+ }
+ }
+ return pos;
+ }
+
+ public void setRowCount(short row)
+ {
+ token_2_rows = row;
+ }
+
+ public short getRowCount()
+ {
+ return token_2_rows;
+ }
+
+ public void setColumnCount(short col)
+ {
+ token_1_columns = (byte)col;
+ }
+
+ public short getColumnCount()
+ {
+ return token_1_columns;
+ }
+
+ /** This size includes the size of the array Ptg plus the Array Ptg Token value size*/
+ public int getSize()
+ {
+ int size = 1+7+1+2;
+ for (int x=0;x<getColumnCount();x++) {
+ for (int y=0;y<getRowCount();y++) {
+ Object o = token_3_arrayValues[x][y];
+ if (o instanceof UnicodeString) {
+ size++;
+ UnicodeString.UnicodeRecordStats rs = new UnicodeString.UnicodeRecordStats();
+ ((UnicodeString)o).getRecordSize(rs);
+ size += rs.recordSize;
+ } else if (o instanceof Double) {
+ size += 9;
+ }
+ }
+ }
+ return size;
+ }
+
+ public String toFormulaString(Workbook book)
+ {
+ StringBuffer b = new StringBuffer();
+ b.append("{");
+ for (int x=0;x<getColumnCount();x++) {
+ for (int y=0;y<getRowCount();y++) {
+ Object o = token_3_arrayValues[x][y];
+ if (o instanceof String) {
+ b.append((String)o);
+ } else if (o instanceof Double) {
+ b.append(((Double)o).doubleValue());
+ }
+ if (y != getRowCount())
+ b.append(",");
+ }
+ if (x != getColumnCount())
+ b.append(";");
+ }
+ b.append("}");
+ return b.toString();
+ }
+
+ public byte getDefaultOperandClass() {
+ return Ptg.CLASS_ARRAY;
+ }
+
+ public Object clone() {
+ ArrayPtg ptg = new ArrayPtg();
+ ptg.field_1_reserved = field_1_reserved;
+ ptg.field_2_reserved = field_2_reserved;
+ ptg.field_3_reserved = field_3_reserved;
+ ptg.field_4_reserved = field_4_reserved;
+ ptg.field_5_reserved = field_5_reserved;
+ ptg.field_6_reserved = field_6_reserved;
+ ptg.field_7_reserved = field_7_reserved;
+
+ ptg.token_1_columns = token_1_columns;
+ ptg.token_2_rows = token_2_rows;
+ ptg.token_3_arrayValues = new Object[getColumnCount()][getRowCount()];
+ for (int x=0;x<getColumnCount();x++) {
+ for (int y=0;y<getRowCount();y++) {
+ ptg.token_3_arrayValues[x][y] = token_3_arrayValues[x][y];
+ }
+ }
+ ptg.setClass(ptgClass);
+ return ptg;
+ }
+}
diff --git a/src/java/org/apache/poi/hssf/record/formula/ArrayPtgA.java b/src/java/org/apache/poi/hssf/record/formula/ArrayPtgA.java
new file mode 100644
index 0000000000..2fdd210c0b
--- /dev/null
+++ b/src/java/org/apache/poi/hssf/record/formula/ArrayPtgA.java
@@ -0,0 +1,72 @@
+/* ====================================================================
+ 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;
+
+/**
+ * ArrayPtgA - handles arrays
+ *
+ * @author Jason Height (jheight at chariot dot net dot au)
+ */
+
+public class ArrayPtgA extends ArrayPtg
+{
+ public final static byte sid = 0x60;
+
+ protected ArrayPtgA() {
+ super();
+ //Required for clone methods
+ }
+
+ public ArrayPtgA(RecordInputStream in)
+ {
+ super(in);
+ }
+
+ public Object clone() {
+ ArrayPtgA ptg = new ArrayPtgA();
+ ptg.field_1_reserved = field_1_reserved;
+ ptg.field_2_reserved = field_2_reserved;
+ ptg.field_3_reserved = field_3_reserved;
+ ptg.field_4_reserved = field_4_reserved;
+ ptg.field_5_reserved = field_5_reserved;
+ ptg.field_6_reserved = field_6_reserved;
+ ptg.field_7_reserved = field_7_reserved;
+
+ ptg.token_1_columns = token_1_columns;
+ ptg.token_2_rows = token_2_rows;
+ ptg.token_3_arrayValues = new Object[getColumnCount()][getRowCount()];
+ for (int x=0;x<getColumnCount();x++) {
+ for (int y=0;y<getRowCount();y++) {
+ ptg.token_3_arrayValues[x][y] = token_3_arrayValues[x][y];
+ }
+ }
+ ptg.setClass(ptgClass);
+ return ptg;
+ }
+}
diff --git a/src/java/org/apache/poi/hssf/record/formula/ArrayPtgV.java b/src/java/org/apache/poi/hssf/record/formula/ArrayPtgV.java
new file mode 100644
index 0000000000..68cf317676
--- /dev/null
+++ b/src/java/org/apache/poi/hssf/record/formula/ArrayPtgV.java
@@ -0,0 +1,77 @@
+/* ====================================================================
+ 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 ArrayPtgV extends ArrayPtg
+{
+ public final static byte sid = 0x40;
+
+ protected ArrayPtgV() {
+ //Required for clone methods
+ }
+
+ public ArrayPtgV(RecordInputStream in)
+ {
+ super(in);
+ }
+
+ public Object clone() {
+ ArrayPtgV ptg = new ArrayPtgV();
+ ptg.field_1_reserved = field_1_reserved;
+ ptg.field_2_reserved = field_2_reserved;
+ ptg.field_3_reserved = field_3_reserved;
+ ptg.field_4_reserved = field_4_reserved;
+ ptg.field_5_reserved = field_5_reserved;
+ ptg.field_6_reserved = field_6_reserved;
+ ptg.field_7_reserved = field_7_reserved;
+
+ ptg.token_1_columns = token_1_columns;
+ ptg.token_2_rows = token_2_rows;
+ ptg.token_3_arrayValues = new Object[getColumnCount()][getRowCount()];
+ for (int x=0;x<getColumnCount();x++) {
+ for (int y=0;y<getRowCount();y++) {
+ ptg.token_3_arrayValues[x][y] = token_3_arrayValues[x][y];
+ }
+ }
+ ptg.setClass(ptgClass);
+ return ptg;
+ }
+}
diff --git a/src/java/org/apache/poi/hssf/record/formula/Ptg.java b/src/java/org/apache/poi/hssf/record/formula/Ptg.java
index 92a7a62819..4e7df5b869 100644
--- a/src/java/org/apache/poi/hssf/record/formula/Ptg.java
+++ b/src/java/org/apache/poi/hssf/record/formula/Ptg.java
@@ -18,6 +18,7 @@ package org.apache.poi.hssf.record.formula;
import java.util.List;
import java.util.ArrayList;
+import java.util.Stack;
import org.apache.poi.hssf.model.Workbook;
import org.apache.poi.hssf.record.RecordInputStream;
@@ -85,8 +86,33 @@ public abstract class Ptg
return retval;
}
*/
+
+ public static Stack createParsedExpressionTokens(short size, RecordInputStream in )
+ {
+ Stack stack = new Stack();
+ int pos = 0;
+ List arrayPtgs = null;
+ while ( pos < size )
+ {
+ Ptg ptg = Ptg.createPtg( in );
+ if (ptg instanceof ArrayPtg) {
+ if (arrayPtgs == null)
+ arrayPtgs = new ArrayList(5);
+ arrayPtgs.add(ptg);
+ pos += 8;
+ } else pos += ptg.getSize();
+ stack.push( ptg );
+ }
+ if (arrayPtgs != null) {
+ for (int i=0;i<arrayPtgs.size();i++) {
+ ArrayPtg p = (ArrayPtg)arrayPtgs.get(i);
+ p.readTokenValues(in);
+ }
+ }
+ return stack;
+ }
- public static Ptg createPtg(RecordInputStream in)
+ private static Ptg createPtg(RecordInputStream in)
{
byte id = in.readByte();
Ptg retval = null;
@@ -157,6 +183,16 @@ public abstract class Ptg
case ConcatPtg.sid :
retval = new ConcatPtg(in);
break;
+
+ case ArrayPtg.sid:
+ retval = new ArrayPtg(in);
+ break;
+ case ArrayPtgV.sid:
+ retval = new ArrayPtgV(in);
+ break;
+ case ArrayPtgA.sid:
+ retval = new ArrayPtgA(in);
+ break;
case AreaPtg.sid :
retval = new AreaPtg(in);
@@ -304,6 +340,34 @@ public abstract class Ptg
return retval;
}
+
+ public static int serializePtgStack(Stack expression, byte[] array, int offset) {
+ int pos = 0;
+ int size = 0;
+ if (expression != null)
+ size = expression.size();
+
+ List arrayPtgs = null;
+
+ for (int k = 0; k < size; k++) {
+ Ptg ptg = ( Ptg ) expression.get(k);
+
+ ptg.writeBytes(array, pos + offset);
+ if (ptg instanceof ArrayPtg) {
+ if (arrayPtgs == null)
+ arrayPtgs = new ArrayList(5);
+ arrayPtgs.add(ptg);
+ pos += 8;
+ } else pos += ptg.getSize();
+ }
+ if (arrayPtgs != null) {
+ for (int i=0;i<arrayPtgs.size();i++) {
+ ArrayPtg p = (ArrayPtg)arrayPtgs.get(i);
+ pos += p.writeTokenValueBytes(array, pos + offset);
+ }
+ }
+ return pos;
+ }
public abstract int getSize();