You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by ni...@apache.org on 2008/08/31 18:37:40 UTC

svn commit: r690726 - in /poi/trunk/src: java/org/apache/poi/util/ scratchpad/src/org/apache/poi/hpbf/model/qcbits/ scratchpad/testcases/org/apache/poi/hpbf/data/ scratchpad/testcases/org/apache/poi/hpbf/model/

Author: nick
Date: Sun Aug 31 09:37:39 2008
New Revision: 690726

URL: http://svn.apache.org/viewvc?rev=690726&view=rev
Log:
Start to support HPBF hyperlinks

Added:
    poi/trunk/src/scratchpad/testcases/org/apache/poi/hpbf/data/LinkAt0And10.pub   (with props)
    poi/trunk/src/scratchpad/testcases/org/apache/poi/hpbf/data/LinkAt10.pub   (with props)
    poi/trunk/src/scratchpad/testcases/org/apache/poi/hpbf/data/LinkAt10And20And30.pub   (with props)
    poi/trunk/src/scratchpad/testcases/org/apache/poi/hpbf/data/LinkAt10And20And30And40.pub   (with props)
    poi/trunk/src/scratchpad/testcases/org/apache/poi/hpbf/data/LinkAt10Longer.pub   (with props)
    poi/trunk/src/scratchpad/testcases/org/apache/poi/hpbf/data/LinkAt20.pub   (with props)
Modified:
    poi/trunk/src/java/org/apache/poi/util/StringUtil.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hpbf/model/qcbits/QCPLCBit.java
    poi/trunk/src/scratchpad/testcases/org/apache/poi/hpbf/model/TestQuillContents.java

Modified: poi/trunk/src/java/org/apache/poi/util/StringUtil.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/util/StringUtil.java?rev=690726&r1=690725&r2=690726&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/util/StringUtil.java (original)
+++ poi/trunk/src/java/org/apache/poi/util/StringUtil.java Sun Aug 31 09:37:39 2008
@@ -68,7 +68,7 @@
 			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 {

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hpbf/model/qcbits/QCPLCBit.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hpbf/model/qcbits/QCPLCBit.java?rev=690726&r1=690725&r2=690726&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hpbf/model/qcbits/QCPLCBit.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hpbf/model/qcbits/QCPLCBit.java Sun Aug 31 09:37:39 2008
@@ -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 @@
 	 * 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];
 		}
 	}
 }

Added: poi/trunk/src/scratchpad/testcases/org/apache/poi/hpbf/data/LinkAt0And10.pub
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/testcases/org/apache/poi/hpbf/data/LinkAt0And10.pub?rev=690726&view=auto
==============================================================================
Binary file - no diff available.

Propchange: poi/trunk/src/scratchpad/testcases/org/apache/poi/hpbf/data/LinkAt0And10.pub
------------------------------------------------------------------------------
    svn:executable = *

Propchange: poi/trunk/src/scratchpad/testcases/org/apache/poi/hpbf/data/LinkAt0And10.pub
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: poi/trunk/src/scratchpad/testcases/org/apache/poi/hpbf/data/LinkAt10.pub
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/testcases/org/apache/poi/hpbf/data/LinkAt10.pub?rev=690726&view=auto
==============================================================================
Binary file - no diff available.

Propchange: poi/trunk/src/scratchpad/testcases/org/apache/poi/hpbf/data/LinkAt10.pub
------------------------------------------------------------------------------
    svn:executable = *

Propchange: poi/trunk/src/scratchpad/testcases/org/apache/poi/hpbf/data/LinkAt10.pub
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: poi/trunk/src/scratchpad/testcases/org/apache/poi/hpbf/data/LinkAt10And20And30.pub
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/testcases/org/apache/poi/hpbf/data/LinkAt10And20And30.pub?rev=690726&view=auto
==============================================================================
Binary file - no diff available.

Propchange: poi/trunk/src/scratchpad/testcases/org/apache/poi/hpbf/data/LinkAt10And20And30.pub
------------------------------------------------------------------------------
    svn:executable = *

Propchange: poi/trunk/src/scratchpad/testcases/org/apache/poi/hpbf/data/LinkAt10And20And30.pub
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: poi/trunk/src/scratchpad/testcases/org/apache/poi/hpbf/data/LinkAt10And20And30And40.pub
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/testcases/org/apache/poi/hpbf/data/LinkAt10And20And30And40.pub?rev=690726&view=auto
==============================================================================
Binary file - no diff available.

Propchange: poi/trunk/src/scratchpad/testcases/org/apache/poi/hpbf/data/LinkAt10And20And30And40.pub
------------------------------------------------------------------------------
    svn:executable = *

Propchange: poi/trunk/src/scratchpad/testcases/org/apache/poi/hpbf/data/LinkAt10And20And30And40.pub
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: poi/trunk/src/scratchpad/testcases/org/apache/poi/hpbf/data/LinkAt10Longer.pub
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/testcases/org/apache/poi/hpbf/data/LinkAt10Longer.pub?rev=690726&view=auto
==============================================================================
Binary file - no diff available.

Propchange: poi/trunk/src/scratchpad/testcases/org/apache/poi/hpbf/data/LinkAt10Longer.pub
------------------------------------------------------------------------------
    svn:executable = *

Propchange: poi/trunk/src/scratchpad/testcases/org/apache/poi/hpbf/data/LinkAt10Longer.pub
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: poi/trunk/src/scratchpad/testcases/org/apache/poi/hpbf/data/LinkAt20.pub
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/testcases/org/apache/poi/hpbf/data/LinkAt20.pub?rev=690726&view=auto
==============================================================================
Binary file - no diff available.

Propchange: poi/trunk/src/scratchpad/testcases/org/apache/poi/hpbf/data/LinkAt20.pub
------------------------------------------------------------------------------
    svn:executable = *

Propchange: poi/trunk/src/scratchpad/testcases/org/apache/poi/hpbf/data/LinkAt20.pub
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Modified: poi/trunk/src/scratchpad/testcases/org/apache/poi/hpbf/model/TestQuillContents.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/testcases/org/apache/poi/hpbf/model/TestQuillContents.java?rev=690726&r1=690725&r2=690726&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/testcases/org/apache/poi/hpbf/model/TestQuillContents.java (original)
+++ poi/trunk/src/scratchpad/testcases/org/apache/poi/hpbf/model/TestQuillContents.java Sun Aug 31 09:37:39 2008
@@ -244,4 +244,191 @@
 		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));
+	}
 }



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