aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/scratchpad/src/org/apache/poi/hdgf/pointers/Pointer.java4
-rw-r--r--src/scratchpad/src/org/apache/poi/hdgf/pointers/PointerFactory.java53
-rw-r--r--src/scratchpad/src/org/apache/poi/hdgf/pointers/PointerV5.java31
-rw-r--r--src/scratchpad/src/org/apache/poi/hdgf/pointers/PointerV6.java32
-rw-r--r--src/scratchpad/src/org/apache/poi/hdgf/streams/PointerContainingStream.java34
-rw-r--r--src/scratchpad/testcases/org/apache/poi/hdgf/streams/StreamTest.java14
6 files changed, 104 insertions, 64 deletions
diff --git a/src/scratchpad/src/org/apache/poi/hdgf/pointers/Pointer.java b/src/scratchpad/src/org/apache/poi/hdgf/pointers/Pointer.java
index d10f154e2e..a2c5854f73 100644
--- a/src/scratchpad/src/org/apache/poi/hdgf/pointers/Pointer.java
+++ b/src/scratchpad/src/org/apache/poi/hdgf/pointers/Pointer.java
@@ -45,6 +45,10 @@ public abstract class Pointer {
}
public abstract int getSizeInBytes();
+ public abstract int getNumPointersOffset(byte[] data);
+ public abstract int getNumPointers(int offset, byte[] data);
+ public abstract int getPostNumPointersSkip();
+
public abstract boolean destinationHasStrings();
public abstract boolean destinationHasPointers();
public abstract boolean destinationHasChunks();
diff --git a/src/scratchpad/src/org/apache/poi/hdgf/pointers/PointerFactory.java b/src/scratchpad/src/org/apache/poi/hdgf/pointers/PointerFactory.java
index 640396cf57..8506c83a97 100644
--- a/src/scratchpad/src/org/apache/poi/hdgf/pointers/PointerFactory.java
+++ b/src/scratchpad/src/org/apache/poi/hdgf/pointers/PointerFactory.java
@@ -31,6 +31,9 @@ public final class PointerFactory {
}
public int getVersion() { return version; }
+ /**
+ * Creates a single Pointer from the data at the given offset
+ */
public Pointer createPointer(byte[] data, int offset) {
Pointer p;
if(version >= 6) {
@@ -57,39 +60,25 @@ public final class PointerFactory {
}
/**
- * In a {@link PointerContainingStream}, where would the
- * number of child pointers be stored for this kind of Pointer?
+ * Parsers the {@link PointerContainingStream} contents and
+ * creates all the child Pointers for it
*/
- public int identifyNumPointersOffset(Pointer pointer, byte[] data) {
- if (pointer instanceof PointerV6) {
- // V6 stores it as the first value in the stream
- return (int)LittleEndian.getUInt(data, 0);
- } else if (pointer instanceof PointerV5) {
- // V5 uses fixed offsets
- switch (pointer.type) {
- case 0x1d:
- case 0x4e:
- return 0x24-6;
- case 0x1e:
- return 0x3c-6;
- case 0x14:
- return 0x88-6;
- }
- return 10;
- } else {
- throw new IllegalArgumentException("Unsupported Pointer type " + pointer);
- }
- }
-
- public int identifyNumPointers(Pointer pointer, int offset, byte[] data) {
- if (pointer instanceof PointerV6) {
- // V6 stores it a 32 bit number at the offset
- return (int)LittleEndian.getUInt(data, offset);
- } else if (pointer instanceof PointerV5) {
- // V5 stores it as a 16 bit number at the offset
- return LittleEndian.getShort(data, offset);
- } else {
- throw new IllegalArgumentException("Unsupported Pointer type " + pointer);
+ public Pointer[] createContainerPointers(Pointer parent, byte[] data) {
+ // Where in the stream does the "number of pointers" offset live?
+ int numPointersOffset = parent.getNumPointersOffset(data);
+ // How many do we have?
+ int numPointers = parent.getNumPointers(numPointersOffset, data);
+ // How much to skip for the num pointers + any extra data?
+ int skip = parent.getPostNumPointersSkip();
+
+ // Create
+ int pos = numPointersOffset + skip;
+ Pointer[] childPointers = new Pointer[numPointers];
+ for(int i=0; i<numPointers; i++) {
+ childPointers[i] = this.createPointer(data, pos);
+ pos += childPointers[i].getSizeInBytes();
}
+
+ return childPointers;
}
}
diff --git a/src/scratchpad/src/org/apache/poi/hdgf/pointers/PointerV5.java b/src/scratchpad/src/org/apache/poi/hdgf/pointers/PointerV5.java
index 23c2a6c479..2fde9a2d56 100644
--- a/src/scratchpad/src/org/apache/poi/hdgf/pointers/PointerV5.java
+++ b/src/scratchpad/src/org/apache/poi/hdgf/pointers/PointerV5.java
@@ -17,6 +17,8 @@
package org.apache.poi.hdgf.pointers;
+import org.apache.poi.util.LittleEndian;
+
/**
* A Pointer from v5
*/
@@ -43,4 +45,33 @@ public final class PointerV5 extends Pointer {
* With v6 pointers, the on-disk size is 16 bytes
*/
public int getSizeInBytes() { return 16; }
+
+ /**
+ * Depends on the type only, not stored
+ */
+ public int getNumPointersOffset(byte[] data) {
+ switch (type) {
+ case 0x1d:
+ case 0x4e:
+ return 0x24-6;
+ case 0x1e:
+ return 0x3c-6;
+ case 0x14:
+ return 0x88-6;
+ }
+ return 10;
+ }
+ /**
+ * 16 bit int at the given offset
+ */
+ public int getNumPointers(int offset, byte[] data) {
+ // V5 stores it as a 16 bit number at the offset
+ return LittleEndian.getShort(data, offset);
+ }
+ /**
+ * Just the 2 bytes of the number of pointers
+ */
+ public int getPostNumPointersSkip() {
+ return 2;
+ }
}
diff --git a/src/scratchpad/src/org/apache/poi/hdgf/pointers/PointerV6.java b/src/scratchpad/src/org/apache/poi/hdgf/pointers/PointerV6.java
index 75445dcd11..09b00fb4ba 100644
--- a/src/scratchpad/src/org/apache/poi/hdgf/pointers/PointerV6.java
+++ b/src/scratchpad/src/org/apache/poi/hdgf/pointers/PointerV6.java
@@ -17,6 +17,8 @@
package org.apache.poi.hdgf.pointers;
+import org.apache.poi.util.LittleEndian;
+
/**
* A Pointer from v6+
*/
@@ -42,4 +44,34 @@ public final class PointerV6 extends Pointer {
* With v6 pointers, the on-disk size is 18 bytes
*/
public int getSizeInBytes() { return 18; }
+
+ /**
+ * Stored within the data
+ */
+ public int getNumPointersOffset(byte[] data) {
+ return getNumPointersOffsetV6(data);
+ }
+ public static int getNumPointersOffsetV6(byte[] data) {
+ // V6 stores it as the first value in the stream
+ return (int)LittleEndian.getUInt(data, 0);
+ }
+ /**
+ * 32 bit int at the given offset
+ */
+ public int getNumPointers(int offset, byte[] data) {
+ return getNumPointersV6(offset, data);
+ }
+ public static int getNumPointersV6(int offset, byte[] data) {
+ // V6 stores it a 32 bit number at the offset
+ return (int)LittleEndian.getUInt(data, offset);
+ }
+ /**
+ * 4 bytes of the number, and 4 more unknown bytes
+ */
+ public int getPostNumPointersSkip() {
+ return getPostNumPointersSkipV6();
+ }
+ public static int getPostNumPointersSkipV6() {
+ return 8;
+ }
}
diff --git a/src/scratchpad/src/org/apache/poi/hdgf/streams/PointerContainingStream.java b/src/scratchpad/src/org/apache/poi/hdgf/streams/PointerContainingStream.java
index d07aa04500..e7f3cf39d4 100644
--- a/src/scratchpad/src/org/apache/poi/hdgf/streams/PointerContainingStream.java
+++ b/src/scratchpad/src/org/apache/poi/hdgf/streams/PointerContainingStream.java
@@ -20,8 +20,6 @@ package org.apache.poi.hdgf.streams;
import org.apache.poi.hdgf.chunks.ChunkFactory;
import org.apache.poi.hdgf.pointers.Pointer;
import org.apache.poi.hdgf.pointers.PointerFactory;
-import org.apache.poi.hdgf.pointers.PointerV6;
-import org.apache.poi.util.LittleEndian;
/**
* A stream that holds pointers, possibly in addition to some
@@ -33,42 +31,14 @@ public class PointerContainingStream extends Stream { // TODO - instantiable sup
private ChunkFactory chunkFactory;
private PointerFactory pointerFactory;
- private int numPointersLocalOffset;
protected PointerContainingStream(Pointer pointer, StreamStore store, ChunkFactory chunkFactory, PointerFactory pointerFactory) {
super(pointer, store);
this.chunkFactory = chunkFactory;
this.pointerFactory = pointerFactory;
-
- // Find the offset to the number of child pointers we have
- numPointersLocalOffset = pointerFactory.identifyNumPointersOffset(
- pointer, store.getContents()
- );
-
- // Generate the objects for the pointers we contain
- int numPointers = pointerFactory.identifyNumPointers(
- pointer, numPointersLocalOffset, store.getContents()
- );
- childPointers = new Pointer[numPointers];
- // Prepare to read the children
- int pos = numPointersLocalOffset;
-
- // v5 only has another (unknown) 4 byte value
- // TODO Should this logic go into PointerFactory?
- if (pointer instanceof PointerV6) {
- pos += 4 + 4;
- } else {
- pos += 2;
- }
-
- // Now create the pointer objects
- for(int i=0; i<numPointers; i++) {
- childPointers[i] = pointerFactory.createPointer(
- store.getContents(), pos
- );
- pos += childPointers[i].getSizeInBytes();
- }
+ // Have the child pointers identified and created
+ childPointers = pointerFactory.createContainerPointers(pointer, store.getContents());
}
/**
diff --git a/src/scratchpad/testcases/org/apache/poi/hdgf/streams/StreamTest.java b/src/scratchpad/testcases/org/apache/poi/hdgf/streams/StreamTest.java
index 99bb4a2bc4..aef1782fa5 100644
--- a/src/scratchpad/testcases/org/apache/poi/hdgf/streams/StreamTest.java
+++ b/src/scratchpad/testcases/org/apache/poi/hdgf/streams/StreamTest.java
@@ -18,6 +18,7 @@
package org.apache.poi.hdgf.streams;
import org.apache.poi.hdgf.pointers.Pointer;
+import static org.apache.poi.hdgf.pointers.PointerV6.*;
import junit.framework.TestCase;
@@ -41,7 +42,20 @@ public abstract class StreamTest extends TestCase {
public boolean destinationHasPointers() { return hasPointers; }
@Override
public boolean destinationHasStrings() { return false; }
+
@Override
public int getSizeInBytes() { return -1; }
+ @Override
+ public int getNumPointersOffset(byte[] data) {
+ return getNumPointersOffsetV6(data);
+ }
+ @Override
+ public int getNumPointers(int offset, byte[] data) {
+ return getNumPointersV6(offset, data);
+ }
+ @Override
+ public int getPostNumPointersSkip() {
+ return getPostNumPointersSkipV6();
+ }
}
}