diff --git a/src/scratchpad/src/org/apache/poi/hdgf/HDGFDiagram.java b/src/scratchpad/src/org/apache/poi/hdgf/HDGFDiagram.java index bc8fc5439..29c9a9085 100644 --- a/src/scratchpad/src/org/apache/poi/hdgf/HDGFDiagram.java +++ b/src/scratchpad/src/org/apache/poi/hdgf/HDGFDiagram.java @@ -16,10 +16,15 @@ ==================================================================== */ package org.apache.poi.hdgf; -import java.io.ByteArrayInputStream; import java.io.FileInputStream; import java.io.IOException; +import org.apache.poi.hdgf.pointers.Pointer; +import org.apache.poi.hdgf.pointers.PointerFactory; +import org.apache.poi.hdgf.streams.PointerContainingStream; +import org.apache.poi.hdgf.streams.Stream; +import org.apache.poi.hdgf.streams.StringsStream; +import org.apache.poi.hdgf.streams.TrailerStream; import org.apache.poi.poifs.filesystem.DocumentEntry; import org.apache.poi.poifs.filesystem.POIFSFileSystem; import org.apache.poi.util.LittleEndian; @@ -40,8 +45,9 @@ public class HDGFDiagram { private short version; private long docSize; - private VisioPointer trailerPointer; - private PointerBlock trailer; + private Pointer trailerPointer; + private TrailerStream trailer; + private PointerFactory ptrFactory; public HDGFDiagram(POIFSFileSystem fs) throws IOException { filesystem = fs; @@ -65,82 +71,72 @@ public class HDGFDiagram { docSize = LittleEndian.getUInt(_docstream, 0x1c); // ??? 0x20 -> 0x23 - // Grab the pointer to the trailer - trailerPointer = VisioPointer.getPointerAt(_docstream, 0x24); + // Create a Pointer Factory for the document version + ptrFactory = new PointerFactory(version); - // And now grab the trailer - trailer = new CompressedPointerBlock(trailerPointer, _docstream); + // Grab the pointer to the trailer + trailerPointer = ptrFactory.createPointer(_docstream, 0x24); + + // Now grab the trailer + trailer = (TrailerStream) + Stream.createStream(trailerPointer, _docstream, ptrFactory); + + // Finally, find all our streams + trailer.findChildren(_docstream); } + + /** + * Returns the TrailerStream, which is at the root of the + * tree of Streams. + */ + public TrailerStream getTrailerStream() { return trailer; } + /** + * Returns all the top level streams, which are the streams + * pointed to by the TrailerStream. + */ + public Stream[] getTopLevelStreams() { return trailer.getPointedToStreams(); } + public void debug() throws IOException { - System.err.println("Trailer is at " + trailerPointer.offset); - System.err.println("Trailer has type " + trailerPointer.type); - System.err.println("Trailer has length " + trailerPointer.length); - System.err.println("Trailer has format " + trailerPointer.format); + System.err.println("Trailer is at " + trailerPointer.getOffset()); + System.err.println("Trailer has type " + trailerPointer.getType()); + System.err.println("Trailer has length " + trailerPointer.getLength()); + System.err.println("Trailer has format " + trailerPointer.getFormat()); - for(int i=0; i 0) { - System.err.println("\tContains " + pb.getPointers().length + " other pointers"); - for(int j=0; j 0) { + System.err.println("\tContains " + pcs.getPointedToStreams().length + " other pointers/streams"); + for(int j=0; j data.length - offset) { - len = data.length - offset; - } - if(offset < 0) { len = 0; } - - contents = new byte[len]; - if(len > 0) - System.arraycopy(data, offset, contents, 0, contents.length); - - // If we're of type 20, we have child pointers - if(len > 0 && (pointer.type == 20 || pointer.destinationHasPointers())) { - // Grab the offset to the number of pointers - 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 0 && (pointer.destinationHasStrings())) { - for(int i=0; i<64; i+=1) { - short s = LittleEndian.getShort(contents, i); - long l = LittleEndian.getUInt(contents, i); - System.err.println(i + "\t" + s + "\t" + Integer.toHexString(s)); - System.err.println(i + "\t" + l + "\t" + Long.toHexString(l)); - } - } - } - } - - /** - * A block containing lots of pointers to other blocks, that - * is itself compressed - */ - public static class CompressedPointerBlock extends PointerBlock { - protected byte[] compressedContents; - private byte[] blockHeader = new byte[4]; - - protected CompressedPointerBlock(VisioPointer pointer, byte[] data) throws IOException { - super(pointer); - - compressedContents = new byte[(int)pointer.length]; - System.arraycopy(data, (int)pointer.offset, compressedContents, 0, compressedContents.length); - - // Decompress - ByteArrayInputStream bais = new ByteArrayInputStream(compressedContents); - -// TIFFLZWDecoder lzw = new TIFFLZWDecoder(); -// byte[] out = new byte[4096]; -// contents = lzw.decode(compressedContents, out); - - LZW4HDGF lzw = new LZW4HDGF(); - byte[] decomp = lzw.decode(bais); - System.arraycopy(decomp, 0, blockHeader, 0, 4); - processData(decomp, 4, decomp.length-4); - } - } - - /** - * A visio pointer, for visio versions 6+ - */ - public static class VisioPointer { - private int type; - private long address; - private long offset; - private long length; - private short format; - - public boolean destinationHasStrings() { - return (0x40 <= format && format < 0x50); - } - public boolean destinationHasPointers() { - 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; - } - - public static VisioPointer getPointerAt(byte[] data, int offset) { - VisioPointer p = new VisioPointer(); - p.type = LittleEndian.getInt(data, offset+0); - p.address = LittleEndian.getUInt(data, offset+4); - p.offset = LittleEndian.getUInt(data, offset+8); - p.length = LittleEndian.getUInt(data, offset+12); - p.format = LittleEndian.getShort(data, offset+16); - - return p; - } } } diff --git a/src/scratchpad/src/org/apache/poi/hdgf/streams/Stream.java b/src/scratchpad/src/org/apache/poi/hdgf/streams/Stream.java index 81cdcaa63..a34296078 100644 --- a/src/scratchpad/src/org/apache/poi/hdgf/streams/Stream.java +++ b/src/scratchpad/src/org/apache/poi/hdgf/streams/Stream.java @@ -34,6 +34,7 @@ public abstract class Stream { public Pointer getPointer() { return pointer; } protected StreamStore getStore() { return store; } + public int _getContentsLength() { return store.getContents().length; } /** * Creates a new Stream, having already used the pointer diff --git a/src/scratchpad/testcases/org/apache/poi/hdgf/TestHDGFCore.java b/src/scratchpad/testcases/org/apache/poi/hdgf/TestHDGFCore.java new file mode 100644 index 000000000..70bf5fae0 --- /dev/null +++ b/src/scratchpad/testcases/org/apache/poi/hdgf/TestHDGFCore.java @@ -0,0 +1,62 @@ +/* ==================================================================== + 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; + +import java.io.FileInputStream; + +import org.apache.poi.hdgf.streams.PointerContainingStream; +import org.apache.poi.hdgf.streams.TrailerStream; +import org.apache.poi.poifs.filesystem.POIFSFileSystem; + +import junit.framework.TestCase; + +public class TestHDGFCore extends TestCase { + POIFSFileSystem fs; + + protected void setUp() throws Exception { + String dirname = System.getProperty("HDGF.testdata.path"); + String filename = dirname + "/Test_Visio-Some_Random_Text.vsd"; + fs = new POIFSFileSystem(new FileInputStream(filename)); + } + + public void testCreate() throws Exception { + new HDGFDiagram(fs); + } + + public void testTrailer() throws Exception { + HDGFDiagram hdgf = new HDGFDiagram(fs); + assertNotNull(hdgf); + assertNotNull(hdgf.getTrailerStream()); + + // Check it has what we'd expect + TrailerStream trailer = hdgf.getTrailerStream(); + assertEquals(0x8a94, trailer.getPointer().getOffset()); + + assertNotNull(trailer.getPointedToStreams()); + assertEquals(20, trailer.getPointedToStreams().length); + + assertEquals(20, hdgf.getTopLevelStreams().length); + + // 9th one should have children + assertNotNull(trailer.getPointedToStreams()[8]); + assertNotNull(trailer.getPointedToStreams()[8].getPointer()); + PointerContainingStream ps8 = (PointerContainingStream) + trailer.getPointedToStreams()[8]; + assertNotNull(ps8.getPointedToStreams()); + assertEquals(8, ps8.getPointedToStreams().length); + } +} diff --git a/src/scratchpad/testcases/org/apache/poi/hdgf/streams/TestStreamBasics.java b/src/scratchpad/testcases/org/apache/poi/hdgf/streams/TestStreamBasics.java index 13dd16489..ba0fee1dd 100644 --- a/src/scratchpad/testcases/org/apache/poi/hdgf/streams/TestStreamBasics.java +++ b/src/scratchpad/testcases/org/apache/poi/hdgf/streams/TestStreamBasics.java @@ -18,8 +18,6 @@ package org.apache.poi.hdgf.streams; import org.apache.poi.hdgf.pointers.Pointer; -import junit.framework.TestCase; - public class TestStreamBasics extends StreamTest { /** The header from when compressedStream is decompressed */ public static final byte[] compressedStreamDCHeader = new byte[] { diff --git a/src/scratchpad/testcases/org/apache/poi/hdgf/streams/TestStreamComplex.java b/src/scratchpad/testcases/org/apache/poi/hdgf/streams/TestStreamComplex.java index ed110eaea..ff7e927b1 100644 --- a/src/scratchpad/testcases/org/apache/poi/hdgf/streams/TestStreamComplex.java +++ b/src/scratchpad/testcases/org/apache/poi/hdgf/streams/TestStreamComplex.java @@ -18,8 +18,6 @@ package org.apache.poi.hdgf.streams; import java.io.FileInputStream; -import junit.framework.TestCase; - import org.apache.poi.hdgf.pointers.Pointer; import org.apache.poi.hdgf.pointers.PointerFactory; import org.apache.poi.poifs.filesystem.DocumentEntry;