From 3f1965ea27570732c9e905ae9ed79636f16dcad1 Mon Sep 17 00:00:00 2001 From: Nick Burch Date: Tue, 25 Oct 2016 09:15:02 +0000 Subject: [PATCH] Work in progress - v5 pointer containers git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1766487 13f79535-47bb-0310-9956-ffa450edef68 --- .../poi/hdgf/pointers/PointerFactory.java | 38 +++++++++++++++++++ .../hdgf/streams/PointerContainingStream.java | 23 +++++++---- 2 files changed, 53 insertions(+), 8 deletions(-) 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 ddb519cef..640396cf5 100644 --- a/src/scratchpad/src/org/apache/poi/hdgf/pointers/PointerFactory.java +++ b/src/scratchpad/src/org/apache/poi/hdgf/pointers/PointerFactory.java @@ -17,6 +17,7 @@ package org.apache.poi.hdgf.pointers; +import org.apache.poi.hdgf.streams.PointerContainingStream; import org.apache.poi.util.LittleEndian; /** @@ -54,4 +55,41 @@ public final class PointerFactory { throw new IllegalArgumentException("Visio files with versions below 5 are not supported, yours was " + version); } } + + /** + * In a {@link PointerContainingStream}, where would the + * number of child pointers be stored for this kind of Pointer? + */ + 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); + } + } } 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 ff8da5e98..d07aa0450 100644 --- a/src/scratchpad/src/org/apache/poi/hdgf/streams/PointerContainingStream.java +++ b/src/scratchpad/src/org/apache/poi/hdgf/streams/PointerContainingStream.java @@ -20,6 +20,7 @@ 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; /** @@ -40,20 +41,26 @@ public class PointerContainingStream extends Stream { // TODO - instantiable sup this.pointerFactory = pointerFactory; // Find the offset to the number of child pointers we have - // This ought to be the first thing stored in us - numPointersLocalOffset = (int)LittleEndian.getUInt( - store.getContents(), 0 + numPointersLocalOffset = pointerFactory.identifyNumPointersOffset( + pointer, store.getContents() ); // Generate the objects for the pointers we contain - int numPointers = (int)LittleEndian.getUInt( - store.getContents(), numPointersLocalOffset + int numPointers = pointerFactory.identifyNumPointers( + pointer, numPointersLocalOffset, store.getContents() ); childPointers = new Pointer[numPointers]; + + // Prepare to read the children + int pos = numPointersLocalOffset; - // After the number of pointers is another (unknown) - // 4 byte value - int pos = numPointersLocalOffset + 4 + 4; + // 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