Start to support HPBF hyperlinks
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@690726 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
2110416cbf
commit
e786480817
@ -68,7 +68,7 @@ public class StringUtil {
|
||||
throw new ArrayIndexOutOfBoundsException("Illegal offset");
|
||||
}
|
||||
if ((len < 0) || (((string.length - offset) / 2) < len)) {
|
||||
throw new IllegalArgumentException("Illegal length");
|
||||
throw new IllegalArgumentException("Illegal length " + len);
|
||||
}
|
||||
|
||||
try {
|
||||
|
@ -17,6 +17,7 @@
|
||||
package org.apache.poi.hpbf.model.qcbits;
|
||||
|
||||
import org.apache.poi.util.LittleEndian;
|
||||
import org.apache.poi.util.StringUtil;
|
||||
|
||||
|
||||
/**
|
||||
@ -168,8 +169,98 @@ public class QCPLCBit extends QCBit {
|
||||
* Type 12 holds hyperlinks, and is very complex.
|
||||
*/
|
||||
public static class Type12 extends QCPLCBit {
|
||||
private String[] hyperlinks;
|
||||
|
||||
private static final int oneStartsAt = 0x4c;
|
||||
private static final int twoStartsAt = 0x68;
|
||||
private static final int threePlusIncrement = 22;
|
||||
|
||||
private Type12(String thingType, String bitType, byte[] data) {
|
||||
super(thingType, bitType, data);
|
||||
|
||||
// How many hyperlinks do we really have?
|
||||
// (zero hyperlinks gets numberOfPLCs=1)
|
||||
if(data.length == 0x34) {
|
||||
hyperlinks = new String[0];
|
||||
} else {
|
||||
hyperlinks = new String[numberOfPLCs];
|
||||
}
|
||||
|
||||
// We have 4 bytes, then the start point of each
|
||||
// hyperlink, then the end point of the text.
|
||||
preData = new int[1+numberOfPLCs+1];
|
||||
for(int i=0; i<preData.length; i++) {
|
||||
preData[i] = (int)LittleEndian.getUInt(data, 8+(i*4));
|
||||
}
|
||||
|
||||
// Then we have a whole bunch of stuff, which grows
|
||||
// with the number of hyperlinks
|
||||
// For now, we think these are shorts
|
||||
int at = 8+4+(numberOfPLCs*4)+4;
|
||||
int until = 0x34;
|
||||
if(numberOfPLCs == 1 && hyperlinks.length == 1) {
|
||||
until = oneStartsAt;
|
||||
} else if(numberOfPLCs >= 2) {
|
||||
until = twoStartsAt + (numberOfPLCs-2)*threePlusIncrement;
|
||||
}
|
||||
|
||||
plcValA = new long[(until-at)/2];
|
||||
plcValB = new long[0];
|
||||
for(int i=0; i<plcValA.length; i++) {
|
||||
plcValA[i] = LittleEndian.getUShort(data, at+(i*2));
|
||||
}
|
||||
|
||||
// Finally, we have a series of lengths + hyperlinks
|
||||
at = until;
|
||||
for(int i=0; i<hyperlinks.length; i++) {
|
||||
int len = LittleEndian.getUShort(data, at);
|
||||
int first = LittleEndian.getUShort(data, at+2);
|
||||
if(first == 0) {
|
||||
// Crazy special case
|
||||
// Length is in bytes, from the start
|
||||
// Hyperlink appears to be empty
|
||||
hyperlinks[i] = "";
|
||||
at += len;
|
||||
} else {
|
||||
// Normal case. Length is in characters
|
||||
hyperlinks[i] = StringUtil.getFromUnicodeLE(data, at+2, len);
|
||||
at += 2 + (2*len);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of hyperlinks, which should
|
||||
* either be zero, or the number of PLC bits
|
||||
*/
|
||||
public int getNumberOfHyperlinks() {
|
||||
return hyperlinks.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the URL of the hyperlink at the
|
||||
* given index.
|
||||
* @param number The hyperlink number, zero based
|
||||
*/
|
||||
public String getHyperlink(int number) {
|
||||
return hyperlinks[number];
|
||||
}
|
||||
/**
|
||||
* Returns where in the text (in characters) the
|
||||
* hyperlink at the given index starts
|
||||
* applying to.
|
||||
* @param number The hyperlink number, zero based
|
||||
*/
|
||||
public int getTextStartAt(int number) {
|
||||
return preData[1+number];
|
||||
}
|
||||
/**
|
||||
* Returns where in the text that this block
|
||||
* of hyperlinks stops applying to. Normally,
|
||||
* but not always the end of the text.
|
||||
*/
|
||||
public int getAllTextEndAt() {
|
||||
return preData[numberOfPLCs+1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
BIN
src/scratchpad/testcases/org/apache/poi/hpbf/data/LinkAt0And10.pub
Executable file
BIN
src/scratchpad/testcases/org/apache/poi/hpbf/data/LinkAt0And10.pub
Executable file
Binary file not shown.
BIN
src/scratchpad/testcases/org/apache/poi/hpbf/data/LinkAt10.pub
Executable file
BIN
src/scratchpad/testcases/org/apache/poi/hpbf/data/LinkAt10.pub
Executable file
Binary file not shown.
BIN
src/scratchpad/testcases/org/apache/poi/hpbf/data/LinkAt10And20And30.pub
Executable file
BIN
src/scratchpad/testcases/org/apache/poi/hpbf/data/LinkAt10And20And30.pub
Executable file
Binary file not shown.
BIN
src/scratchpad/testcases/org/apache/poi/hpbf/data/LinkAt10And20And30And40.pub
Executable file
BIN
src/scratchpad/testcases/org/apache/poi/hpbf/data/LinkAt10And20And30And40.pub
Executable file
Binary file not shown.
BIN
src/scratchpad/testcases/org/apache/poi/hpbf/data/LinkAt10Longer.pub
Executable file
BIN
src/scratchpad/testcases/org/apache/poi/hpbf/data/LinkAt10Longer.pub
Executable file
Binary file not shown.
BIN
src/scratchpad/testcases/org/apache/poi/hpbf/data/LinkAt20.pub
Executable file
BIN
src/scratchpad/testcases/org/apache/poi/hpbf/data/LinkAt20.pub
Executable file
Binary file not shown.
@ -244,4 +244,191 @@ public class TestQuillContents extends TestCase {
|
||||
assertEquals(0x000004, plc16.getPlcValA()[5]);
|
||||
assertEquals(0x000004, plc16.getPlcValB()[5]);
|
||||
}
|
||||
|
||||
public void testNoHyperlinks() throws Exception {
|
||||
File f = new File(dir, "SampleNewsletter.pub");
|
||||
HPBFDocument doc = new HPBFDocument(
|
||||
new FileInputStream(f)
|
||||
);
|
||||
|
||||
QuillContents qc = doc.getQuillContents();
|
||||
assertEquals(20, qc.getBits().length);
|
||||
|
||||
Type12 plc18 = (Type12)qc.getBits()[18];
|
||||
|
||||
assertEquals(1, plc18.getNumberOfPLCs());
|
||||
assertEquals(0, plc18.getNumberOfHyperlinks());
|
||||
assertEquals(0, plc18.getTextStartAt(0));
|
||||
assertEquals(601, plc18.getAllTextEndAt());
|
||||
}
|
||||
|
||||
public void testSimpleHyperlink() throws Exception {
|
||||
File f;
|
||||
HPBFDocument doc;
|
||||
QuillContents qc;
|
||||
Type12 hlBit;
|
||||
|
||||
// Link at 10
|
||||
f = new File(dir, "LinkAt10.pub");
|
||||
doc = new HPBFDocument(
|
||||
new FileInputStream(f)
|
||||
);
|
||||
qc = doc.getQuillContents();
|
||||
|
||||
hlBit = (Type12)qc.getBits()[12];
|
||||
assertEquals(1, hlBit.getNumberOfPLCs());
|
||||
assertEquals(1, hlBit.getNumberOfHyperlinks());
|
||||
|
||||
assertEquals(10, hlBit.getTextStartAt(0));
|
||||
assertEquals(15, hlBit.getAllTextEndAt());
|
||||
assertEquals("http://poi.apache.org/", hlBit.getHyperlink(0));
|
||||
|
||||
// Longer link at 10
|
||||
f = new File(dir, "LinkAt10Longer.pub");
|
||||
doc = new HPBFDocument(
|
||||
new FileInputStream(f)
|
||||
);
|
||||
qc = doc.getQuillContents();
|
||||
|
||||
hlBit = (Type12)qc.getBits()[12];
|
||||
assertEquals(1, hlBit.getNumberOfPLCs());
|
||||
assertEquals(1, hlBit.getNumberOfHyperlinks());
|
||||
|
||||
assertEquals(10, hlBit.getTextStartAt(0));
|
||||
assertEquals(15, hlBit.getAllTextEndAt());
|
||||
assertEquals("http://poi.apache.org/hpbf/", hlBit.getHyperlink(0));
|
||||
|
||||
// Link at 20
|
||||
f = new File(dir, "LinkAt20.pub");
|
||||
doc = new HPBFDocument(
|
||||
new FileInputStream(f)
|
||||
);
|
||||
qc = doc.getQuillContents();
|
||||
|
||||
hlBit = (Type12)qc.getBits()[12];
|
||||
assertEquals(1, hlBit.getNumberOfPLCs());
|
||||
assertEquals(1, hlBit.getNumberOfHyperlinks());
|
||||
|
||||
assertEquals(20, hlBit.getTextStartAt(0));
|
||||
assertEquals(25, hlBit.getAllTextEndAt());
|
||||
assertEquals("http://poi.apache.org/", hlBit.getHyperlink(0));
|
||||
}
|
||||
|
||||
public void testManyHyperlinks() throws Exception {
|
||||
File f;
|
||||
HPBFDocument doc;
|
||||
QuillContents qc;
|
||||
Type12 hlBit;
|
||||
|
||||
// Link at 10
|
||||
f = new File(dir, "LinkAt10.pub");
|
||||
doc = new HPBFDocument(
|
||||
new FileInputStream(f)
|
||||
);
|
||||
qc = doc.getQuillContents();
|
||||
|
||||
hlBit = (Type12)qc.getBits()[12];
|
||||
assertEquals(1, hlBit.getNumberOfPLCs());
|
||||
assertEquals(1, hlBit.getNumberOfHyperlinks());
|
||||
|
||||
assertEquals(10, hlBit.getTextStartAt(0));
|
||||
assertEquals(15, hlBit.getAllTextEndAt());
|
||||
assertEquals("http://poi.apache.org/", hlBit.getHyperlink(0));
|
||||
|
||||
}
|
||||
|
||||
public void testHyperlinkDifferentVersions() throws Exception {
|
||||
File f;
|
||||
HPBFDocument doc;
|
||||
QuillContents qc;
|
||||
Type12 hlBitA;
|
||||
Type12 hlBitB;
|
||||
|
||||
// Latest version
|
||||
f = new File(dir, "Sample.pub");
|
||||
doc = new HPBFDocument(
|
||||
new FileInputStream(f)
|
||||
);
|
||||
qc = doc.getQuillContents();
|
||||
|
||||
hlBitA = (Type12)qc.getBits()[14];
|
||||
assertEquals(2, hlBitA.getNumberOfPLCs());
|
||||
assertEquals(2, hlBitA.getNumberOfHyperlinks());
|
||||
|
||||
assertEquals(25, hlBitA.getTextStartAt(0));
|
||||
assertEquals(72, hlBitA.getTextStartAt(1));
|
||||
assertEquals(87, hlBitA.getAllTextEndAt());
|
||||
assertEquals("http://poi.apache.org/", hlBitA.getHyperlink(0));
|
||||
assertEquals("C:\\Documents and Settings\\Nick\\My Documents\\Booleans.xlsx", hlBitA.getHyperlink(1));
|
||||
|
||||
hlBitB = (Type12)qc.getBits()[15];
|
||||
assertEquals(3, hlBitB.getNumberOfPLCs());
|
||||
assertEquals(3, hlBitB.getNumberOfHyperlinks());
|
||||
|
||||
assertEquals(27, hlBitB.getTextStartAt(0));
|
||||
assertEquals(37, hlBitB.getTextStartAt(1));
|
||||
assertEquals(54, hlBitB.getTextStartAt(2));
|
||||
assertEquals(75, hlBitB.getAllTextEndAt());
|
||||
assertEquals("", hlBitB.getHyperlink(0));
|
||||
assertEquals("mailto:dev@poi.apache.org?subject=HPBF", hlBitB.getHyperlink(1));
|
||||
assertEquals("mailto:dev@poi.apache.org?subject=HPBF", hlBitB.getHyperlink(2));
|
||||
|
||||
// 2000 version
|
||||
f = new File(dir, "Sample2000.pub");
|
||||
doc = new HPBFDocument(
|
||||
new FileInputStream(f)
|
||||
);
|
||||
qc = doc.getQuillContents();
|
||||
|
||||
hlBitA = (Type12)qc.getBits()[13];
|
||||
assertEquals(2, hlBitA.getNumberOfPLCs());
|
||||
assertEquals(2, hlBitA.getNumberOfHyperlinks());
|
||||
|
||||
assertEquals(25, hlBitA.getTextStartAt(0));
|
||||
assertEquals(72, hlBitA.getTextStartAt(1));
|
||||
assertEquals(87, hlBitA.getAllTextEndAt());
|
||||
assertEquals("http://poi.apache.org/", hlBitA.getHyperlink(0));
|
||||
assertEquals("C:\\Documents and Settings\\Nick\\My Documents\\Booleans.xlsx", hlBitA.getHyperlink(1));
|
||||
|
||||
hlBitB = (Type12)qc.getBits()[14];
|
||||
assertEquals(3, hlBitB.getNumberOfPLCs());
|
||||
assertEquals(3, hlBitB.getNumberOfHyperlinks());
|
||||
|
||||
assertEquals(27, hlBitB.getTextStartAt(0));
|
||||
assertEquals(37, hlBitB.getTextStartAt(1));
|
||||
assertEquals(54, hlBitB.getTextStartAt(2));
|
||||
assertEquals(75, hlBitB.getAllTextEndAt());
|
||||
assertEquals("", hlBitB.getHyperlink(0));
|
||||
assertEquals("mailto:dev@poi.apache.org?subject=HPBF", hlBitB.getHyperlink(1));
|
||||
assertEquals("mailto:dev@poi.apache.org?subject=HPBF", hlBitB.getHyperlink(2));
|
||||
|
||||
// 98 version
|
||||
f = new File(dir, "Sample98.pub");
|
||||
doc = new HPBFDocument(
|
||||
new FileInputStream(f)
|
||||
);
|
||||
qc = doc.getQuillContents();
|
||||
|
||||
hlBitA = (Type12)qc.getBits()[13];
|
||||
assertEquals(2, hlBitA.getNumberOfPLCs());
|
||||
assertEquals(2, hlBitA.getNumberOfHyperlinks());
|
||||
|
||||
assertEquals(25, hlBitA.getTextStartAt(0));
|
||||
assertEquals(72, hlBitA.getTextStartAt(1));
|
||||
assertEquals(87, hlBitA.getAllTextEndAt());
|
||||
assertEquals("http://poi.apache.org/", hlBitA.getHyperlink(0));
|
||||
assertEquals("C:\\Documents and Settings\\Nick\\My Documents\\Booleans.xlsx", hlBitA.getHyperlink(1));
|
||||
|
||||
hlBitB = (Type12)qc.getBits()[14];
|
||||
assertEquals(3, hlBitB.getNumberOfPLCs());
|
||||
assertEquals(3, hlBitB.getNumberOfHyperlinks());
|
||||
|
||||
assertEquals(27, hlBitB.getTextStartAt(0));
|
||||
assertEquals(37, hlBitB.getTextStartAt(1));
|
||||
assertEquals(54, hlBitB.getTextStartAt(2));
|
||||
assertEquals(75, hlBitB.getAllTextEndAt());
|
||||
assertEquals("", hlBitB.getHyperlink(0));
|
||||
assertEquals("mailto:dev@poi.apache.org?subject=HPBF", hlBitB.getHyperlink(1));
|
||||
assertEquals("mailto:dev@poi.apache.org?subject=HPBF", hlBitB.getHyperlink(2));
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user