You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by jo...@apache.org on 2008/05/06 04:02:43 UTC

svn commit: r653668 - in /poi/trunk/src: documentation/content/xdocs/ java/org/apache/poi/hssf/record/constant/ java/org/apache/poi/hssf/record/formula/ testcases/org/apache/poi/hssf/record/formula/ testcases/org/apache/poi/hssf/usermodel/

Author: josh
Date: Mon May  5 19:02:41 2008
New Revision: 653668

URL: http://svn.apache.org/viewvc?rev=653668&view=rev
Log:
42564 - fixed ArrayPtg to use ConstantValueParser.  Fixed a few other ArrayPtg encoding issues.

Added:
    poi/trunk/src/testcases/org/apache/poi/hssf/record/formula/TestArrayPtg.java
Modified:
    poi/trunk/src/documentation/content/xdocs/changes.xml
    poi/trunk/src/documentation/content/xdocs/status.xml
    poi/trunk/src/java/org/apache/poi/hssf/record/constant/ConstantValueParser.java
    poi/trunk/src/java/org/apache/poi/hssf/record/constant/ErrorConstant.java
    poi/trunk/src/java/org/apache/poi/hssf/record/formula/ArrayPtg.java
    poi/trunk/src/java/org/apache/poi/hssf/record/formula/ArrayPtgA.java
    poi/trunk/src/java/org/apache/poi/hssf/record/formula/ArrayPtgV.java
    poi/trunk/src/testcases/org/apache/poi/hssf/record/formula/AllFormulaTests.java
    poi/trunk/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java

Modified: poi/trunk/src/documentation/content/xdocs/changes.xml
URL: http://svn.apache.org/viewvc/poi/trunk/src/documentation/content/xdocs/changes.xml?rev=653668&r1=653667&r2=653668&view=diff
==============================================================================
--- poi/trunk/src/documentation/content/xdocs/changes.xml (original)
+++ poi/trunk/src/documentation/content/xdocs/changes.xml Mon May  5 19:02:41 2008
@@ -37,6 +37,7 @@
 
 		<!-- Don't forget to update status.xml too! -->
         <release version="3.1-beta2" date="2008-05-??">
+           <action dev="POI-DEVELOPERS" type="fix">42564 - fixed ArrayPtg to use ConstantValueParser.  Fixed a few other ArrayPtg encoding issues.</action>
            <action dev="POI-DEVELOPERS" type="fix">Follow-on from 28754 - StringPtg.toFormulaString() should escape double quotes</action>
            <action dev="POI-DEVELOPERS" type="fix">44929 - Improved error handling in HSSFWorkbook when attempting to read a BIFF5 file</action>
            <action dev="POI-DEVELOPERS" type="fix">44675 - Parameter operand classes (function metadata) required to encode SUM() etc properly. Added parse validation for number of parameters</action>

Modified: poi/trunk/src/documentation/content/xdocs/status.xml
URL: http://svn.apache.org/viewvc/poi/trunk/src/documentation/content/xdocs/status.xml?rev=653668&r1=653667&r2=653668&view=diff
==============================================================================
--- poi/trunk/src/documentation/content/xdocs/status.xml (original)
+++ poi/trunk/src/documentation/content/xdocs/status.xml Mon May  5 19:02:41 2008
@@ -34,6 +34,7 @@
 	<!-- Don't forget to update changes.xml too! -->
     <changes>
         <release version="3.1-beta2" date="2008-05-??">
+           <action dev="POI-DEVELOPERS" type="fix">42564 - fixed ArrayPtg to use ConstantValueParser.  Fixed a few other ArrayPtg encoding issues.</action>
            <action dev="POI-DEVELOPERS" type="fix">Follow-on from 28754 - StringPtg.toFormulaString() should escape double quotes</action>
            <action dev="POI-DEVELOPERS" type="fix">44929 - Improved error handling in HSSFWorkbook when attempting to read a BIFF5 file</action>
            <action dev="POI-DEVELOPERS" type="fix">44675 - Parameter operand classes (function metadata) required to encode SUM() etc properly. Added parse validation for number of parameters</action>

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/constant/ConstantValueParser.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/constant/ConstantValueParser.java?rev=653668&r1=653667&r2=653668&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/constant/ConstantValueParser.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/constant/ConstantValueParser.java Mon May  5 19:02:41 2008
@@ -24,9 +24,8 @@
 
 /**
  * To support Constant Values (2.5.7) as required by the CRN record.
- * This class should probably also be used for two dimensional arrays which are encoded by 
+ * This class is also used for two dimensional arrays which are encoded by 
  * EXTERNALNAME (5.39) records and Array tokens.<p/>
- * TODO - code in ArrayPtg should be merged with this code.  It currently supports only 2 of the constant types
  * 
  * @author Josh Micich
  */

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/constant/ErrorConstant.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/constant/ErrorConstant.java?rev=653668&r1=653667&r2=653668&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/constant/ErrorConstant.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/constant/ErrorConstant.java Mon May  5 19:02:41 2008
@@ -47,18 +47,31 @@
 	public int getErrorCode() {
 		return _errorCode;
 	}
+	public String getText() {
+		if(HSSFErrorConstants.isValidCode(_errorCode)) {
+			return HSSFErrorConstants.getText(_errorCode);
+		}
+		return "unknown error code (" + _errorCode + ")";
+	}
 
 	public static ErrorConstant valueOf(int errorCode) {
 		switch (errorCode) {
-    		case HSSFErrorConstants.ERROR_NULL:  return NULL;
-    		case HSSFErrorConstants.ERROR_DIV_0: return DIV_0;
-    		case HSSFErrorConstants.ERROR_VALUE: return VALUE;
-    		case HSSFErrorConstants.ERROR_REF:   return REF;
-    		case HSSFErrorConstants.ERROR_NAME:  return NAME;
-    		case HSSFErrorConstants.ERROR_NUM:   return NUM;
-    		case HSSFErrorConstants.ERROR_NA:    return NA;
+			case HSSFErrorConstants.ERROR_NULL:  return NULL;
+			case HSSFErrorConstants.ERROR_DIV_0: return DIV_0;
+			case HSSFErrorConstants.ERROR_VALUE: return VALUE;
+			case HSSFErrorConstants.ERROR_REF:   return REF;
+			case HSSFErrorConstants.ERROR_NAME:  return NAME;
+			case HSSFErrorConstants.ERROR_NUM:   return NUM;
+			case HSSFErrorConstants.ERROR_NA:	return NA;
 		}
 		System.err.println("Warning - unexpected error code (" + errorCode + ")");
 		return new ErrorConstant(errorCode);
 	}
+	public String toString() {
+		StringBuffer sb = new StringBuffer(64);
+		sb.append(getClass().getName()).append(" [");
+		sb.append(getText());
+		sb.append("]");
+		return sb.toString();
+	}
 }

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/formula/ArrayPtg.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/formula/ArrayPtg.java?rev=653668&r1=653667&r2=653668&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/formula/ArrayPtg.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/formula/ArrayPtg.java Mon May  5 19:02:41 2008
@@ -17,22 +17,17 @@
 
 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.usermodel.HSSFWorkbook;
-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;
+import org.apache.poi.hssf.record.constant.ConstantValueParser;
+import org.apache.poi.hssf.record.constant.ErrorConstant;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.apache.poi.util.LittleEndian;
 
 /**
  * ArrayPtg - handles arrays
  * 
- * The ArrayPtg is a little wierd, the size of the Ptg when parsing initially only
+ * The ArrayPtg is a little weird, 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 
@@ -40,209 +35,160 @@
  *  
  * @author Jason Height (jheight at chariot dot net dot au)
  */
+public class ArrayPtg extends Ptg {
+	public static final byte sid  = 0x20;
 
-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.
-     * See page 304-305 of Excel97-2007BinaryFileFormat(xls)Specification.pdf
-     */
-    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] = new Double(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+"' at " + x + "," + y + " with " + in.remaining() + " bytes left");
+	private static final int RESERVED_FIELD_LEN = 7;
+	// TODO - fix up field visibility and subclasses
+	protected 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
+	}
+
+	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();
+		}
+	}
+	
+	/** 
+	 * Read in the actual token (array) values. This occurs 
+	 * AFTER the last Ptg in the expression.
+	 * See page 304-305 of Excel97-2007BinaryFileFormat(xls)Specification.pdf
+	 */
+	public void readTokenValues(RecordInputStream in) {
+		short nColumns = in.readUByte();
+		short nRows = 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.
+		nColumns++;
+		nRows++;
+		
+		token_1_columns = nColumns;
+		token_2_rows = nRows;
+		
+		int totalCount = nRows * nColumns;
+		token_3_arrayValues = ConstantValueParser.parse(in, totalCount);
+	}
+
+	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[getValueIndex(x, y)];
+	   			buffer.append("[").append(x).append("][").append(y).append("] = ").append(o).append("\n"); 
 			}
-        }
-    }
-
-    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(HSSFWorkbook 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;
-    }
+		}
+		return buffer.toString();
+	}
+
+	/* package */ int getValueIndex(int colIx, int rowIx) {
+		if(colIx < 0 || colIx >= token_1_columns) {
+			throw new IllegalArgumentException("Specified colIx (" + colIx 
+					+ ") is outside the allowed range (0.." + (token_1_columns-1) + ")");
+		}
+		if(rowIx < 0 || rowIx >= token_2_rows) {
+			throw new IllegalArgumentException("Specified rowIx (" + rowIx 
+					+ ") is outside the allowed range (0.." + (token_2_rows-1) + ")");
+		}
+		return rowIx * token_1_columns + colIx;
+	}
+
+	public void writeBytes(byte[] data, int offset) {
+		
+		LittleEndian.putByte(data, offset + 0, sid + ptgClass);
+		System.arraycopy(field_1_reserved, 0, data, offset+1, RESERVED_FIELD_LEN);
+	}
+
+	public int writeTokenValueBytes(byte[] data, int offset) {
+
+		LittleEndian.putByte(data,  offset + 0, token_1_columns-1);
+		LittleEndian.putShort(data, offset + 1, (short)(token_2_rows-1));
+		ConstantValueParser.encode(data, offset + 3, token_3_arrayValues);
+		return 3 + ConstantValueParser.getEncodedSize(token_3_arrayValues);
+	}
+
+	public short getRowCount() {
+		return token_2_rows;
+	}
+
+	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;
+		size += ConstantValueParser.getEncodedSize(token_3_arrayValues);
+		return size;
+	}
+
+	public String toFormulaString(HSSFWorkbook book)
+	{
+		StringBuffer b = new StringBuffer();
+		b.append("{");
+		for (int x=0;x<getColumnCount();x++) {
+		  	if (x > 0) {
+				b.append(";");
+			}
+		  	for (int y=0;y<getRowCount();y++) {
+				if (y > 0) {
+					b.append(",");
+				}
+		  		Object o = token_3_arrayValues[getValueIndex(x, y)];
+		  		b.append(getConstantText(o));
+		  	}
+		  }
+		b.append("}");
+		return b.toString();
+	}
+	
+	private static String getConstantText(Object o) {
+
+		if (o == null) {
+			return ""; // TODO - how is 'empty value' represented in formulas?
+		}
+		if (o instanceof UnicodeString) {
+			return "\"" + ((UnicodeString)o).getString() + "\"";
+		}
+		if (o instanceof Double) {
+			return ((Double)o).toString();
+		}
+		if (o instanceof Boolean) {
+			((Boolean)o).toString();
+		}
+		if (o instanceof ErrorConstant) {
+			return ((ErrorConstant)o).getText();
+		}
+		throw new IllegalArgumentException("Unexpected constant class (" + o.getClass().getName() + ")");
+	}
+	
+	public byte getDefaultOperandClass() {
+		return Ptg.CLASS_ARRAY;
+	}
+	
+	public Object clone() {
+	  ArrayPtg ptg = new ArrayPtg();
+	  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/trunk/src/java/org/apache/poi/hssf/record/formula/ArrayPtgA.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/formula/ArrayPtgA.java?rev=653668&r1=653667&r2=653668&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/formula/ArrayPtgA.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/formula/ArrayPtgA.java Mon May  5 19:02:41 2008
@@ -17,56 +17,31 @@
 
 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.usermodel.HSSFWorkbook;
-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 class ArrayPtgA extends ArrayPtg {
     public final static byte sid  = 0x60;
 
-    protected ArrayPtgA() {
-    	super();
+    private ArrayPtgA() {
       //Required for clone methods
     }
 
-    public ArrayPtgA(RecordInputStream in)
-    {
+    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.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 = 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.token_3_arrayValues = (Object[]) token_3_arrayValues.clone();
       ptg.setClass(ptgClass);
       return ptg;
     }

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/formula/ArrayPtgV.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/formula/ArrayPtgV.java?rev=653668&r1=653667&r2=653668&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/formula/ArrayPtgV.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/formula/ArrayPtgV.java Mon May  5 19:02:41 2008
@@ -17,22 +17,12 @@
 
 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.usermodel.HSSFWorkbook;
-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
+ * The ArrayPtg is a little weird, 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 
@@ -40,38 +30,24 @@
  *  
  * @author Jason Height (jheight at chariot dot net dot au)
  */
-
-public class ArrayPtgV extends ArrayPtg
-{
+public final class ArrayPtgV extends ArrayPtg {
     public final static byte sid  = 0x40;
 
-    protected ArrayPtgV() {
+    private ArrayPtgV() {
       //Required for clone methods
     }
 
-    public ArrayPtgV(RecordInputStream in)
-    {
+    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.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 = 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.token_3_arrayValues = (Object[]) token_3_arrayValues.clone();
       ptg.setClass(ptgClass);
       return ptg;
     }

Modified: poi/trunk/src/testcases/org/apache/poi/hssf/record/formula/AllFormulaTests.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/hssf/record/formula/AllFormulaTests.java?rev=653668&r1=653667&r2=653668&view=diff
==============================================================================
--- poi/trunk/src/testcases/org/apache/poi/hssf/record/formula/AllFormulaTests.java (original)
+++ poi/trunk/src/testcases/org/apache/poi/hssf/record/formula/AllFormulaTests.java Mon May  5 19:02:41 2008
@@ -40,6 +40,7 @@
 		result.addTestSuite(TestArea3DPtg.class);
 		result.addTestSuite(TestAreaErrPtg.class);
 		result.addTestSuite(TestAreaPtg.class);
+		result.addTestSuite(TestArrayPtg.class);
 		result.addTestSuite(TestErrPtg.class);
 		result.addTestSuite(TestExternalFunctionFormulas.class);
 		result.addTestSuite(TestFuncPtg.class);

Added: poi/trunk/src/testcases/org/apache/poi/hssf/record/formula/TestArrayPtg.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/hssf/record/formula/TestArrayPtg.java?rev=653668&view=auto
==============================================================================
--- poi/trunk/src/testcases/org/apache/poi/hssf/record/formula/TestArrayPtg.java (added)
+++ poi/trunk/src/testcases/org/apache/poi/hssf/record/formula/TestArrayPtg.java Mon May  5 19:02:41 2008
@@ -0,0 +1,95 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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 java.util.Arrays;
+
+import org.apache.poi.hssf.record.TestcaseRecordInputStream;
+import org.apache.poi.hssf.record.UnicodeString;
+
+import junit.framework.AssertionFailedError;
+import junit.framework.TestCase;
+/**
+ * Tests for <tt>ArrayPtg</tt>
+ * 
+ * @author Josh Micich
+ */
+public final class TestArrayPtg extends TestCase {
+
+	private static final byte[] ENCODED_PTG_DATA = {
+		0x40, 0x00,
+		0x08, 0x00,
+		0, 0, 0, 0, 0, 0, 0, 0, 
+	};
+	private static final byte[] ENCODED_CONSTANT_DATA = {
+		2,    // 3 columns
+		1, 0, // 2 rows
+		4, 1, 0, 0, 0, 0, 0, 0, 0, // TRUE
+		2, 4, 0, 0, 65, 66, 67, 68, // "ABCD"
+		2, 1, 0, 0, 69, // "E"
+		1, 0, 0, 0, 0, 0, 0, 0, 0, // 0
+		4, 0, 0, 0, 0, 0, 0, 0, 0, // FALSE
+		2, 2, 0, 0, 70, 71, // "FG"
+	};
+
+	/**
+	 * Lots of problems with ArrayPtg's encoding of 
+	 */
+	public void testReadWriteTokenValueBytes() {
+		
+		ArrayPtg ptg = new ArrayPtgV(new TestcaseRecordInputStream(ArrayPtgV.sid, ENCODED_PTG_DATA));
+		
+		ptg.readTokenValues(new TestcaseRecordInputStream(0, ENCODED_CONSTANT_DATA));
+		assertEquals(3, ptg.getColumnCount());
+		assertEquals(2, ptg.getRowCount());
+		Object[] values = ptg.token_3_arrayValues;
+		assertEquals(6, values.length);
+		
+		
+		assertEquals(Boolean.TRUE, values[0]);
+		assertEquals(new UnicodeString("ABCD"), values[1]);
+		assertEquals(new Double(0), values[3]);
+		assertEquals(Boolean.FALSE, values[4]);
+		assertEquals(new UnicodeString("FG"), values[5]);
+		
+		byte[] outBuf = new byte[ENCODED_CONSTANT_DATA.length];
+		ptg.writeTokenValueBytes(outBuf, 0);
+		
+		if(outBuf[0] == 4) {
+			throw new AssertionFailedError("Identified bug 42564b");
+		}
+		assertTrue(Arrays.equals(ENCODED_CONSTANT_DATA, outBuf));
+	}
+
+	/**
+	 * make sure constant elements are stored row by row 
+	 */
+	public void testElementOrdering() {
+		ArrayPtg ptg = new ArrayPtgV(new TestcaseRecordInputStream(ArrayPtgV.sid, ENCODED_PTG_DATA));
+		ptg.readTokenValues(new TestcaseRecordInputStream(0, ENCODED_CONSTANT_DATA));
+		assertEquals(3, ptg.getColumnCount());
+		assertEquals(2, ptg.getRowCount());
+		
+		assertEquals(0, ptg.getValueIndex(0, 0));
+		assertEquals(1, ptg.getValueIndex(1, 0));
+		assertEquals(2, ptg.getValueIndex(2, 0));
+		assertEquals(3, ptg.getValueIndex(0, 1));
+		assertEquals(4, ptg.getValueIndex(1, 1));
+		assertEquals(5, ptg.getValueIndex(2, 1));
+	}
+}

Modified: poi/trunk/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java?rev=653668&r1=653667&r2=653668&view=diff
==============================================================================
--- poi/trunk/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java (original)
+++ poi/trunk/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java Mon May  5 19:02:41 2008
@@ -732,7 +732,7 @@
      *  with the NameRecord, once you get past the BOFRecord
      *  issue.
      */
-    public void DISABLEDtest42564Alt() {
+    public void test42564Alt() {
         HSSFWorkbook wb = openSample("42564-2.xls");
         writeOutAndReadBack(wb);
     }



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