poi-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From j...@apache.org
Subject svn commit: r703069 - in /poi/branches/ooxml: ./ src/documentation/content/xdocs/ src/java/org/apache/poi/hssf/record/ src/java/org/apache/poi/hssf/usermodel/ src/java/org/apache/poi/ss/formula/ src/java/org/apache/poi/util/ src/scratchpad/examples/src...
Date Thu, 09 Oct 2008 06:38:51 GMT
Author: josh
Date: Wed Oct  8 23:38:50 2008
New Revision: 703069

URL: http://svn.apache.org/viewvc?rev=703069&view=rev
Log:
Merged revisions 700479,700493,700916,701302,701569,701598,701747 via svnmerge from 
https://svn.apache.org/repos/asf/poi/trunk

........
  r700479 | yegor | 2008-09-30 07:32:37 -0700 (Tue, 30 Sep 2008) | 1 line
  
  reverted the change made in r693085 , see bug #45859
........
  r700493 | yegor | 2008-09-30 08:11:26 -0700 (Tue, 30 Sep 2008) | 1 line
  
  initial support for creating hyperlinks in HSLF, units test are still to do
........
  r700916 | josh | 2008-10-01 13:56:21 -0700 (Wed, 01 Oct 2008) | 1 line
  
  Fixed bug in CellCacheEntry (support for caching blank evaluation results)
........
  r701302 | yegor | 2008-10-02 22:27:06 -0700 (Thu, 02 Oct 2008) | 1 line
  
  fixed bug #45889:rrayIndexOutOfBoundsException when constructing HSLF Table with a single row
........
  r701569 | josh | 2008-10-03 16:50:22 -0700 (Fri, 03 Oct 2008) | 1 line
  
  Fix for bug 45912 - ArrayIndexOutOfBoundsException in EmbeddedObjectRefSubRecord
........
  r701598 | josh | 2008-10-03 21:59:26 -0700 (Fri, 03 Oct 2008) | 1 line
  
  changed workbook reference to index in CellLocation
........
  r701747 | josh | 2008-10-04 21:43:48 -0700 (Sat, 04 Oct 2008) | 1 line
  
  Better bounds checking in RecordInputStream. Removed rarely used methods readShortArray and putShortArray
........

Added:
    poi/branches/ooxml/src/scratchpad/examples/src/org/apache/poi/hslf/examples/CreateHyperlink.java
      - copied unchanged from r701747, poi/trunk/src/scratchpad/examples/src/org/apache/poi/hslf/examples/CreateHyperlink.java
    poi/branches/ooxml/src/testcases/org/apache/poi/ss/formula/TestCellCacheEntry.java
      - copied unchanged from r701747, poi/trunk/src/testcases/org/apache/poi/ss/formula/TestCellCacheEntry.java
Modified:
    poi/branches/ooxml/   (props changed)
    poi/branches/ooxml/src/documentation/content/xdocs/changes.xml
    poi/branches/ooxml/src/documentation/content/xdocs/status.xml
    poi/branches/ooxml/src/java/org/apache/poi/hssf/record/EmbeddedObjectRefSubRecord.java
    poi/branches/ooxml/src/java/org/apache/poi/hssf/record/RecordInputStream.java
    poi/branches/ooxml/src/java/org/apache/poi/hssf/record/SeriesListRecord.java
    poi/branches/ooxml/src/java/org/apache/poi/hssf/usermodel/HSSFObjectData.java
    poi/branches/ooxml/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java
    poi/branches/ooxml/src/java/org/apache/poi/ss/formula/CellCacheEntry.java
    poi/branches/ooxml/src/java/org/apache/poi/ss/formula/CellLocation.java
    poi/branches/ooxml/src/java/org/apache/poi/ss/formula/CollaboratingWorkbooksEnvironment.java
    poi/branches/ooxml/src/java/org/apache/poi/ss/formula/EvaluationCache.java
    poi/branches/ooxml/src/java/org/apache/poi/ss/formula/WorkbookEvaluator.java
    poi/branches/ooxml/src/java/org/apache/poi/util/LittleEndian.java
    poi/branches/ooxml/src/scratchpad/src/org/apache/poi/hslf/model/Table.java
    poi/branches/ooxml/src/scratchpad/src/org/apache/poi/hslf/model/TextShape.java
    poi/branches/ooxml/src/scratchpad/src/org/apache/poi/hslf/record/TxInteractiveInfoAtom.java
    poi/branches/ooxml/src/scratchpad/testcases/org/apache/poi/hslf/model/TestTable.java
    poi/branches/ooxml/src/testcases/org/apache/poi/hssf/record/TestEmbeddedObjectRefSubRecord.java
    poi/branches/ooxml/src/testcases/org/apache/poi/hssf/record/TestSeriesListRecord.java
    poi/branches/ooxml/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java
    poi/branches/ooxml/src/testcases/org/apache/poi/ss/formula/AllSSFormulaTests.java

Propchange: poi/branches/ooxml/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Wed Oct  8 23:38:50 2008
@@ -1 +1 @@
-/poi/trunk:693591-694881,695264-695420,695621,695649-700356
+/poi/trunk:693591-694881,695264-695420,695621,695649-701747

Propchange: poi/branches/ooxml/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Wed Oct  8 23:38:50 2008
@@ -1 +1 @@
-/poi/trunk:1-638784,638786-639486,639488-639601,639603-640056,640058-642562,642564-642566,642568-642574,642576-642736,642739-650914,650916-700356
+/poi/trunk:1-638784,638786-639486,639488-639601,639603-640056,640058-642562,642564-642566,642568-642574,642576-642736,642739-650914,650916-701747

Modified: poi/branches/ooxml/src/documentation/content/xdocs/changes.xml
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/documentation/content/xdocs/changes.xml?rev=703069&r1=703068&r2=703069&view=diff
==============================================================================
--- poi/branches/ooxml/src/documentation/content/xdocs/changes.xml (original)
+++ poi/branches/ooxml/src/documentation/content/xdocs/changes.xml Wed Oct  8 23:38:50 2008
@@ -67,6 +67,9 @@
            <action dev="POI-DEVELOPERS" type="add">Created a common interface for handling Excel files, irrespective of if they are .xls or .xlsx</action>
         </release>
         <release version="3.2-alpha1" date="2008-??-??">
+           <action dev="POI-DEVELOPERS" type="fix">45912 - fixed ArrayIndexOutOfBoundsException in EmbeddedObjectRefSubRecord</action>
+           <action dev="POI-DEVELOPERS" type="fix">45889 - fixed ArrayIndexOutOfBoundsException when constructing HSLF Table with a single row </action>
+           <action dev="POI-DEVELOPERS" type="add">Initial support for creating hyperlinks in HSLF</action>
            <action dev="POI-DEVELOPERS" type="fix">45876 - fixed BoundSheetRecord to allow sheet names longer than 31 chars</action>
            <action dev="POI-DEVELOPERS" type="add">45890 - fixed HSSFSheet.shiftRows to also update conditional formats</action>
            <action dev="POI-DEVELOPERS" type="add">45865 modified Formula Parser/Evaluator to handle cross-worksheet formulas</action>

Modified: poi/branches/ooxml/src/documentation/content/xdocs/status.xml
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/documentation/content/xdocs/status.xml?rev=703069&r1=703068&r2=703069&view=diff
==============================================================================
--- poi/branches/ooxml/src/documentation/content/xdocs/status.xml (original)
+++ poi/branches/ooxml/src/documentation/content/xdocs/status.xml Wed Oct  8 23:38:50 2008
@@ -64,6 +64,9 @@
            <action dev="POI-DEVELOPERS" type="add">Created a common interface for handling Excel files, irrespective of if they are .xls or .xlsx</action>
         </release>
         <release version="3.2-alpha1" date="2008-??-??">
+           <action dev="POI-DEVELOPERS" type="fix">45912 - fixed ArrayIndexOutOfBoundsException in EmbeddedObjectRefSubRecord</action>
+           <action dev="POI-DEVELOPERS" type="fix">45889 - fixed ArrayIndexOutOfBoundsException when constructing HSLF Table with a single row </action>
+           <action dev="POI-DEVELOPERS" type="add">Initial support for creating hyperlinks in HSLF</action>
            <action dev="POI-DEVELOPERS" type="fix">45876 - fixed BoundSheetRecord to allow sheet names longer than 31 chars</action>
            <action dev="POI-DEVELOPERS" type="add">45890 - fixed HSSFSheet.shiftRows to also update conditional formats</action>
            <action dev="POI-DEVELOPERS" type="add">45865 modified Formula Parser/Evaluator to handle cross-worksheet formulas</action>

Modified: poi/branches/ooxml/src/java/org/apache/poi/hssf/record/EmbeddedObjectRefSubRecord.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/java/org/apache/poi/hssf/record/EmbeddedObjectRefSubRecord.java?rev=703069&r1=703068&r2=703069&view=diff
==============================================================================
--- poi/branches/ooxml/src/java/org/apache/poi/hssf/record/EmbeddedObjectRefSubRecord.java (original)
+++ poi/branches/ooxml/src/java/org/apache/poi/hssf/record/EmbeddedObjectRefSubRecord.java Wed Oct  8 23:38:50 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,166 +15,312 @@
    limitations under the License.
 ==================================================================== */
 
-
 package org.apache.poi.hssf.record;
 
+import java.io.ByteArrayInputStream;
 
-
-import org.apache.poi.util.*;
+import org.apache.poi.hssf.record.formula.Area3DPtg;
+import org.apache.poi.hssf.record.formula.AreaPtg;
+import org.apache.poi.hssf.record.formula.Ptg;
+import org.apache.poi.hssf.record.formula.Ref3DPtg;
+import org.apache.poi.hssf.record.formula.RefPtg;
+import org.apache.poi.util.HexDump;
+import org.apache.poi.util.LittleEndian;
+import org.apache.poi.util.StringUtil;
 
 /**
+ * ftPictFmla (0x0009)<br/>
  * A sub-record within the OBJ record which stores a reference to an object
  * stored in a separate entry within the OLE2 compound file.
  *
  * @author Daniel Noll
  */
-public class EmbeddedObjectRefSubRecord
-    extends SubRecord
-{
-    public static final short sid = 0x9;
-
-    public short   field_1_stream_id_offset;                    // Offset to stream ID from the point after this value.
-    public short[] field_2_unknown;                             // Unknown stuff at the front.  TODO: Confirm that it's a short[]
-    // TODO: Consider making a utility class for these.  I've discovered the same field ordering
-    //       in FormatRecord and StringRecord, it may be elsewhere too.
-    public short   field_3_unicode_len;                         // Length of Unicode string.
-    public boolean field_4_unicode_flag;                        // Flags whether the string is Unicode.
-    public String  field_5_ole_classname;                       // Classname of the embedded OLE document (e.g. Word.Document.8)
-    public int     field_6_stream_id;                           // ID of the OLE stream containing the actual data.
-
-    private int field_5_ole_classname_padding; // developer laziness...
-    public byte[] remainingBytes;
-
-    public EmbeddedObjectRefSubRecord()
-    {
-        field_2_unknown = new short[0];
-        remainingBytes = new byte[0];
-        field_1_stream_id_offset = 6;
-        field_5_ole_classname = "";
-    }
-
-    public short getSid()
-    {
-        return sid;
-    }
-
-    public EmbeddedObjectRefSubRecord(RecordInputStream in)
-    {
-        field_1_stream_id_offset       = in.readShort();
-        field_2_unknown                = in.readShortArray();
-        field_3_unicode_len            = in.readShort();
-        field_4_unicode_flag           = ( in.readByte() & 0x01 ) != 0;
-
-        if ( field_4_unicode_flag )
-        {
-            field_5_ole_classname      = in.readUnicodeLEString( field_3_unicode_len );
-        }
-        else
-        {
-            field_5_ole_classname      = in.readCompressedUnicode( field_3_unicode_len );
-        }
-
-        // Padded with NUL bytes.  The -2 is because field_1_stream_id_offset
-        // is relative to after the offset field, whereas in.getRecordOffset()
-        // is relative to the start of this record (minus the header.)
-        field_5_ole_classname_padding = 0;
-        while (in.getRecordOffset() - 2 < field_1_stream_id_offset)
-        {
-            field_5_ole_classname_padding++;
-            in.readByte(); // discard
-        }
-
-        // Fetch the stream ID
-        field_6_stream_id = in.readInt();
-        
-        // Store what's left
-        remainingBytes = in.readRemainder();
-    }
-
-    public int serialize(int offset, byte[] data)
-    {
-        int pos = offset;
-
-        LittleEndian.putShort(data, pos, sid); pos += 2;
-        LittleEndian.putShort(data, pos, (short)(getRecordSize() - 4)); pos += 2;
-
-        LittleEndian.putShort(data, pos, field_1_stream_id_offset); pos += 2;
-        LittleEndian.putShortArray(data, pos, field_2_unknown); pos += field_2_unknown.length * 2 + 2;
-        LittleEndian.putShort(data, pos, field_3_unicode_len); pos += 2;
-        data[pos] = field_4_unicode_flag ? (byte) 0x01 : (byte) 0x00; pos++;
-
-        if ( field_4_unicode_flag )
-        {
-            StringUtil.putUnicodeLE( field_5_ole_classname, data, pos ); pos += field_5_ole_classname.length() * 2;
-        }
-        else
-        {
-            StringUtil.putCompressedUnicode( field_5_ole_classname, data, pos ); pos += field_5_ole_classname.length();
-        }
-
-        // Padded with the same number of NUL bytes as were originally skipped.
-        // XXX: This is only accurate until we make the classname mutable.
-        pos += field_5_ole_classname_padding;
-        
-        LittleEndian.putInt(data, pos, field_6_stream_id); pos += 4;
-
-        System.arraycopy(remainingBytes, 0, data, pos, remainingBytes.length);
-
-        return getRecordSize();
-    }
-
-    /**
-     * Size of record (exluding 4 byte header)
-     */
-    public int getRecordSize()
-    {
-        // The stream id offset is relative to after the stream ID.
-        // Add 2 bytes for the stream id offset and 4 bytes for the stream id itself and 4 byts for the record header.
-        return remainingBytes.length + field_1_stream_id_offset + 2 + 4 + 4;
-    }
-
-    /**
-     * Gets the stream ID containing the actual data.  The data itself
-     * can be found under a top-level directory entry in the OLE2 filesystem
-     * under the name "MBD<var>xxxxxxxx</var>" where <var>xxxxxxxx</var> is
-     * this ID converted into hex (in big endian order, funnily enough.)
-     * 
-     * @return the data stream ID.
-     */
-    public int getStreamId()
-    {
-        return field_6_stream_id;
-    }
-
-    public String toString()
-    {
-        StringBuffer buffer = new StringBuffer();
-        buffer.append("[ftPictFmla]\n");
-        buffer.append("    .streamIdOffset       = ")
-            .append("0x").append(HexDump.toHex(  field_1_stream_id_offset ))
-            .append(" (").append( field_1_stream_id_offset ).append(" )")
-            .append(System.getProperty("line.separator"));
-        buffer.append("    .unknown              = ")
-            .append("0x").append(HexDump.toHex(  field_2_unknown ))
-            .append(" (").append( field_2_unknown.length ).append(" )")
-            .append(System.getProperty("line.separator"));
-        buffer.append("    .unicodeLen           = ")
-            .append("0x").append(HexDump.toHex(  field_3_unicode_len ))
-            .append(" (").append( field_3_unicode_len ).append(" )")
-            .append(System.getProperty("line.separator"));
-        buffer.append("    .unicodeFlag          = ")
-            .append("0x").append( field_4_unicode_flag ? 0x01 : 0x00 )
-            .append(" (").append( field_4_unicode_flag ).append(" )")
-            .append(System.getProperty("line.separator"));
-        buffer.append("    .oleClassname         = ")
-            .append(field_5_ole_classname)
-            .append(System.getProperty("line.separator"));
-        buffer.append("    .streamId             = ")
-            .append("0x").append(HexDump.toHex(  field_6_stream_id ))
-            .append(" (").append( field_6_stream_id ).append(" )")
-            .append(System.getProperty("line.separator"));
-        buffer.append("[/ftPictFmla]");
-        return buffer.toString();
-    }
+public final class EmbeddedObjectRefSubRecord extends SubRecord {
+	public static final short sid = 0x0009;
+
+	private static final byte[] EMPTY_BYTE_ARRAY = { };
 
+	private int field_1_unknown_int;
+	/** either an area or a cell ref */
+	private Ptg field_2_refPtg;
+	private byte[] field_2_unknownFormulaData;
+	// TODO: Consider making a utility class for these.  I've discovered the same field ordering
+	//	   in FormatRecord and StringRecord, it may be elsewhere too.
+	private boolean field_3_unicode_flag;  // Flags whether the string is Unicode.
+	private String  field_4_ole_classname; // Classname of the embedded OLE document (e.g. Word.Document.8)
+	/** Formulas often have a single non-zero trailing byte.
+	 * This is in a similar position to he pre-streamId padding
+	 * It is unknown if the value is important (it seems to mirror a value a few bytes earlier) 
+	 *  */
+	private Byte  field_4_unknownByte;
+	private Integer field_5_stream_id;     // ID of the OLE stream containing the actual data.
+	private byte[] field_6_unknown;
+
+
+	// currently for testing only - needs review
+	EmbeddedObjectRefSubRecord() {
+		field_2_unknownFormulaData = new byte[] { 0x02, 0x6C, 0x6A, 0x16, 0x01, }; // just some sample data.  These values vary a lot
+		field_6_unknown = EMPTY_BYTE_ARRAY;
+		field_4_ole_classname = null;
+	}
+
+	public short getSid() {
+		return sid;
+	}
+
+	public EmbeddedObjectRefSubRecord(RecordInputStream in) {
+		// Much guess-work going on here due to lack of any documentation.
+		// See similar source code in OOO:
+		// http://lxr.go-oo.org/source/sc/sc/source/filter/excel/xiescher.cxx
+		// 1223 void XclImpOleObj::ReadPictFmla( XclImpStream& rStrm, sal_uInt16 nRecSize )
+
+		int streamIdOffset = in.readShort(); // OOO calls this 'nFmlaLen'
+
+		int dataLenAfterFormula = in.remaining() - streamIdOffset;
+		int formulaSize = in.readUShort();
+		field_1_unknown_int = in.readInt();
+		byte[] formulaRawBytes = readRawData(in, formulaSize);
+		field_2_refPtg = readRefPtg(formulaRawBytes);
+		if (field_2_refPtg == null) {
+			// common case
+			// field_2_n16 seems to be 5 here
+			// The formula almost looks like tTbl but the row/column values seem like garbage.
+			field_2_unknownFormulaData = formulaRawBytes;
+		} else {
+			field_2_unknownFormulaData = null;
+		}
+
+		int stringByteCount;
+		if (in.remaining() >= dataLenAfterFormula + 3) {
+			int tag = in.readByte();
+			if (tag != 0x03) {
+				throw new RecordFormatException("Expected byte 0x03 here");
+			}
+			int nChars = in.readUShort();
+			if (nChars > 0) {
+				 // OOO: the 4th way Xcl stores a unicode string: not even a Grbit byte present if length 0
+				field_3_unicode_flag		   = ( in.readByte() & 0x01 ) != 0;
+				if (field_3_unicode_flag) {
+					field_4_ole_classname = in.readUnicodeLEString(nChars);
+					stringByteCount = nChars * 2;
+				} else {
+					field_4_ole_classname = in.readCompressedUnicode(nChars);
+					stringByteCount = nChars;
+				}
+			} else {
+				field_4_ole_classname = "";
+				stringByteCount = 0;
+			}
+		} else {
+			field_4_ole_classname = null;
+			stringByteCount = 0;
+		}
+		// Pad to next 2-byte boundary
+		if (((stringByteCount + formulaSize) % 2) != 0) {
+			int b = in.readByte();
+			if (field_2_refPtg != null && field_4_ole_classname == null) {
+				field_4_unknownByte = new Byte((byte)b);
+			}
+		}
+		int nUnexpectedPadding = in.remaining() - dataLenAfterFormula;
+
+		if (nUnexpectedPadding > 0) {
+			System.err.println("Discarding " + nUnexpectedPadding + " unexpected padding bytes ");
+			readRawData(in, nUnexpectedPadding);
+		}
+
+		// Fetch the stream ID
+		if (dataLenAfterFormula >= 4) {
+			field_5_stream_id = new Integer(in.readInt());
+		} else {
+			field_5_stream_id = null;
+		}
+
+		field_6_unknown = in.readRemainder();
+	}
+
+	private static Ptg readRefPtg(byte[] formulaRawBytes) {
+		byte[] data = new byte[formulaRawBytes.length + 4];
+		LittleEndian.putUShort(data, 0, -5555);
+		LittleEndian.putUShort(data, 2, formulaRawBytes.length);
+		System.arraycopy(formulaRawBytes, 0, data, 4, formulaRawBytes.length);
+		RecordInputStream in = new RecordInputStream(new ByteArrayInputStream(data));
+		in.nextRecord();
+	   	byte ptgSid = in.readByte();
+		switch(ptgSid) {
+			case AreaPtg.sid:   return new AreaPtg(in);
+			case Area3DPtg.sid: return new Area3DPtg(in);
+			case RefPtg.sid:	return new RefPtg(in);
+			case Ref3DPtg.sid:  return new Ref3DPtg(in);
+		}
+		return null;
+	}
+
+	private static byte[] readRawData(RecordInputStream in, int size) {
+		if (size < 0) {
+			throw new IllegalArgumentException("Negative size (" + size + ")");
+		}
+		if (size == 0) {
+			return EMPTY_BYTE_ARRAY;
+		}
+		byte[] result = new byte[size];
+		for(int i=0; i< size; i++) {
+			result[i] = in.readByte();
+		}
+		return result;
+	}
+	
+	private int getStreamIDOffset(int formulaSize) {
+		int result = 2 + 4; // formulaSize + f2unknown_int
+		result += formulaSize;
+		
+		int stringLen;
+		if (field_4_ole_classname == null) {
+			// don't write 0x03, stringLen, flag, text
+			stringLen = 0;
+		} else {
+			result += 1 + 2 + 1;  // 0x03, stringLen, flag
+			stringLen = field_4_ole_classname.length();
+			if (field_3_unicode_flag) {
+				result += stringLen * 2;
+			} else {
+				result += stringLen;
+			}
+		}
+		// pad to next 2 byte boundary
+		if ((result % 2) != 0) {
+			result ++; 
+		}
+		return result;
+	}
+	
+	private int getDataSize(int idOffset) {
+
+		int result = 2 + idOffset; // 2 for idOffset short field itself
+		if (field_5_stream_id != null) {
+    		result += 4;
+		}
+		return result +  field_6_unknown.length;
+	}
+	private int getDataSize() {
+		int formulaSize = field_2_refPtg == null ? field_2_unknownFormulaData.length : field_2_refPtg.getSize();
+		int idOffset = getStreamIDOffset(formulaSize);
+		return getDataSize(idOffset);
+	}
+
+	public int serialize(int base, byte[] data) {
+
+		int formulaSize = field_2_refPtg == null ? field_2_unknownFormulaData.length : field_2_refPtg.getSize();
+		int idOffset = getStreamIDOffset(formulaSize);
+		int dataSize = getDataSize(idOffset);
+		
+
+		LittleEndian.putUShort(data, base + 0, sid);
+		LittleEndian.putUShort(data, base + 2, dataSize);
+
+		LittleEndian.putUShort(data, base + 4, idOffset);
+		LittleEndian.putUShort(data, base + 6, formulaSize);
+		LittleEndian.putInt(data, base + 8, field_1_unknown_int);
+
+		int pos = base+12;
+
+		if (field_2_refPtg == null) {
+			System.arraycopy(field_2_unknownFormulaData, 0, data, pos, field_2_unknownFormulaData.length);
+		} else {
+			field_2_refPtg.writeBytes(data, pos);
+		}
+	   	pos += formulaSize;
+
+		int stringLen;
+		if (field_4_ole_classname == null) {
+			// don't write 0x03, stringLen, flag, text
+			stringLen = 0;
+		} else {
+			LittleEndian.putByte(data, pos, 0x03);
+			pos += 1;
+			stringLen = field_4_ole_classname.length();
+			LittleEndian.putUShort(data, pos, stringLen);
+			pos += 2;
+			LittleEndian.putByte(data, pos, field_3_unicode_flag ? 0x01 : 0x00);
+			pos += 1;
+
+			if (field_3_unicode_flag) {
+				StringUtil.putUnicodeLE(field_4_ole_classname, data, pos);
+				pos += stringLen * 2;
+			} else {
+				StringUtil.putCompressedUnicode(field_4_ole_classname, data, pos);
+				pos += stringLen;
+			}
+		}
+
+		// pad to next 2-byte boundary (requires 0 or 1 bytes)
+		switch(idOffset - (pos - 6 - base)) { // 6 for 3 shorts: sid, dataSize, idOffset
+			case 1:
+				LittleEndian.putByte(data, pos, field_4_unknownByte == null ? 0x00 : field_4_unknownByte.intValue());
+				pos ++;
+			case 0:
+				break;
+			default:
+				throw new IllegalStateException("Bad padding calculation (" + idOffset + ", " + (pos-base) + ")");	
+		}
+
+		if (field_5_stream_id != null) {
+    		LittleEndian.putInt(data, pos, field_5_stream_id.intValue());
+    		pos += 4;
+		}
+		System.arraycopy(field_6_unknown, 0, data, pos, field_6_unknown.length);
+
+		return 4 + dataSize;
+	}
+
+	public int getRecordSize() {
+		return 4 + getDataSize();
+	}
+
+	/**
+	 * Gets the stream ID containing the actual data.  The data itself
+	 * can be found under a top-level directory entry in the OLE2 filesystem
+	 * under the name "MBD<var>xxxxxxxx</var>" where <var>xxxxxxxx</var> is
+	 * this ID converted into hex (in big endian order, funnily enough.)
+	 *
+	 * @return the data stream ID. Possibly <code>null</code>
+	 */
+	public Integer getStreamId() {
+		return field_5_stream_id;
+	}
+
+	public String getOLEClassName() {
+		return field_4_ole_classname;
+	}
+
+	public byte[] getObjectData() {
+		return field_6_unknown;
+	}
+
+
+	public String toString() {
+		StringBuffer sb = new StringBuffer();
+		sb.append("[ftPictFmla]\n");
+		sb.append("    .f2unknown     = ").append(HexDump.intToHex(field_1_unknown_int)).append("\n");
+		if (field_2_refPtg == null) {
+			sb.append("    .f3unknown     = ").append(HexDump.toHex(field_2_unknownFormulaData)).append("\n");
+		} else {
+			sb.append("    .formula       = ").append(field_2_refPtg.toString()).append("\n");
+		}
+		if (field_4_ole_classname != null) {
+			sb.append("    .unicodeFlag   = ").append(field_3_unicode_flag).append("\n");
+			sb.append("    .oleClassname  = ").append(field_4_ole_classname).append("\n");
+		}
+		if (field_4_unknownByte != null) {
+			sb.append("    .f4unknown   = ").append(HexDump.byteToHex(field_4_unknownByte.intValue())).append("\n");
+		}
+		if (field_5_stream_id != null) {
+			sb.append("    .streamId      = ").append(HexDump.intToHex(field_5_stream_id.intValue())).append("\n");
+		}
+		if (field_6_unknown.length > 0) {
+			sb.append("    .f7unknown     = ").append(HexDump.toHex(field_6_unknown)).append("\n");
+		}
+		sb.append("[/ftPictFmla]");
+		return sb.toString();
+	}
 }

Modified: poi/branches/ooxml/src/java/org/apache/poi/hssf/record/RecordInputStream.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/java/org/apache/poi/hssf/record/RecordInputStream.java?rev=703069&r1=703068&r2=703069&view=diff
==============================================================================
--- poi/branches/ooxml/src/java/org/apache/poi/hssf/record/RecordInputStream.java (original)
+++ poi/branches/ooxml/src/java/org/apache/poi/hssf/record/RecordInputStream.java Wed Oct  8 23:38:50 2008
@@ -33,7 +33,7 @@
   /** Maximum size of a single record (minus the 4 byte header) without a continue*/
   public final static short MAX_RECORD_DATA_SIZE = 8224;
   private static final int INVALID_SID_VALUE = -1;
-  
+
   private InputStream in;
   protected short currentSid;
   protected short currentLength = -1;
@@ -42,34 +42,34 @@
   protected byte[] data = new byte[MAX_RECORD_DATA_SIZE];
   protected short recordOffset;
   protected long pos;
-  
+
   private boolean autoContinue = true;
 
-  public RecordInputStream(InputStream in) throws RecordFormatException  {
+  public RecordInputStream(InputStream in) throws RecordFormatException {
     this.in = in;
     try {
       nextSid = LittleEndian.readShort(in);
-      //Dont increment the pos just yet (technically we are at the start of
-      //the record stream until nextRecord is called).      
+      //Don't increment the pos just yet (technically we are at the start of
+      //the record stream until nextRecord is called).
     } catch (IOException ex) {
       throw new RecordFormatException("Error reading bytes", ex);
     }
   }
-  
-  /** This method will read a byte from the current record*/
-  public int read() {
-    checkRecordPosition();
-
-    byte result = data[recordOffset];
-    recordOffset += 1;
-    pos += 1;
-    return result;    
-  }
-  
+
+	/** This method will read a byte from the current record*/
+	public int read() {
+		checkRecordPosition(LittleEndian.BYTE_SIZE);
+
+		byte result = data[recordOffset];
+		recordOffset += LittleEndian.BYTE_SIZE;
+		pos += LittleEndian.BYTE_SIZE;
+		return result;
+	}
+
   public short getSid() {
     return currentSid;
   }
-  
+
   public short getLength() {
     return currentLength;
   }
@@ -85,12 +85,11 @@
   public boolean hasNextRecord() {
     return nextSid != INVALID_SID_VALUE;
   }
-  
+
   /** Moves to the next record in the stream.
-   * 
+   *
    * <i>Note: The auto continue flag is reset to true</i>
    */
-  
   public void nextRecord() throws RecordFormatException {
     if ((currentLength != -1) && (currentLength != recordOffset)) {
       System.out.println("WARN. Unread "+remaining()+" bytes of record 0x"+Integer.toHexString(currentSid));
@@ -100,7 +99,7 @@
     autoContinue = true;
     try {
       recordOffset = 0;
-      currentLength = LittleEndian.readShort(in);     
+      currentLength = LittleEndian.readShort(in);
       if (currentLength > MAX_RECORD_DATA_SIZE)
         throw new RecordFormatException("The content of an excel record cannot exceed "+MAX_RECORD_DATA_SIZE+" bytes");
       pos += LittleEndian.SHORT_SIZE;
@@ -113,138 +112,124 @@
               // ex45582-22397.xls has one extra byte after the last record
               // Excel reads that file OK
           }
-          nextSid = INVALID_SID_VALUE;  
+          nextSid = INVALID_SID_VALUE;
       } else {
           nextSid = LittleEndian.readShort(in);
           if (nextSid == INVALID_SID_VALUE) {
               throw new RecordFormatException("Found sid " + nextSid + " after record with sid 0x"
                       + Integer.toHexString(currentSid).toUpperCase());
           }
-      }      
+      }
     } catch (IOException ex) {
       throw new RecordFormatException("Error reading bytes", ex);
     }
   }
-  
+
   public void setAutoContinue(boolean enable) {
-    this.autoContinue = enable;    
+    this.autoContinue = enable;
   }
-  
+
   public boolean getAutoContinue() {
     return autoContinue;
   }
-  
-  protected void checkRecordPosition() {
-    if (remaining() <= 0) {
-      if (isContinueNext() && autoContinue) {
-        nextRecord();
-      }
-      else throw new ArrayIndexOutOfBoundsException();
-    }    
-  }
-  
-  /**
-   * Reads an 8 bit, signed value
-   */
-  public byte readByte() {
-    checkRecordPosition();
-    
-    byte result = data[recordOffset];
-    recordOffset += 1;
-    pos += 1;
-    return result;
-  }
-  
-  /**
-   * Reads a 16 bit, signed value
-   */
-  public short readShort() {
-    checkRecordPosition();
-    
-    short result = LittleEndian.getShort(data, recordOffset);
-    recordOffset += LittleEndian.SHORT_SIZE;
-    pos += LittleEndian.SHORT_SIZE;
-    return result;
-  }
 
-  public int readInt() {
-    checkRecordPosition();
-    
-    int result = LittleEndian.getInt(data, recordOffset);
-    recordOffset += LittleEndian.INT_SIZE;
-    pos += LittleEndian.INT_SIZE;
-    return result;
-  }
+	private void checkRecordPosition(int requiredByteCount) {
 
-  public long readLong() {
-    checkRecordPosition();    
-    
-    long result = LittleEndian.getLong(data, recordOffset);
-    recordOffset += LittleEndian.LONG_SIZE;
-    pos += LittleEndian.LONG_SIZE;
-    return result;
-  }
+		if (remaining() < requiredByteCount) {
+			if (isContinueNext() && autoContinue) {
+				nextRecord();
+			} else {
+			   throw new ArrayIndexOutOfBoundsException();
+			}
+		}
+	}
+
+	/**
+	 * Reads an 8 bit, signed value
+	 */
+	public byte readByte() {
+		checkRecordPosition(LittleEndian.BYTE_SIZE);
+
+		byte result = data[recordOffset];
+		recordOffset += LittleEndian.BYTE_SIZE;
+		pos += LittleEndian.BYTE_SIZE;
+		return result;
+	}
+
+	/**
+	 * Reads a 16 bit, signed value
+	 */
+	public short readShort() {
+		checkRecordPosition(LittleEndian.SHORT_SIZE);
+
+		short result = LittleEndian.getShort(data, recordOffset);
+		recordOffset += LittleEndian.SHORT_SIZE;
+		pos += LittleEndian.SHORT_SIZE;
+		return result;
+	}
+
+	public int readInt() {
+		checkRecordPosition(LittleEndian.INT_SIZE);
+
+		int result = LittleEndian.getInt(data, recordOffset);
+		recordOffset += LittleEndian.INT_SIZE;
+		pos += LittleEndian.INT_SIZE;
+		return result;
+	}
+
+	public long readLong() {
+		checkRecordPosition(LittleEndian.LONG_SIZE);
+
+		long result = LittleEndian.getLong(data, recordOffset);
+		recordOffset += LittleEndian.LONG_SIZE;
+		pos += LittleEndian.LONG_SIZE;
+		return result;
+	}
+
+	/**
+	 * Reads an 8 bit, unsigned value
+	 */
+	public short readUByte() {
+		return (short) (readByte() & 0x00FF);
+	}
+
+	/**
+	 * Reads a 16 bit, unsigned value.
+	 * @return
+	 */
+	public int readUShort() {
+		checkRecordPosition(LittleEndian.SHORT_SIZE);
+
+		int result = LittleEndian.getUShort(data, recordOffset);
+		recordOffset += LittleEndian.SHORT_SIZE;
+		pos += LittleEndian.SHORT_SIZE;
+		return result;
+	}
+
+	public double readDouble() {
+		checkRecordPosition(LittleEndian.DOUBLE_SIZE);
+		long valueLongBits = LittleEndian.getLong(data, recordOffset);
+		double result = Double.longBitsToDouble(valueLongBits);
+		if (Double.isNaN(result)) {
+			throw new RuntimeException("Did not expect to read NaN"); // (Because Excel typically doesn't write NaN
+		}
+		recordOffset += LittleEndian.DOUBLE_SIZE;
+		pos += LittleEndian.DOUBLE_SIZE;
+		return result;
+	}
 
   /**
-   * Reads an 8 bit, unsigned value
-   */
-  public short readUByte() {
-      short s = readByte();
-      if(s < 0) {
-          s += 256;
-      }
-      return s;
-  }
-
-  /**
-   * Reads a 16 bit,un- signed value.
-   * @return
-   */
-  public int readUShort() {
-    checkRecordPosition();    
-    
-    int result = LittleEndian.getUShort(data, recordOffset);
-    recordOffset += LittleEndian.SHORT_SIZE;
-    pos += LittleEndian.SHORT_SIZE;
-    return result;
-  }
-
-  public double readDouble() {
-    checkRecordPosition();
-    long valueLongBits = LittleEndian.getLong(data, recordOffset);
-    double result = Double.longBitsToDouble(valueLongBits);
-    if (Double.isNaN(result)) {
-      throw new RuntimeException("Did not expect to read NaN");
-    }
-    recordOffset += LittleEndian.DOUBLE_SIZE;
-    pos += LittleEndian.DOUBLE_SIZE;
-    return result;
-  }
-
-  
-  public short[] readShortArray() {
-    checkRecordPosition();
-    
-    short[] arr = LittleEndian.getShortArray(data, recordOffset);
-    final int size = (2 * (arr.length +1));
-    recordOffset += size;
-    pos += size;
-    
-    return arr;
-  }
-  
-  /**     
-   *  given a byte array of 16-bit unicode characters, compress to 8-bit and     
-   *  return a string     
-   *     
-   * { 0x16, 0x00 } -0x16     
-   *      
+   *  given a byte array of 16-bit unicode characters, compress to 8-bit and
+   *  return a string
+   *
+   * { 0x16, 0x00 } -0x16
+   *
    * @param length the length of the final string
    * @return                                     the converted string
    * @exception  IllegalArgumentException        if len is too large (i.e.,
-   *      there is not enough data in string to create a String of that     
-   *      length)     
-   */  
+   *      there is not enough data in string to create a String of that
+   *      length)
+   */
   public String readUnicodeLEString(int length) {
     if ((length < 0) || (((remaining() / 2) < length) && !isContinueNext())) {
             throw new IllegalArgumentException("Illegal length - asked for " + length + " but only " + (remaining()/2) + " left!");
@@ -258,11 +243,11 @@
         if(compressByte != 1) throw new IllegalArgumentException("compressByte in continue records must be 1 while reading unicode LE string");
       }
       char ch = (char)readShort();
-      buf.append(ch); 
+      buf.append(ch);
     }
     return buf.toString();
   }
-    
+
   public String readCompressedUnicode(int length) {
     if ((length < 0) || ((remaining() < length) && !isContinueNext())) {
             throw new IllegalArgumentException("Illegal length " + length);
@@ -277,23 +262,23 @@
       }
       byte b = readByte();
       char ch = (char)(0x00FF & b); // avoid sex
-      buf.append(ch); 
+      buf.append(ch);
     }
-    return buf.toString();    
+    return buf.toString();
   }
-  
+
   /** Returns an excel style unicode string from the bytes reminaing in the record.
    * <i>Note:</i> Unicode strings differ from <b>normal</b> strings due to the addition of
    * formatting information.
-   * 
+   *
    * @return The unicode string representation of the remaining bytes.
    */
   public UnicodeString readUnicodeString() {
     return new UnicodeString(this);
   }
-  
+
   /** Returns the remaining bytes for the current record.
-   * 
+   *
    * @return The remaining bytes of the current record.
    */
   public byte[] readRemainder() {
@@ -304,39 +289,39 @@
     pos += size;
     return result;
   }
-  
+
   /** Reads all byte data for the current record, including any
    *  that overlaps into any following continue records.
-   * 
+   *
    *  @deprecated Best to write a input stream that wraps this one where there is
    *  special sub record that may overlap continue records.
-   */  
+   */
   public byte[] readAllContinuedRemainder() {
     //Using a ByteArrayOutputStream is just an easy way to get a
     //growable array of the data.
     ByteArrayOutputStream out = new ByteArrayOutputStream(2*MAX_RECORD_DATA_SIZE);
 
     while (isContinueNext()) {
-      byte[] b = readRemainder();      
+      byte[] b = readRemainder();
       out.write(b, 0, b.length);
       nextRecord();
     }
-    byte[] b = readRemainder();      
-    out.write(b, 0, b.length);    
-    
+    byte[] b = readRemainder();
+    out.write(b, 0, b.length);
+
     return out.toByteArray();
   }
 
   /** The remaining number of bytes in the <i>current</i> record.
-   * 
+   *
    * @return The number of bytes remaining in the current record
    */
   public int remaining() {
     return (currentLength - recordOffset);
   }
 
-  /** Returns true iif a Continue record is next in the excel stream 
-   * 
+  /** Returns true iif a Continue record is next in the excel stream
+   *
    * @return True when a ContinueRecord is next.
    */
   public boolean isContinueNext() {

Modified: poi/branches/ooxml/src/java/org/apache/poi/hssf/record/SeriesListRecord.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/java/org/apache/poi/hssf/record/SeriesListRecord.java?rev=703069&r1=703068&r2=703069&view=diff
==============================================================================
--- poi/branches/ooxml/src/java/org/apache/poi/hssf/record/SeriesListRecord.java (original)
+++ poi/branches/ooxml/src/java/org/apache/poi/hssf/record/SeriesListRecord.java Wed Oct  8 23:38:50 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,66 +14,66 @@
    See the License for the specific language governing permissions and
    limitations under the License.
 ==================================================================== */
-        
 
 package org.apache.poi.hssf.record;
 
-
-
-import org.apache.poi.util.*;
+import org.apache.poi.util.LittleEndian;
 
 /**
- * The series list record defines the series displayed as an overlay to the main chart record.
- * NOTE: This source is automatically generated please do not modify this file.  Either subclass or
- *       remove the record in src/records/definitions.
-
+ * 
+ * The series list record defines the series displayed as an overlay to the main chart record.<br/>
+ * TODO - does this record (0x1016) really exist.  It doesn't seem to be referenced in either the OOO or MS doc
+ * 
  * @author Glen Stampoultzis (glens at apache.org)
  */
-public class SeriesListRecord
-    extends Record
-{
-    public final static short      sid                             = 0x1016;
+public final class SeriesListRecord extends Record {
+    public final static short sid = 0x1016;
     private  short[]    field_1_seriesNumbers;
 
-
-    public SeriesListRecord()
-    {
-
+    public SeriesListRecord(short[] seriesNumbers) {
+    	field_1_seriesNumbers = seriesNumbers;
     }
 
-    public SeriesListRecord(RecordInputStream in)
-    {
-        field_1_seriesNumbers          = in.readShortArray();
+    public SeriesListRecord(RecordInputStream in) {
+    	int nItems = in.readUShort();
+    	short[] ss = new short[nItems];
+    	for (int i = 0; i < nItems; i++) {
+			ss[i] = in.readShort();
+			
+		}
+        field_1_seriesNumbers = ss;
     }
 
-    public String toString()
-    {
+    public String toString() {
         StringBuffer buffer = new StringBuffer();
 
         buffer.append("[SERIESLIST]\n");
-        buffer.append("    .seriesNumbers        = ")
-            .append(" (").append( getSeriesNumbers() ).append(" )");
-        buffer.append(System.getProperty("line.separator")); 
+        buffer.append("    .seriesNumbers= ").append(" (").append( getSeriesNumbers() ).append(" )");
+        buffer.append("\n"); 
 
         buffer.append("[/SERIESLIST]\n");
         return buffer.toString();
     }
 
-    public int serialize(int offset, byte[] data)
-    {
-        int pos = 0;
+    public int serialize(int offset, byte[] data) {
 
-        LittleEndian.putShort(data, 0 + offset, sid);
-        LittleEndian.putShort(data, 2 + offset, (short)(getRecordSize() - 4));
+        int nItems = field_1_seriesNumbers.length;
+        int dataSize = 2 + 2 * nItems;
+    	
+        LittleEndian.putUShort(data, 0 + offset, sid);
+        LittleEndian.putUShort(data, 2 + offset, dataSize);
 
-        LittleEndian.putShortArray(data, 4 + offset + pos, field_1_seriesNumbers);
+        LittleEndian.putUShort(data, 4 + offset, nItems);
+        
+        int pos = offset + 6;
+    	for (int i = 0; i < nItems; i++) {
+    		LittleEndian.putUShort(data, pos, field_1_seriesNumbers[i]);
+    		pos += 2;
+    	}
 
-        return getRecordSize();
+        return 4 + dataSize;
     }
 
-    /**
-     * Size of record (exluding 4 byte header)
-     */
     public int getRecordSize()
     {
         return 4  + field_1_seriesNumbers.length * 2 + 2;
@@ -86,34 +85,23 @@
     }
 
     public Object clone() {
-        SeriesListRecord rec = new SeriesListRecord();
-    
-        rec.field_1_seriesNumbers = field_1_seriesNumbers;
-        return rec;
+        return new SeriesListRecord((short[]) field_1_seriesNumbers.clone());
     }
 
-
-
-
     /**
      * Get the series numbers field for the SeriesList record.
      */
-    public short[] getSeriesNumbers()
-    {
+    public short[] getSeriesNumbers() {
         return field_1_seriesNumbers;
     }
 
     /**
      * Set the series numbers field for the SeriesList record.
      */
-    public void setSeriesNumbers(short[] field_1_seriesNumbers)
-    {
+    public void setSeriesNumbers(short[] field_1_seriesNumbers) {
         this.field_1_seriesNumbers = field_1_seriesNumbers;
     }
-
-
-}  // END OF CLASS
-
+}
 
 
 

Modified: poi/branches/ooxml/src/java/org/apache/poi/hssf/usermodel/HSSFObjectData.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/java/org/apache/poi/hssf/usermodel/HSSFObjectData.java?rev=703069&r1=703068&r2=703069&view=diff
==============================================================================
--- poi/branches/ooxml/src/java/org/apache/poi/hssf/usermodel/HSSFObjectData.java (original)
+++ poi/branches/ooxml/src/java/org/apache/poi/hssf/usermodel/HSSFObjectData.java Wed Oct  8 23:38:50 2008
@@ -32,7 +32,7 @@
  *
  * @author Daniel Noll
  */
-public class HSSFObjectData
+public final class HSSFObjectData
 {
     /**
      * Underlying object record ultimately containing a reference to the object.
@@ -60,8 +60,7 @@
      * Returns the OLE2 Class Name of the object
      */
     public String getOLE2ClassName() {
-    	EmbeddedObjectRefSubRecord subRecord = findObjectRecord();
-    	return subRecord.field_5_ole_classname;
+        return findObjectRecord().getOLEClassName();
     }
 
     /**
@@ -72,9 +71,9 @@
      * @throws IOException if there was an error reading the data.
      */
     public DirectoryEntry getDirectory() throws IOException {
-    	EmbeddedObjectRefSubRecord subRecord = findObjectRecord();
+        EmbeddedObjectRefSubRecord subRecord = findObjectRecord();
 
-    	int streamId = ((EmbeddedObjectRefSubRecord) subRecord).getStreamId();
+        int streamId = subRecord.getStreamId().intValue();
         String streamName = "MBD" + HexDump.toHex(streamId);
 
         Entry entry = poifs.getRoot().getEntry(streamName);
@@ -91,8 +90,7 @@
      *  Entry
      */
     public byte[] getObjectData() {
-    	EmbeddedObjectRefSubRecord subRecord = findObjectRecord();
-    	return subRecord.remainingBytes;
+        return findObjectRecord().getObjectData();
     }
     
     /**
@@ -101,10 +99,11 @@
      * (Not all do, those that don't have a data portion)
      */
     public boolean hasDirectoryEntry() {
-    	EmbeddedObjectRefSubRecord subRecord = findObjectRecord();
-    	
-    	// Field 6 tells you
-    	return (subRecord.field_6_stream_id != 0);
+        EmbeddedObjectRefSubRecord subRecord = findObjectRecord();
+        
+        // 'stream id' field tells you
+        Integer streamId = subRecord.getStreamId();
+        return streamId != null && streamId.intValue() != 0;
     }
     
     /**
@@ -117,7 +116,7 @@
         while (subRecordIter.hasNext()) {
             Object subRecord = subRecordIter.next();
             if (subRecord instanceof EmbeddedObjectRefSubRecord) {
-            	return (EmbeddedObjectRefSubRecord)subRecord;
+                return (EmbeddedObjectRefSubRecord)subRecord;
             }
         }
         

Modified: poi/branches/ooxml/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java?rev=703069&r1=703068&r2=703069&view=diff
==============================================================================
--- poi/branches/ooxml/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java (original)
+++ poi/branches/ooxml/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java Wed Oct  8 23:38:50 2008
@@ -724,8 +724,8 @@
             HSSFName newName = new HSSFName(this, newNameRecord);
             names.add(newName);
 
+            workbook.cloneDrawings(clonedSheet.getSheet());
         }
-        workbook.cloneDrawings(clonedSheet.getSheet());
         // TODO - maybe same logic required for other/all built-in name records
         
         return clonedSheet;

Modified: poi/branches/ooxml/src/java/org/apache/poi/ss/formula/CellCacheEntry.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/java/org/apache/poi/ss/formula/CellCacheEntry.java?rev=703069&r1=703068&r2=703069&view=diff
==============================================================================
--- poi/branches/ooxml/src/java/org/apache/poi/ss/formula/CellCacheEntry.java (original)
+++ poi/branches/ooxml/src/java/org/apache/poi/ss/formula/CellCacheEntry.java Wed Oct  8 23:38:50 2008
@@ -20,6 +20,7 @@
 import java.util.HashSet;
 import java.util.Set;
 
+import org.apache.poi.hssf.record.formula.eval.BlankEval;
 import org.apache.poi.hssf.record.formula.eval.BoolEval;
 import org.apache.poi.hssf.record.formula.eval.ErrorEval;
 import org.apache.poi.hssf.record.formula.eval.NumberEval;
@@ -60,6 +61,9 @@
 			// value type is changing
 			return false;
 		}
+		if (a == BlankEval.INSTANCE) {
+			return b == a;
+		}
 		if (cls == NumberEval.class) {
 			return ((NumberEval)a).getNumberValue() == ((NumberEval)b).getNumberValue();
 		}

Modified: poi/branches/ooxml/src/java/org/apache/poi/ss/formula/CellLocation.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/java/org/apache/poi/ss/formula/CellLocation.java?rev=703069&r1=703068&r2=703069&view=diff
==============================================================================
--- poi/branches/ooxml/src/java/org/apache/poi/ss/formula/CellLocation.java (original)
+++ poi/branches/ooxml/src/java/org/apache/poi/ss/formula/CellLocation.java Wed Oct  8 23:38:50 2008
@@ -25,24 +25,24 @@
 final class CellLocation {
 	public static final CellLocation[] EMPTY_ARRAY = { };
 	
-	private final EvaluationWorkbook _book;
+	private final int _bookIx;
 	private final int _sheetIndex;
 	private final int _rowIndex;
 	private final int _columnIndex;
 	private final int _hashCode;
 
-	public CellLocation(EvaluationWorkbook book, int sheetIndex, int rowIndex, int columnIndex) {
+	public CellLocation(int bookIx, int sheetIndex, int rowIndex, int columnIndex) {
 		if (sheetIndex < 0) {
 			throw new IllegalArgumentException("sheetIndex must not be negative");
 		}
-		_book = book;
+		_bookIx = bookIx;
 		_sheetIndex = sheetIndex;
 		_rowIndex = rowIndex;
 		_columnIndex = columnIndex;
-		_hashCode = System.identityHashCode(book) + sheetIndex + 17 * (rowIndex + 17 * columnIndex);
+		_hashCode = _bookIx + 17 * (sheetIndex + 17 * (rowIndex + 17 * columnIndex));
 	}
-	public Object getBook() {
-		return _book;
+	public int getBookIndex() {
+		return _bookIx;
 	}
 	public int getSheetIndex() {
 		return _sheetIndex;
@@ -65,7 +65,7 @@
 		if (getSheetIndex() != other.getSheetIndex()) {
 			return false;
 		}
-		if (getBook() != other.getBook()) {
+		if (getBookIndex() != other.getBookIndex()) {
 			return false;
 		}
 		return true;

Modified: poi/branches/ooxml/src/java/org/apache/poi/ss/formula/CollaboratingWorkbooksEnvironment.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/java/org/apache/poi/ss/formula/CollaboratingWorkbooksEnvironment.java?rev=703069&r1=703068&r2=703069&view=diff
==============================================================================
--- poi/branches/ooxml/src/java/org/apache/poi/ss/formula/CollaboratingWorkbooksEnvironment.java (original)
+++ poi/branches/ooxml/src/java/org/apache/poi/ss/formula/CollaboratingWorkbooksEnvironment.java Wed Oct  8 23:38:50 2008
@@ -97,7 +97,7 @@
 		EvaluationCache cache = new EvaluationCache(evalListener);
 		
 		for(int i=0; i<nItems; i++) {
-			evaluators[i].attachToEnvironment(env, cache);
+			evaluators[i].attachToEnvironment(env, cache, i);
 		}
 		
 	}

Modified: poi/branches/ooxml/src/java/org/apache/poi/ss/formula/EvaluationCache.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/java/org/apache/poi/ss/formula/EvaluationCache.java?rev=703069&r1=703068&r2=703069&view=diff
==============================================================================
--- poi/branches/ooxml/src/java/org/apache/poi/ss/formula/EvaluationCache.java (original)
+++ poi/branches/ooxml/src/java/org/apache/poi/ss/formula/EvaluationCache.java Wed Oct  8 23:38:50 2008
@@ -203,7 +203,7 @@
 			CellLocation clB = (CellLocation) b;
 			
 			int cmp;
-			cmp = System.identityHashCode(clA.getBook()) - System.identityHashCode(clB.getBook());
+			cmp = clA.getBookIndex() - clB.getBookIndex();
 			if (cmp != 0) {
 				return cmp;
 			}

Modified: poi/branches/ooxml/src/java/org/apache/poi/ss/formula/WorkbookEvaluator.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/java/org/apache/poi/ss/formula/WorkbookEvaluator.java?rev=703069&r1=703068&r2=703069&view=diff
==============================================================================
--- poi/branches/ooxml/src/java/org/apache/poi/ss/formula/WorkbookEvaluator.java (original)
+++ poi/branches/ooxml/src/java/org/apache/poi/ss/formula/WorkbookEvaluator.java Wed Oct  8 23:38:50 2008
@@ -80,6 +80,7 @@
 
 	private final EvaluationWorkbook _workbook;
 	private EvaluationCache _cache;
+	private int _workbookIx;
 
 	private final IEvaluationListener _evaluationListener;
 	private final Map _sheetIndexesBySheet;
@@ -94,6 +95,7 @@
 		_cache = new EvaluationCache(evaluationListener);
 		_sheetIndexesBySheet = new IdentityHashMap();
 		_collaboratingWorkbookEnvironment = CollaboratingWorkbooksEnvironment.EMPTY;
+		_workbookIx = 0;
 	}
 
 	/**
@@ -111,9 +113,10 @@
 			System.out.println(s);
 		}
 	}
-	/* package */ void attachToEnvironment(CollaboratingWorkbooksEnvironment collaboratingWorkbooksEnvironment, EvaluationCache cache) {
+	/* package */ void attachToEnvironment(CollaboratingWorkbooksEnvironment collaboratingWorkbooksEnvironment, EvaluationCache cache, int workbookIx) {
 		_collaboratingWorkbookEnvironment = collaboratingWorkbooksEnvironment;
 		_cache = cache;
+		_workbookIx = workbookIx;
 	}
 	/* package */ CollaboratingWorkbooksEnvironment getEnvironment() {
 		return _collaboratingWorkbookEnvironment;
@@ -122,6 +125,7 @@
 	/* package */ void detachFromEnvironment() {
 		_collaboratingWorkbookEnvironment = CollaboratingWorkbooksEnvironment.EMPTY;
 		_cache = new EvaluationCache(_evaluationListener);
+		_workbookIx = 0;
 	}
 	/* package */ IEvaluationListener getEvaluationListener() {
 		return _evaluationListener;
@@ -148,7 +152,7 @@
 			throw new IllegalArgumentException("value must not be null");
 		}
 		int sheetIndex = getSheetIndex(sheet);
-		_cache.setValue(new CellLocation(_workbook, sheetIndex, rowIndex, columnIndex), true, CellLocation.EMPTY_ARRAY, value);
+		_cache.setValue(getCellLoc(sheetIndex, rowIndex, columnIndex), true, CellLocation.EMPTY_ARRAY, value);
 
 	}
 	/**
@@ -157,7 +161,7 @@
 	 */
 	public void notifySetFormula(Sheet sheet, int rowIndex, int columnIndex) {
 		int sheetIndex = getSheetIndex(sheet);
-		_cache.setValue(new CellLocation(_workbook, sheetIndex, rowIndex, columnIndex), false, CellLocation.EMPTY_ARRAY, null);
+		_cache.setValue(getCellLoc(sheetIndex, rowIndex, columnIndex), false, CellLocation.EMPTY_ARRAY, null);
 
 	}
 	private int getSheetIndex(Sheet sheet) {
@@ -175,7 +179,7 @@
 
 	public ValueEval evaluate(Cell srcCell) {
 		int sheetIndex = getSheetIndex(srcCell.getSheet());
-		CellLocation cellLoc = new CellLocation(_workbook, sheetIndex, srcCell.getRowIndex(), srcCell.getCellNum());
+		CellLocation cellLoc = getCellLoc(sheetIndex, srcCell.getRowIndex(), srcCell.getCellNum());
 		return internalEvaluate(srcCell, cellLoc, new EvaluationTracker(_cache));
 	}
 
@@ -471,8 +475,11 @@
 		} else {
 			cell = row.getCell(columnIndex);
  		}
-		CellLocation cellLoc = new CellLocation(_workbook, sheetIndex, rowIndex, columnIndex);
+		CellLocation cellLoc = getCellLoc(sheetIndex, rowIndex, columnIndex);
 		tracker.acceptDependency(cellLoc);
 		return internalEvaluate(cell, cellLoc, tracker);
 	}
+	private CellLocation getCellLoc(int sheetIndex, int rowIndex, int columnIndex) {
+		return new CellLocation(_workbookIx, sheetIndex, rowIndex, columnIndex);
+	}
 }

Modified: poi/branches/ooxml/src/java/org/apache/poi/util/LittleEndian.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/java/org/apache/poi/util/LittleEndian.java?rev=703069&r1=703068&r2=703069&view=diff
==============================================================================
--- poi/branches/ooxml/src/java/org/apache/poi/util/LittleEndian.java (original)
+++ poi/branches/ooxml/src/java/org/apache/poi/util/LittleEndian.java Wed Oct  8 23:38:50 2008
@@ -251,20 +251,6 @@
     }
 
     /**
-     *  put a array of shorts into a byte array
-     *
-     *@param  data    the byte array
-     *@param  offset  a starting offset into the byte array
-     *@param  value   the short array
-     */
-    public static void putShortArray(final byte[] data, final int offset, final short[] value) {
-        putNumber(data, offset, value.length, SHORT_SIZE);
-        for (int i = 0; i < value.length; i++) {
-            putNumber(data, offset + 2 + (i * 2), value[i], SHORT_SIZE);
-        }
-    }
-
-    /**
      * put an unsigned short value into a byte array
      *
      * @param data the byte array

Modified: poi/branches/ooxml/src/scratchpad/src/org/apache/poi/hslf/model/Table.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/scratchpad/src/org/apache/poi/hslf/model/Table.java?rev=703069&r1=703068&r2=703069&view=diff
==============================================================================
--- poi/branches/ooxml/src/scratchpad/src/org/apache/poi/hslf/model/Table.java (original)
+++ poi/branches/ooxml/src/scratchpad/src/org/apache/poi/hslf/model/Table.java Wed Oct  8 23:38:50 2008
@@ -53,6 +53,9 @@
     public Table(int numrows, int numcols) {
         super();
 
+        if(numrows < 1) throw new IllegalArgumentException("The number of rows must be greater than 1");
+        if(numcols < 1) throw new IllegalArgumentException("The number of columns must be greater than 1");
+
         int x=0, y=0, tblWidth=0, tblHeight=0;
         cells = new TableCell[numrows][numcols];
         for (int i = 0; i < cells.length; i++) {
@@ -165,11 +168,11 @@
                 Rectangle anchor = sh[i].getAnchor();
                 if(anchor.y != y0){
                     y0 = anchor.y;
-                    if(row != null) maxrowlen = Math.max(maxrowlen, row.size());
                     row = new ArrayList();
                     lst.add(row);
                 }
                 row.add(sh[i]);
+                maxrowlen = Math.max(maxrowlen, row.size());
             }
         }
         cells = new TableCell[lst.size()][maxrowlen];

Modified: poi/branches/ooxml/src/scratchpad/src/org/apache/poi/hslf/model/TextShape.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/scratchpad/src/org/apache/poi/hslf/model/TextShape.java?rev=703069&r1=703068&r2=703069&view=diff
==============================================================================
--- poi/branches/ooxml/src/scratchpad/src/org/apache/poi/hslf/model/TextShape.java (original)
+++ poi/branches/ooxml/src/scratchpad/src/org/apache/poi/hslf/model/TextShape.java Wed Oct  8 23:38:50 2008
@@ -547,4 +547,31 @@
         return (OEPlaceholderAtom)getClientDataRecord(RecordTypes.OEPlaceholderAtom.typeID);
     }
 
+    /**
+     *
+     * Assigns a hyperlink to this text shape
+     *
+     * @param linkId    id of the hyperlink, @see org.apache.poi.hslf.usermodel.SlideShow#addHyperlink(Hyperlink)
+     * @param      beginIndex   the beginning index, inclusive.
+     * @param      endIndex     the ending index, exclusive.
+     * @see org.apache.poi.hslf.usermodel.SlideShow#addHyperlink(Hyperlink)
+     */
+    public void setHyperlink(int linkId, int beginIndex, int endIndex){
+        //TODO validate beginIndex and endIndex and throw IllegalArgumentException
+
+        InteractiveInfo info = new InteractiveInfo();
+        InteractiveInfoAtom infoAtom = info.getInteractiveInfoAtom();
+        infoAtom.setAction(InteractiveInfoAtom.ACTION_HYPERLINK);
+        infoAtom.setHyperlinkType(InteractiveInfoAtom.LINK_Url);
+        infoAtom.setHyperlinkID(linkId);
+
+        _txtbox.appendChildRecord(info);
+
+        TxInteractiveInfoAtom txiatom = new TxInteractiveInfoAtom();
+        txiatom.setStartIndex(beginIndex);
+        txiatom.setEndIndex(endIndex);
+        _txtbox.appendChildRecord(txiatom);
+
+    }
+
 }

Modified: poi/branches/ooxml/src/scratchpad/src/org/apache/poi/hslf/record/TxInteractiveInfoAtom.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/scratchpad/src/org/apache/poi/hslf/record/TxInteractiveInfoAtom.java?rev=703069&r1=703068&r2=703069&view=diff
==============================================================================
--- poi/branches/ooxml/src/scratchpad/src/org/apache/poi/hslf/record/TxInteractiveInfoAtom.java (original)
+++ poi/branches/ooxml/src/scratchpad/src/org/apache/poi/hslf/record/TxInteractiveInfoAtom.java Wed Oct  8 23:38:50 2008
@@ -40,7 +40,7 @@
     /**
      * Constructs a brand new link related atom record.
      */
-    protected TxInteractiveInfoAtom() {
+    public TxInteractiveInfoAtom() {
         _header = new byte[8];
         _data = new byte[8];
 

Modified: poi/branches/ooxml/src/scratchpad/testcases/org/apache/poi/hslf/model/TestTable.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/scratchpad/testcases/org/apache/poi/hslf/model/TestTable.java?rev=703069&r1=703068&r2=703069&view=diff
==============================================================================
--- poi/branches/ooxml/src/scratchpad/testcases/org/apache/poi/hslf/model/TestTable.java (original)
+++ poi/branches/ooxml/src/scratchpad/testcases/org/apache/poi/hslf/model/TestTable.java Wed Oct  8 23:38:50 2008
@@ -60,4 +60,40 @@
         assertEquals(tbl.getNumberOfRows(), tbl3.getNumberOfRows());
     }
 
+    /**
+     * Error constructing Table when rownum=1
+     */
+    public void test45889(){
+        SlideShow ppt = new SlideShow();
+        Slide slide = ppt.createSlide();
+        Shape[] shapes;
+        Table tbl1 = new Table(1, 5);
+        assertEquals(5, tbl1.getNumberOfColumns());
+        assertEquals(1, tbl1.getNumberOfRows());
+        slide.addShape(tbl1);
+
+        shapes = slide.getShapes();
+        assertEquals(1, shapes.length);
+
+        Table tbl2 = (Table)shapes[0];
+        assertSame(tbl1.getSpContainer(), tbl2.getSpContainer());
+
+        assertEquals(tbl1.getNumberOfColumns(), tbl2.getNumberOfColumns());
+        assertEquals(tbl1.getNumberOfRows(), tbl2.getNumberOfRows());
+    }
+
+    public void testIllegalCOnstruction(){
+        try {
+            Table tbl = new Table(0, 5);
+            fail("Table(rownum, colnum) must throw IllegalArgumentException if any of tghe arguments is less than 1");
+        } catch (IllegalArgumentException e){
+
+        }
+        try {
+            Table tbl = new Table(5, 0);
+            fail("Table(rownum, colnum) must throw IllegalArgumentException if any of tghe arguments is less than 1");
+        } catch (IllegalArgumentException e){
+
+        }
+    }
 }

Modified: poi/branches/ooxml/src/testcases/org/apache/poi/hssf/record/TestEmbeddedObjectRefSubRecord.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/testcases/org/apache/poi/hssf/record/TestEmbeddedObjectRefSubRecord.java?rev=703069&r1=703068&r2=703069&view=diff
==============================================================================
--- poi/branches/ooxml/src/testcases/org/apache/poi/hssf/record/TestEmbeddedObjectRefSubRecord.java (original)
+++ poi/branches/ooxml/src/testcases/org/apache/poi/hssf/record/TestEmbeddedObjectRefSubRecord.java Wed Oct  8 23:38:50 2008
@@ -16,13 +16,13 @@
 ==================================================================== */
 package org.apache.poi.hssf.record;
 
-import junit.framework.TestCase;
-import org.apache.poi.util.HexRead;
-
-import java.io.IOException;
 import java.io.ByteArrayInputStream;
 import java.util.Arrays;
 
+import junit.framework.TestCase;
+
+import org.apache.poi.util.HexRead;
+
 /**
  * Tests the serialization and deserialization of the TestEmbeddedObjectRefSubRecord
  * class works correctly.  Test data taken directly from a real
@@ -30,53 +30,111 @@
  *
  * @author Yegor Kozlov
  */
-public class TestEmbeddedObjectRefSubRecord extends TestCase {
-
-    String data1 = "[20, 00, 05, 00, FC, 10, 76, 01, 02, 24, 14, DF, 00, 03, 10, 00, 00, 46, 6F, 72, 6D, 73, 2E, 43, 68, 65, 63, 6B, 42, 6F, 78, 2E, 31, 00, 00, 00, 00, 00, 70, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, ]";
-
-    public void testStore() throws IOException {
-
-        byte[] src = HexRead.readFromString(data1);
-        src = TestcaseRecordInputStream.mergeDataAndSid(EmbeddedObjectRefSubRecord.sid, (short)src.length, src);
-
-        RecordInputStream in = new RecordInputStream(new ByteArrayInputStream(src));
-        in.nextRecord();
-
-        EmbeddedObjectRefSubRecord record1 = new EmbeddedObjectRefSubRecord(in);
-
-        byte[] ser = record1.serialize();
-
-        RecordInputStream in2 = new RecordInputStream(new ByteArrayInputStream(ser));
-        in2.nextRecord();
-        EmbeddedObjectRefSubRecord record2 = new EmbeddedObjectRefSubRecord(in2);
-
-        assertTrue(Arrays.equals(src, ser));
-        assertEquals(record1.field_1_stream_id_offset, record2.field_1_stream_id_offset);
-        assertTrue(Arrays.equals(record1.field_2_unknown, record2.field_2_unknown));
-        assertEquals(record1.field_3_unicode_len, record2.field_3_unicode_len);
-        assertEquals(record1.field_4_unicode_flag, record2.field_4_unicode_flag);
-        assertEquals(record1.field_5_ole_classname, record2.field_5_ole_classname);
-        assertEquals(record1.field_6_stream_id, record2.field_6_stream_id);
-        assertTrue(Arrays.equals(record1.remainingBytes, record2.remainingBytes));
-    }
-
-    public void testCreate() throws IOException {
-
+public final class TestEmbeddedObjectRefSubRecord extends TestCase {
 
-        EmbeddedObjectRefSubRecord record1 = new EmbeddedObjectRefSubRecord();
+	String data1 = "[20, 00, 05, 00, FC, 10, 76, 01, 02, 24, 14, DF, 00, 03, 10, 00, 00, 46, 6F, 72, 6D, 73, 2E, 43, 68, 65, 63, 6B, 42, 6F, 78, 2E, 31, 00, 00, 00, 00, 00, 70, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, ]";
 
-        byte[] ser = record1.serialize();
-        RecordInputStream in2 = new RecordInputStream(new ByteArrayInputStream(ser));
-        in2.nextRecord();
-        EmbeddedObjectRefSubRecord record2 = new EmbeddedObjectRefSubRecord(in2);
+	public void testStore() {
 
-        assertEquals(record1.field_1_stream_id_offset, record2.field_1_stream_id_offset);
-        assertTrue(Arrays.equals(record1.field_2_unknown, record2.field_2_unknown));
-        assertEquals(record1.field_3_unicode_len, record2.field_3_unicode_len);
-        assertEquals(record1.field_4_unicode_flag, record2.field_4_unicode_flag);
-        assertEquals(record1.field_5_ole_classname, record2.field_5_ole_classname);
-        assertEquals(record1.field_6_stream_id, record2.field_6_stream_id);
-        assertTrue(Arrays.equals(record1.remainingBytes, record2.remainingBytes));
+		byte[] src = hr(data1);
+		src = TestcaseRecordInputStream.mergeDataAndSid(EmbeddedObjectRefSubRecord.sid, (short)src.length, src);
 
-    }
+		RecordInputStream in = new RecordInputStream(new ByteArrayInputStream(src));
+		in.nextRecord();
+
+		EmbeddedObjectRefSubRecord record1 = new EmbeddedObjectRefSubRecord(in);
+
+		byte[] ser = record1.serialize();
+
+		RecordInputStream in2 = new RecordInputStream(new ByteArrayInputStream(ser));
+		in2.nextRecord();
+		EmbeddedObjectRefSubRecord record2 = new EmbeddedObjectRefSubRecord(in2);
+
+		assertTrue(Arrays.equals(src, ser));
+		assertEquals(record1.getOLEClassName(), record2.getOLEClassName());
+
+		byte[] ser2 = record1.serialize();
+		assertTrue(Arrays.equals(ser, ser2));
+	}
+
+	public void testCreate() {
+
+		EmbeddedObjectRefSubRecord record1 = new EmbeddedObjectRefSubRecord();
+
+		byte[] ser = record1.serialize();
+		RecordInputStream in2 = new RecordInputStream(new ByteArrayInputStream(ser));
+		in2.nextRecord();
+		EmbeddedObjectRefSubRecord record2 = new EmbeddedObjectRefSubRecord(in2);
+
+		assertEquals(record1.getOLEClassName(), record2.getOLEClassName());
+		assertEquals(record1.getStreamId(), record2.getStreamId());
+
+		byte[] ser2 = record1.serialize();
+		assertTrue(Arrays.equals(ser, ser2));
+	}
+
+
+	/**
+	 * taken from ftPictFmla sub-record in attachment 22645 (offset 0x40AB).
+	 */
+	private static final byte[] data45912 = hr(
+		"09 00 14 00 " +
+		"12 00 0B 00 F8 02 88 04 3B 00 " +
+		"00 00 00 01 00 00 00 01 " +
+		"00 00");
+
+	public void testCameraTool_bug45912() {
+		byte[] data = data45912;
+		RecordInputStream in = new RecordInputStream(new ByteArrayInputStream(data));
+		in.nextRecord();
+
+		EmbeddedObjectRefSubRecord rec = new EmbeddedObjectRefSubRecord(in);
+		byte[] ser2 = rec.serialize();
+		assertTrue(Arrays.equals(data, ser2));
+
+
+	}
+
+	private static byte[] hr(String string) {
+		return HexRead.readFromString(string);
+	}
+
+	/**
+	 * tests various examples of OLE controls
+	 */
+	public void testVarious() {
+		String[] rawData = {
+			"12 00 0B 00 70 95 0B 05 3B 01 00 36 00 40 00 18 00 19 00 18",
+			"12 00 0B 00 B0 4D 3E 03 3B 00 00 00 00 01 00 00 80 01 C0 00",
+			"0C 00 05 00 60 AF 3B 03 24 FD FF FE C0 FE",
+			"24 00 05 00 40 42 3E 03 02 80 CD B4 04 03 15 00 00 46 6F 72 6D 73 2E 43 6F 6D 6D 61 6E 64 42 75 74 74 6F 6E 2E 31 00 00 00 00 54 00 00 00 00 00 00 00 00 00 00 00",
+			"22 00 05 00 10 4E 3E 03 02 00 4C CC 04 03 12 00 00 46 6F 72 6D 73 2E 53 70 69 6E 42 75 74 74 6F 6E 2E 31 00 54 00 00 00 20 00 00 00 00 00 00 00 00 00 00 00",
+			"20 00 05 00 E0 41 3E 03 02 00 FC 0B 05 03 10 00 00 46 6F 72 6D 73 2E 43 6F 6D 62 6F 42 6F 78 2E 31 00 74 00 00 00 4C 00 00 00 00 00 00 00 00 00 00 00",
+			"24 00 05 00 00 4C AF 03 02 80 E1 93 05 03 14 00 00 46 6F 72 6D 73 2E 4F 70 74 69 6F 6E 42 75 74 74 6F 6E 2E 31 00 C0 00 00 00 70 00 00 00 00 00 00 00 00 00 00 00",
+			"20 00 05 00 E0 A4 28 04 02 80 EA 93 05 03 10 00 00 46 6F 72 6D 73 2E 43 68 65 63 6B 42 6F 78 2E 31 00 30 01 00 00 6C 00 00 00 00 00 00 00 00 00 00 00",
+			"1C 00 05 00 30 40 3E 03 02 00 CC B4 04 03 0D 00 00 46 6F 72 6D 73 2E 4C 61 62 65 6C 2E 31 9C 01 00 00 54 00 00 00 00 00 00 00 00 00 00 00",
+			"1E 00 05 00 B0 A4 28 04 02 00 D0 0A 05 03 0F 00 00 46 6F 72 6D 73 2E 4C 69 73 74 42 6F 78 2E 31 F0 01 00 00 48 00 00 00 00 00 00 00 00 00 00 00",
+			"24 00 05 00 C0 AF 3B 03 02 80 D1 0A 05 03 14 00 00 46 6F 72 6D 73 2E 54 6F 67 67 6C 65 42 75 74 74 6F 6E 2E 31 00 38 02 00 00 6C 00 00 00 00 00 00 00 00 00 00 00",
+			"1E 00 05 00 90 AF 3B 03 02 80 D4 0A 05 03 0F 00 00 46 6F 72 6D 73 2E 54 65 78 74 42 6F 78 2E 31 A4 02 00 00 48 00 00 00 00 00 00 00 00 00 00 00",
+			"24 00 05 00 60 40 3E 03 02 00 D6 0A 05 03 14 00 00 46 6F 72 6D 73 2E 54 6F 67 67 6C 65 42 75 74 74 6F 6E 2E 31 00 EC 02 00 00 6C 00 00 00 00 00 00 00 00 00 00 00",
+			"20 00 05 00 20 4D 3E 03 02 00 D9 0A 05 03 11 00 00 46 6F 72 6D 73 2E 53 63 72 6F 6C 6C 42 61 72 2E 31 58 03 00 00 20 00 00 00 00 00 00 00 00 00 00 00",
+			"20 00 05 00 00 AF 28 04 02 80 31 AC 04 03 10 00 00 53 68 65 6C 6C 2E 45 78 70 6C 6F 72 65 72 2E 32 00 78 03 00 00 AC 00 00 00 00 00 00 00 00 00 00 00",
+		};
+
+		for (int i = 0; i < rawData.length; i++) {
+			confirmRead(hr(rawData[i]), i);
+		}
+	}
+
+	private static void confirmRead(byte[] data, int i) {
+		RecordInputStream in = new TestcaseRecordInputStream(EmbeddedObjectRefSubRecord.sid, (short)data.length, data);
+
+		EmbeddedObjectRefSubRecord rec = new EmbeddedObjectRefSubRecord(in);
+		byte[] ser2 = rec.serialize();
+		byte[] d2 = (byte[]) data.clone(); // remove sid+len for compare
+		System.arraycopy(ser2, 4, d2, 0, d2.length);
+		if (!Arrays.equals(data, d2)) {
+			fail("re-read NQR for case " + i);
+		}
+	}
 }

Modified: poi/branches/ooxml/src/testcases/org/apache/poi/hssf/record/TestSeriesListRecord.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/testcases/org/apache/poi/hssf/record/TestSeriesListRecord.java?rev=703069&r1=703068&r2=703069&view=diff
==============================================================================
--- poi/branches/ooxml/src/testcases/org/apache/poi/hssf/record/TestSeriesListRecord.java (original)
+++ poi/branches/ooxml/src/testcases/org/apache/poi/hssf/record/TestSeriesListRecord.java Wed Oct  8 23:38:50 2008
@@ -29,7 +29,7 @@
  * @author Glen Stampoultzis (glens at apache.org)
  */
 public final class TestSeriesListRecord extends TestCase {
-    byte[] data = new byte[] {
+    private static final byte[] data = {
         (byte)0x02,(byte)0x00,(byte)0x01,(byte)0x20,(byte)0xff,(byte)0xf0
     };
 
@@ -43,10 +43,8 @@
         assertEquals( 4 + 6, record.getRecordSize() );
     }
 
-    public void testStore()
-    {
-        SeriesListRecord record = new SeriesListRecord();
-        record.setSeriesNumbers( new short[] { (short)0x2001, (short)0xf0ff } );
+    public void testStore() {
+        SeriesListRecord record = new SeriesListRecord(new short[] { (short)0x2001, (short)0xf0ff } );
 
         byte [] recordBytes = record.serialize();
         assertEquals(recordBytes.length - 4, data.length);

Modified: poi/branches/ooxml/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java?rev=703069&r1=703068&r2=703069&view=diff
==============================================================================
--- poi/branches/ooxml/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java (original)
+++ poi/branches/ooxml/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java Wed Oct  8 23:38:50 2008
@@ -971,7 +971,7 @@
     public void test44840() {
         HSSFWorkbook wb = openSample("WithCheckBoxes.xls");
 
-        // Take a look at the embeded objects
+        // Take a look at the embedded objects
         List objects = wb.getAllEmbeddedObjects();
         assertEquals(1, objects.size());
 
@@ -982,10 +982,10 @@
         EmbeddedObjectRefSubRecord rec = obj.findObjectRecord();
         assertNotNull(rec);
 
-        assertEquals(32, rec.field_1_stream_id_offset);
-        assertEquals(0, rec.field_6_stream_id); // WRONG!
-        assertEquals("Forms.CheckBox.1", rec.field_5_ole_classname);
-        assertEquals(12, rec.remainingBytes.length);
+//        assertEquals(32, rec.field_1_stream_id_offset);
+        assertEquals(0, rec.getStreamId().intValue()); // WRONG!
+        assertEquals("Forms.CheckBox.1", rec.getOLEClassName());
+        assertEquals(12, rec.getObjectData().length);
 
         // Doesn't have a directory
         assertFalse(obj.hasDirectoryEntry());
@@ -997,7 +997,7 @@
             obj.getDirectory();
             fail();
         } catch(FileNotFoundException e) {
-            // expectd during successful test
+            // expected during successful test
         } catch (IOException e) {
             throw new RuntimeException(e);
         }

Modified: poi/branches/ooxml/src/testcases/org/apache/poi/ss/formula/AllSSFormulaTests.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/testcases/org/apache/poi/ss/formula/AllSSFormulaTests.java?rev=703069&r1=703068&r2=703069&view=diff
==============================================================================
--- poi/branches/ooxml/src/testcases/org/apache/poi/ss/formula/AllSSFormulaTests.java (original)
+++ poi/branches/ooxml/src/testcases/org/apache/poi/ss/formula/AllSSFormulaTests.java Wed Oct  8 23:38:50 2008
@@ -26,9 +26,10 @@
  */
 public final class AllSSFormulaTests {
     public static Test suite() {
-        TestSuite result = new TestSuite(AllSSFormulaTests.class.getName());
-        result.addTestSuite(TestEvaluationCache.class);
-        result.addTestSuite(TestWorkbookEvaluator.class);
-        return result;
-    }
+		TestSuite result = new TestSuite(AllSSFormulaTests.class.getName());
+		result.addTestSuite(TestCellCacheEntry.class);
+		result.addTestSuite(TestEvaluationCache.class);
+		result.addTestSuite(TestWorkbookEvaluator.class);
+		return result;
+	}
 }



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


Mime
View raw message