]> source.dussan.org Git - poi.git/commitdiff
Work in progress - v5 pointer containers
authorNick Burch <nick@apache.org>
Tue, 25 Oct 2016 09:15:02 +0000 (09:15 +0000)
committerNick Burch <nick@apache.org>
Tue, 25 Oct 2016 09:15:02 +0000 (09:15 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1766487 13f79535-47bb-0310-9956-ffa450edef68

src/scratchpad/src/org/apache/poi/hdgf/pointers/PointerFactory.java
src/scratchpad/src/org/apache/poi/hdgf/streams/PointerContainingStream.java

index ddb519cef794bf0762f30c0372bbd36a7dce0223..640396cf571d7ce6900e0ef530a26a7878637a3f 100644 (file)
@@ -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);
+        }
+       }
 }
index ff8da5e983f819fa082bdd88d4c96b71facb1927..d07aa04500da0cba2f6a2d715797129fca87f962 100644 (file)
@@ -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<numPointers; i++) {