]> source.dussan.org Git - poi.git/commitdiff
Initial support for HDGF pointers, along with tests
authorNick Burch <nick@apache.org>
Mon, 18 Jun 2007 19:39:29 +0000 (19:39 +0000)
committerNick Burch <nick@apache.org>
Mon, 18 Jun 2007 19:39:29 +0000 (19:39 +0000)
git-svn-id: https://svn.apache.org/repos/asf/jakarta/poi/trunk@548461 13f79535-47bb-0310-9956-ffa450edef68

src/scratchpad/src/org/apache/poi/hdgf/HDGFDiagram.java
src/scratchpad/src/org/apache/poi/hdgf/pointers/Pointer.java [new file with mode: 0644]
src/scratchpad/src/org/apache/poi/hdgf/pointers/PointerFactory.java [new file with mode: 0644]
src/scratchpad/src/org/apache/poi/hdgf/pointers/PointerV6.java [new file with mode: 0644]
src/scratchpad/testcases/org/apache/poi/hdgf/pointers/TestPointerFactory.java [new file with mode: 0644]

index dfe46ac744d0da05e76494c5b1394f2c44dd7cdf..bc8fc5439a061e162c730a9344e469e89bfcdd0a 100644 (file)
@@ -198,7 +198,7 @@ public class HDGFDiagram {
                                int nPointersAt = (int)LittleEndian.getUInt(contents, 0);
                                int numPointers = (int)LittleEndian.getUInt(contents, nPointersAt);
                                int unknownA = (int)LittleEndian.getUInt(contents, nPointersAt+4);
-                               
+
                                pointers = new VisioPointer[numPointers];
                                int pos = nPointersAt + 8;
                                for(int i=0; i<numPointers; i++) {
diff --git a/src/scratchpad/src/org/apache/poi/hdgf/pointers/Pointer.java b/src/scratchpad/src/org/apache/poi/hdgf/pointers/Pointer.java
new file mode 100644 (file)
index 0000000..848d52b
--- /dev/null
@@ -0,0 +1,51 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+package org.apache.poi.hdgf.pointers;
+
+/**
+ * Base class of pointers, which hold metadata and offsets about 
+ *  blocks elsewhere in the file
+ */
+public abstract class Pointer {
+       protected int type;
+       protected int address;
+       protected int offset;
+       protected int length;
+       protected short format;
+       
+       public int getAddress() {
+               return address;
+       }
+       public short getFormat() {
+               return format;
+       }
+       public int getLength() {
+               return length;
+       }
+       public int getOffset() {
+               return offset;
+       }
+       public int getType() {
+               return type;
+       }
+       
+       public abstract int getSizeInBytes();
+       public abstract boolean destinationHasStrings();
+       public abstract boolean destinationHasPointers();
+       public abstract boolean destinationHasChunks();
+       public abstract boolean destinationCompressed();
+}
diff --git a/src/scratchpad/src/org/apache/poi/hdgf/pointers/PointerFactory.java b/src/scratchpad/src/org/apache/poi/hdgf/pointers/PointerFactory.java
new file mode 100644 (file)
index 0000000..ad36da0
--- /dev/null
@@ -0,0 +1,48 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+package org.apache.poi.hdgf.pointers;
+
+import org.apache.poi.util.LittleEndian;
+
+/**
+ * Factor class to create the appropriate pointers, based on the version
+ *  of the file
+ */
+public class PointerFactory {
+       private int version;
+       public PointerFactory(int version) {
+               this.version = version;
+       }
+       
+       public Pointer createPointer(byte[] data, int offset) {
+               Pointer p;
+               if(version >= 6) {
+                       p = new PointerV6();
+                       p.type = LittleEndian.getInt(data, offset+0);
+                       p.address = (int)LittleEndian.getUInt(data, offset+4);
+                       p.offset = (int)LittleEndian.getUInt(data, offset+8);
+                       p.length = (int)LittleEndian.getUInt(data, offset+12);
+                       p.format = LittleEndian.getShort(data, offset+16);
+                       
+                       return p;
+               } else if(version == 5) {
+                       throw new RuntimeException("TODO");
+               } else {
+                       throw new IllegalArgumentException("Visio files with versions below 5 are not supported, yours was " + version);
+               }
+       }
+}
diff --git a/src/scratchpad/src/org/apache/poi/hdgf/pointers/PointerV6.java b/src/scratchpad/src/org/apache/poi/hdgf/pointers/PointerV6.java
new file mode 100644 (file)
index 0000000..e94beed
--- /dev/null
@@ -0,0 +1,44 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+package org.apache.poi.hdgf.pointers;
+
+/**
+ * A Pointer from v6+ 
+ */
+public class PointerV6 extends Pointer {
+       public boolean destinationHasStrings() {
+               return (0x40 <= format && format < 0x50);
+       }
+       public boolean destinationHasPointers() {
+               if(type == 20) return true;
+               if(format == 0x1d || format == 0x1e) return true;
+               return (0x50 <= format && format < 0x60);
+       }
+       public boolean destinationHasChunks() {
+               return (0xd0 <= format && format < 0xd0);
+       }
+       
+       public boolean destinationCompressed() {
+               // Apparently, it's the second least significant bit
+               return (format & 2) > 0;
+       }
+       
+       /**
+        * With v6 pointers, the on-disk size is 18 bytes
+        */
+       public int getSizeInBytes() { return 18; }
+}
diff --git a/src/scratchpad/testcases/org/apache/poi/hdgf/pointers/TestPointerFactory.java b/src/scratchpad/testcases/org/apache/poi/hdgf/pointers/TestPointerFactory.java
new file mode 100644 (file)
index 0000000..25316b3
--- /dev/null
@@ -0,0 +1,139 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+package org.apache.poi.hdgf.pointers;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests for the pointer factory, and the pointers themselves
+ */
+public class TestPointerFactory extends TestCase {
+       // Type: 16   Addr: 0143aff4  Offset: 80   Len: 54   Format: 46   From: 8a94
+       private static byte[] vp6_a = new byte[] {
+               22, 0, 0, 0, -12, -81, 67, 1, -128, 0, 0, 0, 84, 0, 0, 0, 70, 0
+       };
+       // Type: 17   Addr: 014fd84c  Offset: d4   Len: 20   Format: 54   From: 8a94
+       private static byte[] vp6_b = new byte[] {
+               23, 0, 0, 0, 76, -40, 79, 1, -44, 0, 0, 0, 32, 0, 0, 0, 84, 0 
+       };
+       // Type: 17   Addr: 014fd8bc  Offset: f8   Len: 20   Format: 54   From: 8a94
+       private static byte[] vp6_c = new byte[] {
+               23, 0, 0, 0, -68, -40, 79, 1, -8, 0, 0, 0, 32, 0, 0, 0, 84, 0
+       };
+       // Type: ff   Addr: 014fffac  Offset: 0    Len:  0   Format: 60   From: 8a94
+       private static byte[] vp6_d = new byte[] {
+               -1, 0, 0, 0, -84, -1, 79, 1, 0, 0, 0, 0, 0, 0, 0, 0, 96, 0
+       };
+       
+       public void testCreateV4() throws Exception {
+               PointerFactory pf = new PointerFactory(4);
+               try {
+                       pf.createPointer(new byte[]{}, 0);
+                       fail();
+               } catch(IllegalArgumentException e) {
+                       // As expected
+               }
+       }
+       
+       public void testCreateV5() throws Exception {
+               PointerFactory pf = new PointerFactory(5);
+               try {
+                       pf.createPointer(new byte[]{}, 0);
+                       fail();
+               } catch(RuntimeException e) {
+                       // Still to do
+                       assertEquals("TODO", e.getMessage());
+               }
+       }
+
+       public void testCreateV6() throws Exception {
+               PointerFactory pf = new PointerFactory(6);
+               
+               Pointer a = pf.createPointer(vp6_a, 0);
+               assertEquals(0x16, a.getType());
+               assertEquals(0x0143aff4, a.getAddress());
+               assertEquals(0x80, a.getOffset());
+               assertEquals(0x54, a.getLength());
+               assertEquals(0x46, a.getFormat());
+               
+               assertTrue(a.destinationCompressed());
+               assertTrue(a.destinationHasStrings());
+               assertFalse(a.destinationHasChunks());
+               assertFalse(a.destinationHasPointers());
+               
+               assertEquals(18, a.getSizeInBytes());
+               
+               
+               Pointer b = pf.createPointer(vp6_b, 0);
+               assertEquals(0x17, b.getType());
+               assertEquals(0x014fd84c, b.getAddress());
+               assertEquals(0xd4, b.getOffset());
+               assertEquals(0x20, b.getLength());
+               assertEquals(0x54, b.getFormat());
+               
+               assertFalse(b.destinationCompressed());
+               assertFalse(b.destinationHasStrings());
+               assertFalse(b.destinationHasChunks());
+               assertTrue(b.destinationHasPointers());
+               
+               Pointer c = pf.createPointer(vp6_c, 0);
+               assertEquals(0x17, c.getType());
+               assertEquals(0x014fd8bc, c.getAddress());
+               assertEquals(0xf8, c.getOffset());
+               assertEquals(0x20, c.getLength());
+               assertEquals(0x54, c.getFormat());
+               
+               assertFalse(c.destinationCompressed());
+               assertFalse(c.destinationHasStrings());
+               assertFalse(c.destinationHasChunks());
+               assertTrue(c.destinationHasPointers());
+               
+               // Type: ff   Addr: 014fffac  Offset: 0    Len:  0   Format: 60   From: 8a94
+               Pointer d = pf.createPointer(vp6_d, 0);
+               assertEquals(0xff, d.getType());
+               assertEquals(0x014fffac, d.getAddress());
+               assertEquals(0x00, d.getOffset());
+               assertEquals(0x00, d.getLength());
+               assertEquals(0x60, d.getFormat());
+               
+               assertFalse(d.destinationCompressed());
+               assertFalse(d.destinationHasStrings());
+               assertFalse(d.destinationHasChunks());
+               assertFalse(d.destinationHasPointers());
+       }
+
+       public void testCreateV6FromMid() throws Exception {
+               PointerFactory pf = new PointerFactory(11);
+               
+               // Create a from part way down the byte stream
+               byte[] bytes = new byte[28];
+               System.arraycopy(vp6_b, 0, bytes, 0, 10);
+               System.arraycopy(vp6_a, 0, bytes, 10, 18);
+               
+               Pointer a = pf.createPointer(bytes, 10);
+               assertEquals(0x16, a.getType());
+               assertEquals(0x0143aff4, a.getAddress());
+               assertEquals(0x80, a.getOffset());
+               assertEquals(0x54, a.getLength());
+               assertEquals(0x46, a.getFormat());
+               
+               assertTrue(a.destinationCompressed());
+               assertTrue(a.destinationHasStrings());
+               assertFalse(a.destinationHasChunks());
+               assertFalse(a.destinationHasPointers());
+       }
+}