Get the Hyperlink record code so that it doesn't break any existing tests, and add in (no usermodel support yet though)

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@617523 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Nick Burch 2008-02-01 15:41:32 +00:00
parent dc92ea3725
commit 93ccde2d0e
6 changed files with 115 additions and 36 deletions

View File

@ -65,11 +65,13 @@ public class HyperlinkRecord extends Record implements CellValueRecordInterface
private short field_3_xf_index; private short field_3_xf_index;
private short field_4_unknown; private short field_4_unknown;
private byte[] field_5_unknown; private byte[] field_5_unknown;
private int field_6_url_len; private int field_6_label_opts;
private int field_7_label_len; private int field_7_url_len;
private String field_8_label; private int field_8_label_len;
private byte[] field_9_unknown; private String field_9_label;
private String field_10_url; private byte[] field_10_unknown;
private int field_11_url_opts;
private String field_12_url;
/** Blank Constructor */ /** Blank Constructor */
public HyperlinkRecord() public HyperlinkRecord()
@ -186,33 +188,51 @@ public class HyperlinkRecord extends Record implements CellValueRecordInterface
*/ */
protected void fillFields(RecordInputStream in) 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_1_row = in.readUShort();
field_2_column = in.readShort(); field_2_column = in.readShort();
field_3_xf_index = in.readShort(); field_3_xf_index = in.readShort();
field_4_unknown = in.readShort(); field_4_unknown = in.readShort();
// Next up is 20 bytes we don't get // Next up is 16 bytes we don't get
field_5_unknown = new byte[20]; field_5_unknown = new byte[16];
try { try {
in.read(field_5_unknown); in.read(field_5_unknown);
} catch(IOException e) { throw new IllegalStateException(e); } } catch(IOException e) { throw new IllegalStateException(e); }
// Some sort of opts
field_6_label_opts = in.readInt();
// Now for lengths, in characters // Now for lengths, in characters
field_6_url_len = in.readInt(); field_7_url_len = in.readInt();
field_7_label_len = in.readInt(); field_8_label_len = in.readInt();
// Now we have the label, as little endian unicode, // Now we have the label, as little endian unicode,
// with a trailing \0 // 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 // 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 { try {
in.read(field_9_unknown); in.read(field_10_unknown);
} catch(IOException e) { throw new IllegalStateException(e); } } 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 // 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) /* (non-Javadoc)
@ -247,19 +267,23 @@ public class HyperlinkRecord extends Record implements CellValueRecordInterface
offset++; offset++;
} }
LittleEndian.putInt(data, offset, field_6_url_len); LittleEndian.putInt(data, offset, field_6_label_opts);
offset += 4; offset += 4;
LittleEndian.putInt(data, offset, field_7_label_len); LittleEndian.putInt(data, offset, field_7_url_len);
offset += 4; offset += 4;
StringUtil.putUnicodeLE(field_8_label, data, offset); LittleEndian.putInt(data, offset, field_8_label_len);
offset += field_8_label.length()*2; offset += 4;
StringUtil.putUnicodeLE(field_9_label, data, offset);
offset += field_9_label.length()*2;
for(int i=0; i<field_9_unknown.length; i++) { for(int i=0; i<field_10_unknown.length; i++) {
data[offset] = field_9_unknown[i]; data[offset] = field_10_unknown[i];
offset++; 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(); return getRecordSize();
} }
@ -269,14 +293,15 @@ public class HyperlinkRecord extends Record implements CellValueRecordInterface
// We have: // We have:
// 4 shorts // 4 shorts
// junk // junk
// 2 ints // 3 ints
// label // label
// junk // junk
// int
// url // url
return 4 + 4*2 + field_5_unknown.length + return 4 + 4*2 + field_5_unknown.length +
2*4 + field_8_label.length()*2 + 3*4 + field_9_label.length()*2 +
field_9_unknown.length + field_10_unknown.length + 4 +
field_10_url.length()*2; field_12_url.length()*2;
} }
public String toString() 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(" .row = ").append(Integer.toHexString(getRow())).append("\n");
buffer.append(" .column = ").append(Integer.toHexString(getColumn())).append("\n"); buffer.append(" .column = ").append(Integer.toHexString(getColumn())).append("\n");
buffer.append(" .xfindex = ").append(Integer.toHexString(getXFIndex())).append("\n"); buffer.append(" .xfindex = ").append(Integer.toHexString(getXFIndex())).append("\n");
buffer.append(" .label = ").append(field_8_label).append("\n"); buffer.append(" .label = ").append(field_9_label).append("\n");
buffer.append(" .url = ").append(field_10_url).append("\n"); buffer.append(" .url = ").append(field_12_url).append("\n");
buffer.append("[/HYPERLINK RECORD]\n"); buffer.append("[/HYPERLINK RECORD]\n");
return buffer.toString(); return buffer.toString();
} }
@ -298,11 +323,11 @@ public class HyperlinkRecord extends Record implements CellValueRecordInterface
*/ */
public String getLabel() public String getLabel()
{ {
if(field_8_label.length() == 0) { if(field_9_label.length() == 0) {
return ""; return "";
} else { } else {
// Trim off \0 // 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) public void setLabel(String label)
{ {
this.field_8_label = label + '\u0000'; this.field_9_label = label + '\u0000';
this.field_7_label_len = field_8_label.length(); this.field_8_label_len = field_9_label.length();
} }
/** /**
@ -324,11 +349,11 @@ public class HyperlinkRecord extends Record implements CellValueRecordInterface
} }
public String getUrlString() public String getUrlString()
{ {
if(field_10_url.length() == 0) { if(field_12_url.length() == 0) {
return ""; return "";
} else { } else {
// Trim off \0 // 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) public void setUrl(String url)
{ {
this.field_10_url = url + '\u0000'; this.field_12_url = url + '\u0000';
this.field_6_url_len = field_10_url.length(); this.field_7_url_len = field_12_url.length();
} }
} }

View File

@ -76,7 +76,8 @@ public class RecordFactory
WriteProtectRecord.class, FilePassRecord.class, PaneRecord.class, WriteProtectRecord.class, FilePassRecord.class, PaneRecord.class,
NoteRecord.class, ObjectProtectRecord.class, ScenarioProtectRecord.class, NoteRecord.class, ObjectProtectRecord.class, ScenarioProtectRecord.class,
FileSharingRecord.class, ChartTitleFormatRecord.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); private static Map recordsMap = recordsToMap(records);

View File

@ -249,7 +249,7 @@ public class RecordInputStream extends InputStream
*/ */
public String readUnicodeLEString(int length) { public String readUnicodeLEString(int length) {
if ((length < 0) || (((remaining() / 2) < length) && !isContinueNext())) { 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); StringBuffer buf = new StringBuffer(length);

View File

@ -56,6 +56,37 @@ public class TestHyperlinkRecord extends TestCase {
0, 110, 0, 103, 0, 115, 0, 46, 0, 99, 0, 111, 0, 0, 110, 0, 103, 0, 115, 0, 46, 0, 99, 0, 111, 0,
109, 0, 109, 0,
0, 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 { public void testRecordParsing() throws Exception {
RecordInputStream inp = new RecordInputStream( RecordInputStream inp = new RecordInputStream(
@ -81,4 +112,20 @@ public class TestHyperlinkRecord extends TestCase {
assertEquals(data[i], d[i]); 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());
}
} }

View File

@ -310,6 +310,12 @@ extends TestCase {
in.close(); 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*/ /*tests the toString() method of HSSFCell*/
public void testToString() throws Exception { public void testToString() throws Exception {
HSSFWorkbook wb = new HSSFWorkbook(); HSSFWorkbook wb = new HSSFWorkbook();