]> source.dussan.org Git - poi.git/commitdiff
Get the Hyperlink record code so that it doesn't break any existing tests, and add...
authorNick Burch <nick@apache.org>
Fri, 1 Feb 2008 15:41:32 +0000 (15:41 +0000)
committerNick Burch <nick@apache.org>
Fri, 1 Feb 2008 15:41:32 +0000 (15:41 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@617523 13f79535-47bb-0310-9956-ffa450edef68

src/java/org/apache/poi/hssf/record/HyperlinkRecord.java
src/java/org/apache/poi/hssf/record/RecordFactory.java
src/java/org/apache/poi/hssf/record/RecordInputStream.java
src/testcases/org/apache/poi/hssf/data/WithHyperlink.xls [new file with mode: 0644]
src/testcases/org/apache/poi/hssf/record/TestHyperlinkRecord.java
src/testcases/org/apache/poi/hssf/usermodel/TestHSSFCell.java

index 76f9f531d6ef75d72600d41bcacccb52dc1456e1..36a26f4151c4c22dc35e36077493c2043d8b86e4 100644 (file)
@@ -65,11 +65,13 @@ public class HyperlinkRecord extends Record implements CellValueRecordInterface
     private short field_3_xf_index;
     private short field_4_unknown;
     private byte[] field_5_unknown;
-    private int field_6_url_len;
-    private int field_7_label_len;
-    private String field_8_label;
-    private byte[] field_9_unknown;
-    private String field_10_url;
+    private int field_6_label_opts;
+    private int field_7_url_len;
+    private int field_8_label_len;
+    private String field_9_label;
+    private byte[] field_10_unknown;
+    private int field_11_url_opts;
+    private String field_12_url;
 
     /** Blank Constructor */
     public HyperlinkRecord()
@@ -186,33 +188,51 @@ public class HyperlinkRecord extends Record implements CellValueRecordInterface
      */
     protected void fillFields(RecordInputStream in)
     {
+//     System.err.println(in.currentSid);
+//     System.err.println(in.currentLength);
+//     for(int i=0; i<300; i++) {
+//             System.err.println(in.readByte());
+//     }
+//     if(1==1)
+//             throw new IllegalArgumentException("");
+       
         field_1_row = in.readUShort(); 
         field_2_column = in.readShort();
         field_3_xf_index = in.readShort();
         field_4_unknown = in.readShort();
         
-        // Next up is 20 bytes we don't get
-        field_5_unknown = new byte[20];
+        // Next up is 16 bytes we don't get
+        field_5_unknown = new byte[16];
         try {
         in.read(field_5_unknown);
         } catch(IOException e) { throw new IllegalStateException(e); }
         
+        // Some sort of opts
+        field_6_label_opts = in.readInt();
+        
         // Now for lengths, in characters
-        field_6_url_len = in.readInt();
-        field_7_label_len = in.readInt();
+        field_7_url_len = in.readInt();
+        field_8_label_len = in.readInt();
         
         // Now we have the label, as little endian unicode,
         //  with a trailing \0
-        field_8_label = in.readUnicodeLEString(field_7_label_len);
+        field_9_label = in.readUnicodeLEString(field_8_label_len);
         
         // Next up is some more data we can't make sense of
-        field_9_unknown = new byte[20];
+        field_10_unknown = new byte[16];
         try {
-        in.read(field_9_unknown);
+        in.read(field_10_unknown);
         } catch(IOException e) { throw new IllegalStateException(e); }
         
+        // Might need to nudge the length by one byte
+        // This is an empirical hack!
+        field_11_url_opts = in.readInt();
+        if(field_11_url_opts == 44) {
+               field_7_url_len--;
+        }
+        
         // Finally it's the URL
-        field_10_url = in.readUnicodeLEString(field_6_url_len);
+        field_12_url = in.readUnicodeLEString(field_7_url_len);
     }
     
     /* (non-Javadoc)
@@ -247,19 +267,23 @@ public class HyperlinkRecord extends Record implements CellValueRecordInterface
                offset++;
         }
         
-        LittleEndian.putInt(data, offset, field_6_url_len);
+        LittleEndian.putInt(data, offset, field_6_label_opts);
+        offset += 4;
+        LittleEndian.putInt(data, offset, field_7_url_len);
         offset += 4;
-        LittleEndian.putInt(data, offset, field_7_label_len);
+        LittleEndian.putInt(data, offset, field_8_label_len);
         offset += 4;
-        StringUtil.putUnicodeLE(field_8_label, data, offset);
-        offset += field_8_label.length()*2;
+        StringUtil.putUnicodeLE(field_9_label, data, offset);
+        offset += field_9_label.length()*2;
 
-        for(int i=0; i<field_9_unknown.length; i++) {
-               data[offset] = field_9_unknown[i];
+        for(int i=0; i<field_10_unknown.length; i++) {
+               data[offset] = field_10_unknown[i];
                offset++;
         }
        
-        StringUtil.putUnicodeLE(field_10_url, data, offset);
+        LittleEndian.putInt(data, offset, field_11_url_opts);
+        offset += 4;
+        StringUtil.putUnicodeLE(field_12_url, data, offset);
         
        return getRecordSize();
     }
@@ -269,14 +293,15 @@ public class HyperlinkRecord extends Record implements CellValueRecordInterface
        // We have:
        // 4 shorts
        // junk
-       // 2 ints
+       // 3 ints
        // label
        // junk
+       // int
        // url
        return 4 + 4*2 + field_5_unknown.length +
-               2*4 + field_8_label.length()*2 +
-               field_9_unknown.length +
-               field_10_url.length()*2;
+               3*4 + field_9_label.length()*2 +
+               field_10_unknown.length + 4 +
+               field_12_url.length()*2;
     }
 
     public String toString()
@@ -287,8 +312,8 @@ public class HyperlinkRecord extends Record implements CellValueRecordInterface
         buffer.append("    .row            = ").append(Integer.toHexString(getRow())).append("\n");
         buffer.append("    .column         = ").append(Integer.toHexString(getColumn())).append("\n");
         buffer.append("    .xfindex        = ").append(Integer.toHexString(getXFIndex())).append("\n");
-        buffer.append("    .label          = ").append(field_8_label).append("\n");
-        buffer.append("    .url            = ").append(field_10_url).append("\n");
+        buffer.append("    .label          = ").append(field_9_label).append("\n");
+        buffer.append("    .url            = ").append(field_12_url).append("\n");
         buffer.append("[/HYPERLINK RECORD]\n");
         return buffer.toString();
     }
@@ -298,11 +323,11 @@ public class HyperlinkRecord extends Record implements CellValueRecordInterface
      */
     public String getLabel()
     {
-       if(field_8_label.length() == 0) {
+       if(field_9_label.length() == 0) {
                return "";
        } else {
                // Trim off \0
-            return field_8_label.substring(0, field_8_label.length() - 1);
+            return field_9_label.substring(0, field_9_label.length() - 1);
        }
     }
 
@@ -311,8 +336,8 @@ public class HyperlinkRecord extends Record implements CellValueRecordInterface
      */
     public void setLabel(String label)
     {
-        this.field_8_label = label + '\u0000';
-        this.field_7_label_len = field_8_label.length();
+        this.field_9_label = label + '\u0000';
+        this.field_8_label_len = field_9_label.length();
     }
 
     /**
@@ -324,11 +349,11 @@ public class HyperlinkRecord extends Record implements CellValueRecordInterface
     }
     public String getUrlString()
     {
-       if(field_10_url.length() == 0) {
+       if(field_12_url.length() == 0) {
                return "";
        } else {
                // Trim off \0
-            return field_10_url.substring(0, field_10_url.length() - 1);
+            return field_12_url.substring(0, field_12_url.length() - 1);
        }
     }
 
@@ -344,7 +369,7 @@ public class HyperlinkRecord extends Record implements CellValueRecordInterface
      */
     public void setUrl(String url)
     {
-        this.field_10_url = url + '\u0000';
-        this.field_6_url_len = field_10_url.length();
+        this.field_12_url = url + '\u0000';
+        this.field_7_url_len = field_12_url.length();
     }
 }
index 20e8ba788accecef918403373efaa982e34a37ee..0f164b44735ae4ac4c58df02af4dd2206bf37a97 100644 (file)
@@ -76,7 +76,8 @@ public class RecordFactory
                 WriteProtectRecord.class, FilePassRecord.class, PaneRecord.class,
                 NoteRecord.class, ObjectProtectRecord.class, ScenarioProtectRecord.class, 
                 FileSharingRecord.class, ChartTitleFormatRecord.class,
-                DVRecord.class, DVALRecord.class, UncalcedRecord.class
+                DVRecord.class, DVALRecord.class, UncalcedRecord.class,
+                HyperlinkRecord.class
             };
     }
     private static Map           recordsMap  = recordsToMap(records);
index dd853f2463904ea36293d51124c2e8a73b22cb43..32094287fa73f26725c2d7cac219cb6f30812163 100755 (executable)
@@ -249,7 +249,7 @@ public class RecordInputStream extends InputStream
    */  
   public String readUnicodeLEString(int length) {
     if ((length < 0) || (((remaining() / 2) < length) && !isContinueNext())) {
-            throw new IllegalArgumentException("Illegal length");
+            throw new IllegalArgumentException("Illegal length - asked for " + length + " but only " + (remaining()/2) + " left!");
     }
 
     StringBuffer buf = new StringBuffer(length);
diff --git a/src/testcases/org/apache/poi/hssf/data/WithHyperlink.xls b/src/testcases/org/apache/poi/hssf/data/WithHyperlink.xls
new file mode 100644 (file)
index 0000000..7d74684
Binary files /dev/null and b/src/testcases/org/apache/poi/hssf/data/WithHyperlink.xls differ
index 587548b48f66c773ab7ff33c766d267457b05212..983b916015832abc0e0990a2c831656198795978 100644 (file)
@@ -56,6 +56,37 @@ public class TestHyperlinkRecord extends TestCase {
                0, 110, 0, 103, 0, 115, 0, 46, 0, 99, 0, 111, 0,
                109, 0, 
                0, 0 };
+       
+       private byte[] data2 = new byte[] {
+               -72, 1, -126, 0,
+               // Row, col, xf, ??
+               2, 0, 2, 0, 4, 0, 4, 0,
+
+               // ??
+               -48, -55, -22, 121, -7, -70, -50, 17,
+               -116, -126, 0, -86, 0, 75, -87, 11,
+               2, 0, 0, 0,
+               
+               // URL and Label lengths
+               23, 0, 0, 0,
+               15, 0, 0, 0,
+
+               // Label
+               83, 0, 116, 0, 97, 0, 99, 0, 105, 0,
+               101, 0, 64, 0, 65, 0, 66, 0, 67, 0,
+               46, 0, 99, 0, 111, 0, 109, 0, 0, 0,
+
+               // ??
+               -32, -55, -22, 121, -7, -70, -50, 17,
+               -116, -126, 0, -86, 0, 75, -87, 11,
+               44, 0, 0, 0,
+
+               // URL
+               109, 0, 97, 0, 105, 0, 108, 0, 116, 0,
+               111, 0, 58, 0, 83, 0, 116, 0, 97, 0,
+               99, 0, 105, 0, 101, 0, 64, 0, 65, 0,
+               66, 0, 67, 0, 46, 0, 99, 0, 111, 0,
+               109, 0, 0, 0 };
 
        public void testRecordParsing() throws Exception {
         RecordInputStream inp = new RecordInputStream(
@@ -81,4 +112,20 @@ public class TestHyperlinkRecord extends TestCase {
                assertEquals(data[i], d[i]);
         }
        }
+
+       public void testSecondRecord() throws Exception {
+        RecordInputStream inp = new RecordInputStream(
+                new ByteArrayInputStream(data2)
+        );
+        inp.nextRecord();
+
+        HyperlinkRecord r = new HyperlinkRecord(inp);
+        
+        assertEquals(2, r.getRow());
+        assertEquals(2, r.getColumn());
+        assertEquals(4, r.getXFIndex());
+        
+               assertEquals("Stacie@ABC.com", r.getLabel());
+               assertEquals("mailto:Stacie@ABC.com", r.getUrlString());
+       }
 }
index ee3cace263f1c82f1776b434bf228bc6ec85069c..482ae7c6cd192ce3cb025c04417e137bd598b284 100644 (file)
@@ -310,6 +310,12 @@ extends TestCase {
             in.close();
     }    
     
+    public void testWithHyperlinks() throws Exception {
+        String dir = System.getProperty("HSSF.testdata.path");
+        File f = new File(dir, "WithHyperlink.xls");
+       HSSFWorkbook wb = new HSSFWorkbook(new FileInputStream(f));
+    }
+    
     /*tests the toString() method of HSSFCell*/
     public void testToString() throws Exception {
        HSSFWorkbook wb = new HSSFWorkbook();