poi-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ye...@apache.org
Subject svn commit: r890871 - in /poi/trunk/src: documentation/content/xdocs/status.xml java/org/apache/poi/hssf/record/ExternalNameRecord.java testcases/org/apache/poi/hssf/record/TestExternalNameRecord.java
Date Tue, 15 Dec 2009 16:25:15 GMT
Author: yegor
Date: Tue Dec 15 16:25:14 2009
New Revision: 890871

URL: http://svn.apache.org/viewvc?rev=890871&view=rev
Log:
fixed ExternalNameRecord to properly distinguish DDE data from OLE data in the record body,
see Bugzilla 48339 

Modified:
    poi/trunk/src/documentation/content/xdocs/status.xml
    poi/trunk/src/java/org/apache/poi/hssf/record/ExternalNameRecord.java
    poi/trunk/src/testcases/org/apache/poi/hssf/record/TestExternalNameRecord.java

Modified: poi/trunk/src/documentation/content/xdocs/status.xml
URL: http://svn.apache.org/viewvc/poi/trunk/src/documentation/content/xdocs/status.xml?rev=890871&r1=890870&r2=890871&view=diff
==============================================================================
--- poi/trunk/src/documentation/content/xdocs/status.xml (original)
+++ poi/trunk/src/documentation/content/xdocs/status.xml Tue Dec 15 16:25:14 2009
@@ -34,6 +34,7 @@
 
     <changes>
         <release version="3.7-SNAPSHOT" date="2010-??-??">
+           <action dev="POI-DEVELOPERS" type="fix">48339 - fixed ExternalNameRecord
to properly distinguish DDE data from OLE data items </action>
            <action dev="POI-DEVELOPERS" type="fix">47920 - allow editing workbooks
embedded into PowerPoint files</action>
            <action dev="POI-DEVELOPERS" type="add">48343 - added implementation of
SUBTOTAL function</action>
         </release>

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/ExternalNameRecord.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/ExternalNameRecord.java?rev=890871&r1=890870&r2=890871&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/ExternalNameRecord.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/ExternalNameRecord.java Tue Dec 15 16:25:14
2009
@@ -34,15 +34,14 @@
 	private static final int OPT_BUILTIN_NAME          = 0x0001;
 	private static final int OPT_AUTOMATIC_LINK        = 0x0002; // m$ doc calls this fWantAdvise
 	private static final int OPT_PICTURE_LINK          = 0x0004;
-	private static final int OPT_STD_DOCUMENT_NAME     = 0x0008;
-	private static final int OPT_OLE_LINK              = 0x0010;
+	private static final int OPT_STD_DOCUMENT_NAME     = 0x0008; //fOle
+	private static final int OPT_OLE_LINK              = 0x0010; //fOleLink
 //	private static final int OPT_CLIP_FORMAT_MASK      = 0x7FE0;
 	private static final int OPT_ICONIFIED_PICTURE_LINK= 0x8000;
 
 
 	private short  field_1_option_flag;
-	private short  field_2_index;
-	private short  field_3_not_used;
+	private int  field_2_not_used;
 	private String field_4_name;
 	private Formula  field_5_name_definition;
 
@@ -99,109 +98,67 @@
 	}
 
 	protected int getDataSize(){
-		int result = 3 * 2  // 3 short fields
-			+ 2 + field_4_name.length(); // nameLen and name
-		if(hasFormula()) {
-			result += field_5_name_definition.getEncodedSize();
-		} else {
-			if (_ddeValues != null) {
-				result += 3; // byte, short
-				result += ConstantValueParser.getEncodedSize(_ddeValues);
-			}
-		}
+		int result = 2 + 4;  // short and int
+        result += StringUtil.getEncodedSize(field_4_name) - 1; //size is byte, not short

+
+        if(!isOLELink() && !isStdDocumentNameIdentifier()){
+            if(isAutomaticLink()){
+                result += 3; // byte, short
+                result += ConstantValueParser.getEncodedSize(_ddeValues);
+            } else {
+                result += field_5_name_definition.getEncodedSize();
+            }
+        }
 		return result;
 	}
 
 	public void serialize(LittleEndianOutput out) {
 		out.writeShort(field_1_option_flag);
-		out.writeShort(field_2_index);
-		out.writeShort(field_3_not_used);
-		int nameLen = field_4_name.length();
-		out.writeShort(nameLen);
-		StringUtil.putCompressedUnicode(field_4_name, out);
-		if (hasFormula()) {
-			field_5_name_definition.serialize(out);
-		} else {
-			if (_ddeValues != null) {
-				out.writeByte(_nColumns-1);
-				out.writeShort(_nRows-1);
-				ConstantValueParser.encode(out, _ddeValues);
-			}
-		}
+		out.writeInt(field_2_not_used);
+
+        out.writeByte(field_4_name.length());
+        StringUtil.writeUnicodeStringFlagAndData(out, field_4_name);
+
+        if(!isOLELink() && !isStdDocumentNameIdentifier()){
+            if(isAutomaticLink()){
+                out.writeByte(_nColumns-1);
+                out.writeShort(_nRows-1);
+                ConstantValueParser.encode(out, _ddeValues);
+            } else {
+                field_5_name_definition.serialize(out);
+            }
+        }
 	}
 
 
 	public ExternalNameRecord(RecordInputStream in) {
 		field_1_option_flag = in.readShort();
-		field_2_index       = in.readShort();
-		field_3_not_used    = in.readShort();
-		int nameLength = in.readUByte();
-		int multibyteFlag = in.readUByte();
-		if (multibyteFlag == 0) {
-			field_4_name = in.readCompressedUnicode(nameLength);
-		} else {
-			field_4_name = in.readUnicodeLEString(nameLength);
-		}
-		if(!hasFormula()) {
-			if (!isStdDocumentNameIdentifier() && !isOLELink() && isAutomaticLink())
{
-				// both need to be incremented
-				int nColumns = in.readUByte() + 1;
-				int nRows = in.readShort() + 1;
-
-				int totalCount = nRows * nColumns;
-				_ddeValues = ConstantValueParser.parse(in, totalCount);
-				_nColumns = nColumns;
-				_nRows = nRows;
-			}
-			if(in.remaining() > 0) {
-				throw readFail("Some unread data (is formula present?)");
-			}
-			field_5_name_definition = null;
-			return;
-		}
-		int nBytesRemaining = in.available();
-		if(nBytesRemaining <= 0) {
-			throw readFail("Ran out of record data trying to read formula.");
-		}
-		int formulaLen = in.readUShort();
-		nBytesRemaining -=2;
-		field_5_name_definition = Formula.read(formulaLen, in, nBytesRemaining);
-	}
-	/*
-	 * Makes better error messages (while hasFormula() is not reliable)
-	 * Remove this when hasFormula() is stable.
-	 */
-	private RuntimeException readFail(String msg) {
-		String fullMsg = msg + " fields: (option=" + field_1_option_flag + " index=" + field_2_index
-		+ " not_used=" + field_3_not_used + " name='" + field_4_name + "')";
-		return new RecordFormatException(fullMsg);
-	}
-
-	private boolean hasFormula() {
-		// TODO - determine exact conditions when formula is present
-		if (false) {
-			// "Microsoft Office Excel 97-2007 Binary File Format (.xls) Specification"
-			// m$'s document suggests logic like this, but bugzilla 44774 att 21790 seems to disagree
-			if (isStdDocumentNameIdentifier()) {
-				if (isOLELink()) {
-					// seems to be not possible according to m$ document
-					throw new IllegalStateException(
-							"flags (std-doc-name and ole-link) cannot be true at the same time");
-				}
-				return false;
-			}
-			if (isOLELink()) {
-				return false;
-			}
-			return true;
-		}
-
-		// This was derived by trial and error, but doesn't seem quite right
-		if (isAutomaticLink()) {
-			return false;
-		}
-		return true;
-	}
+		field_2_not_used    = in.readInt();
+
+        int numChars = in.readUByte();
+        field_4_name = StringUtil.readUnicodeString(in, numChars);
+
+        // the record body can take different forms.
+        // The form is dictated by the values of 3-th and 4-th bits in field_1_option_flag
+        if(!isOLELink() && !isStdDocumentNameIdentifier()){
+            // another switch: the fWantAdvise bit specifies whether the body describes
+            // an external defined name or a DDE data item
+            if(isAutomaticLink()){
+                //body specifies DDE data item
+                int nColumns = in.readUByte() + 1;
+                int nRows = in.readShort() + 1;
+
+                int totalCount = nRows * nColumns;
+                _ddeValues = ConstantValueParser.parse(in, totalCount);
+                _nColumns = nColumns;
+                _nRows = nRows;
+            } else {
+                //body specifies an external defined name
+                int formulaLen = in.readUShort();
+                field_5_name_definition = Formula.read(formulaLen, in);
+            }
+        }
+    }
 
 	public short getSid() {
 		return sid;
@@ -211,7 +168,7 @@
 		StringBuffer sb = new StringBuffer();
 		sb.append(getClass().getName()).append(" [EXTERNALNAME ");
 		sb.append(" ").append(field_4_name);
-		sb.append(" ix=").append(field_2_index);
+		sb.append(" ix=").append(field_2_not_used);
 		sb.append("]");
 		return sb.toString();
 	}

Modified: poi/trunk/src/testcases/org/apache/poi/hssf/record/TestExternalNameRecord.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/hssf/record/TestExternalNameRecord.java?rev=890871&r1=890870&r2=890871&view=diff
==============================================================================
--- poi/trunk/src/testcases/org/apache/poi/hssf/record/TestExternalNameRecord.java (original)
+++ poi/trunk/src/testcases/org/apache/poi/hssf/record/TestExternalNameRecord.java Tue Dec
15 16:25:14 2009
@@ -18,6 +18,7 @@
 package org.apache.poi.hssf.record;
 
 import org.apache.poi.util.HexRead;
+import org.apache.poi.util.HexDump;
 
 import junit.framework.AssertionFailedError;
 import junit.framework.TestCase;
@@ -156,5 +157,19 @@
 			throw e;
 		}
 		assertEquals("\u0159azen\u00ED_Billa", enr.getText());
+        byte[] ser = enr.serialize();
+        assertEquals(HexDump.toHex(dataUN), HexDump.toHex(ser));
 	}
+
+    public void test48339() {
+        // data taken from bugzilla 48339
+        byte[] data = HexRead.readFromString(
+                "23 00 09 00" +
+                "F4, FF, 14, 2D, 61, 01, 01, 00, 27");
+
+        RecordInputStream in = TestcaseRecordInputStream.create(data);
+        ExternalNameRecord enr = new ExternalNameRecord(in);
+        byte[] ser = enr.serialize();
+        assertEquals(HexDump.toHex(data), HexDump.toHex(ser));
+    }
 }



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


Mime
View raw message