]> source.dussan.org Git - poi.git/commitdiff
Bugzilla 47229 - Fixed ExternalNameRecord to handle DDE links
authorJosh Micich <josh@apache.org>
Thu, 21 May 2009 21:41:47 +0000 (21:41 +0000)
committerJosh Micich <josh@apache.org>
Thu, 21 May 2009 21:41:47 +0000 (21:41 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@777275 13f79535-47bb-0310-9956-ffa450edef68

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

index 158f096d09b5b9e423f1906d9fe829fe4e82fcbb..4411ea6f6e94120f1e045231586544d0655fe475 100644 (file)
@@ -37,6 +37,7 @@
 
                <!-- Don't forget to update status.xml too! -->
         <release version="3.5-beta6" date="2009-??-??">
+           <action dev="POI-DEVELOPERS" type="add">47229 - Fixed ExternalNameRecord to handle DDE links</action>
            <action dev="POI-DEVELOPERS" type="add">46287 - Control of header and footer extraction in ExcelExtractor / XSSFExcelExtractor</action>
            <action dev="POI-DEVELOPERS" type="add">46554 - New ant target "jar-examples"</action>
            <action dev="POI-DEVELOPERS" type="add">46161 - Support in XSSF for setGroupColumnCollapsed and setGroupRowCollapsed</action>
index 84f815edcbbb0f31afaaec8e68cf71a162b32fe5..b46e086a671bc2cd8df75684f6f28211ac131dd0 100644 (file)
@@ -34,6 +34,7 @@
        <!-- Don't forget to update changes.xml too! -->
     <changes>
         <release version="3.5-beta6" date="2009-??-??">
+           <action dev="POI-DEVELOPERS" type="add">47229 - Fixed ExternalNameRecord to handle DDE links</action>
            <action dev="POI-DEVELOPERS" type="add">46287 - Control of header and footer extraction in ExcelExtractor / XSSFExcelExtractor</action>
            <action dev="POI-DEVELOPERS" type="add">46554 - New ant target "jar-examples"</action>
            <action dev="POI-DEVELOPERS" type="add">46161 - Support in XSSF for setGroupColumnCollapsed and setGroupRowCollapsed</action>
index 1233ab44231c5b99c67713fa6781f7d646aad804..0ac34880d574e227ef521c0b8f063aa1e1f6481d 100755 (executable)
 
 package org.apache.poi.hssf.record;
 
+import org.apache.poi.hssf.record.constant.ConstantValueParser;
 import org.apache.poi.ss.formula.Formula;
-import org.apache.poi.util.LittleEndianByteArrayOutputStream;
 import org.apache.poi.util.LittleEndianOutput;
 import org.apache.poi.util.StringUtil;
 
 /**
  * EXTERNALNAME (0x0023)<p/>
- * 
+ *
  * @author Josh Micich
  */
 public final class ExternalNameRecord extends StandardRecord {
@@ -32,7 +32,7 @@ public final class ExternalNameRecord extends StandardRecord {
        public final static short sid = 0x0023; // as per BIFF8. (some old versions used 0x223)
 
        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_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;
@@ -46,6 +46,21 @@ public final class ExternalNameRecord extends StandardRecord {
        private String field_4_name;
        private Formula  field_5_name_definition;
 
+       /**
+        * 'rgoper' / 'Last received results of the DDE link'
+        * (seems to be only applicable to DDE links)<br/>
+        * Logically this is a 2-D array, which has been flattened into 1-D array here.
+        */
+       private Object[] _ddeValues;
+       /**
+        * (logical) number of columns in the {@link #_ddeValues} array
+        */
+       private int _nColumns;
+       /**
+        * (logical) number of rows in the {@link #_ddeValues} array
+        */
+       private int _nRows;
+
        /**
         * Convenience Function to determine if the name is a built-in name
         */
@@ -88,6 +103,11 @@ public final class ExternalNameRecord extends StandardRecord {
                        + 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);
+                       }
                }
                return result;
        }
@@ -101,6 +121,12 @@ public final class ExternalNameRecord extends StandardRecord {
                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);
+                       }
                }
        }
 
@@ -112,6 +138,16 @@ public final class ExternalNameRecord extends StandardRecord {
                short nameLength    = in.readShort();
                field_4_name = in.readCompressedUnicode(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?)");
                        }
@@ -127,11 +163,11 @@ public final class ExternalNameRecord extends StandardRecord {
                field_5_name_definition = Formula.read(formulaLen, in, nBytesRemaining);
        }
        /*
-        * Makes better error messages (while hasFormula() is not reliable) 
+        * 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 
+               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);
        }
index 8ce8a3d5b43281901ea1ce4bad185f2e4c024ac8..5c693d36c2281c36def500163a7d4e917674b3d0 100644 (file)
@@ -17,6 +17,8 @@
 
 package org.apache.poi.hssf.record;
 
+import org.apache.poi.util.HexRead;
+
 import junit.framework.AssertionFailedError;
 import junit.framework.TestCase;
 /**
@@ -102,4 +104,35 @@ public final class TestExternalNameRecord extends TestCase {
 
                TestcaseRecordInputStream.confirmRecordEncoding(0x0023, dataPlainName, enr.serialize());
        }
+
+       public void testDDELink_bug47229() {
+               /**
+                * Hex dump read directly from text of bugzilla 47229
+                */
+               final byte[] dataDDE = HexRead.readFromString(
+                               "E2 7F 00 00 00 00 " +
+                               "37 00 " + // text len
+                               // 010672AT0 MUNI,[RTG_MOODY_UNDERLYING,RTG_SP_UNDERLYING]
+                               "30 31 30 36 37 32 41 54 30 20 4D 55 4E 49 2C " +
+                               "5B 52 54 47 5F 4D 4F 4F 44 59 5F 55 4E 44 45 52 4C 59 49 4E 47 2C " +
+                               "52 54 47 5F 53 50 5F 55 4E 44 45 52 4C 59 49 4E 47 5D " +
+                               // constant array { { "#N/A N.A.", "#N/A N.A.", }, }
+                               " 01 00 00 " +
+                               "02 09 00 00 23 4E 2F 41 20 4E 2E 41 2E " +
+                               "02 09 00 00 23 4E 2F 41 20 4E 2E 41 2E");
+               ExternalNameRecord enr;
+               try {
+                       enr = createSimpleENR(dataDDE);
+               } catch (RecordFormatException e) {
+                       // actual msg reported in bugzilla 47229 is different
+                       // because that seems to be using a version from before svn r646666
+                       if (e.getMessage().startsWith("Some unread data (is formula present?)")) {
+                               throw new AssertionFailedError("Identified bug 47229 - failed to read ENR with OLE/DDE result data");
+                       }
+                       throw e;
+               }
+               assertEquals("010672AT0 MUNI,[RTG_MOODY_UNDERLYING,RTG_SP_UNDERLYING]", enr.getText());
+
+               TestcaseRecordInputStream.confirmRecordEncoding(0x0023, dataDDE, enr.serialize());
+       }
 }