001: /* ====================================================================
002: Licensed to the Apache Software Foundation (ASF) under one or more
003: contributor license agreements. See the NOTICE file distributed with
004: this work for additional information regarding copyright ownership.
005: The ASF licenses this file to You under the Apache License, Version 2.0
006: (the "License"); you may not use this file except in compliance with
007: the License. You may obtain a copy of the License at
008:
009: http://www.apache.org/licenses/LICENSE-2.0
010:
011: Unless required by applicable law or agreed to in writing, software
012: distributed under the License is distributed on an "AS IS" BASIS,
013: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: See the License for the specific language governing permissions and
015: limitations under the License.
016: ==================================================================== */
017: package org.apache.poi.hdgf;
018:
019: import java.io.FileInputStream;
020: import java.io.IOException;
021:
022: import org.apache.poi.POIDocument;
023: import org.apache.poi.hdgf.chunks.ChunkFactory;
024: import org.apache.poi.hdgf.pointers.Pointer;
025: import org.apache.poi.hdgf.pointers.PointerFactory;
026: import org.apache.poi.hdgf.streams.PointerContainingStream;
027: import org.apache.poi.hdgf.streams.Stream;
028: import org.apache.poi.hdgf.streams.StringsStream;
029: import org.apache.poi.hdgf.streams.TrailerStream;
030: import org.apache.poi.poifs.filesystem.DocumentEntry;
031: import org.apache.poi.poifs.filesystem.POIFSFileSystem;
032: import org.apache.poi.util.LittleEndian;
033:
034: /**
035: * See
036: * http://www.redferni.uklinux.net/visio/
037: * http://www.gnome.ru/projects/docs/vsdocs.html
038: * http://www.gnome.ru/projects/docs/slide1.png
039: * http://www.gnome.ru/projects/docs/slide2.png
040: */
041: public class HDGFDiagram extends POIDocument {
042: private static final String VISIO_HEADER = "Visio (TM) Drawing\r\n";
043:
044: private byte[] _docstream;
045:
046: private short version;
047: private long docSize;
048:
049: private Pointer trailerPointer;
050: private TrailerStream trailer;
051:
052: private ChunkFactory chunkFactory;
053: private PointerFactory ptrFactory;
054:
055: public HDGFDiagram(POIFSFileSystem fs) throws IOException {
056: filesystem = fs;
057:
058: DocumentEntry docProps = (DocumentEntry) filesystem.getRoot()
059: .getEntry("VisioDocument");
060:
061: // Grab the document stream
062: _docstream = new byte[docProps.getSize()];
063: filesystem.createDocumentInputStream("VisioDocument").read(
064: _docstream);
065:
066: // Read in the common POI streams
067: readProperties();
068:
069: // Check it's really visio
070: String typeString = new String(_docstream, 0, 20);
071: if (!typeString.equals(VISIO_HEADER)) {
072: throw new IllegalArgumentException(
073: "Wasn't a valid visio document, started with "
074: + typeString);
075: }
076:
077: // Grab the version number, 0x1a -> 0x1b
078: version = LittleEndian.getShort(_docstream, 0x1a);
079: // Grab the document size, 0x1c -> 0x1f
080: docSize = LittleEndian.getUInt(_docstream, 0x1c);
081: // ??? 0x20 -> 0x23
082:
083: // Create the Chunk+Pointer Factories for the document version
084: ptrFactory = new PointerFactory(version);
085: chunkFactory = new ChunkFactory(version);
086:
087: // Grab the pointer to the trailer
088: trailerPointer = ptrFactory.createPointer(_docstream, 0x24);
089:
090: // Now grab the trailer
091: trailer = (TrailerStream) Stream.createStream(trailerPointer,
092: _docstream, chunkFactory, ptrFactory);
093:
094: // Finally, find all our streams
095: trailer.findChildren(_docstream);
096: }
097:
098: /**
099: * Returns the TrailerStream, which is at the root of the
100: * tree of Streams.
101: */
102: public TrailerStream getTrailerStream() {
103: return trailer;
104: }
105:
106: /**
107: * Returns all the top level streams, which are the streams
108: * pointed to by the TrailerStream.
109: */
110: public Stream[] getTopLevelStreams() {
111: return trailer.getPointedToStreams();
112: }
113:
114: public long getDocumentSize() {
115: return docSize;
116: }
117:
118: /**
119: * Prints out some simple debug on the base contents of the file.
120: * @see org.apache.poi.hdgf.dev.VSDDumper
121: */
122: public void debug() throws IOException {
123: System.err.println("Trailer is at "
124: + trailerPointer.getOffset());
125: System.err.println("Trailer has type "
126: + trailerPointer.getType());
127: System.err.println("Trailer has length "
128: + trailerPointer.getLength());
129: System.err.println("Trailer has format "
130: + trailerPointer.getFormat());
131:
132: for (int i = 0; i < trailer.getPointedToStreams().length; i++) {
133: Stream stream = trailer.getPointedToStreams()[i];
134: Pointer ptr = stream.getPointer();
135:
136: System.err.println("Looking at pointer " + i);
137: System.err.println("\tType is " + ptr.getType() + "\t\t"
138: + Integer.toHexString(ptr.getType()));
139: System.err.println("\tOffset is " + ptr.getOffset()
140: + "\t\t" + Long.toHexString(ptr.getOffset()));
141: System.err.println("\tAddress is " + ptr.getAddress()
142: + "\t" + Long.toHexString(ptr.getAddress()));
143: System.err.println("\tLength is " + ptr.getLength()
144: + "\t\t" + Long.toHexString(ptr.getLength()));
145: System.err.println("\tFormat is " + ptr.getFormat()
146: + "\t\t" + Long.toHexString(ptr.getFormat()));
147: System.err.println("\tCompressed is "
148: + ptr.destinationCompressed());
149: System.err.println("\tStream is " + stream.getClass());
150:
151: if (stream instanceof PointerContainingStream) {
152: PointerContainingStream pcs = (PointerContainingStream) stream;
153:
154: if (pcs.getPointedToStreams() != null
155: && pcs.getPointedToStreams().length > 0) {
156: System.err.println("\tContains "
157: + pcs.getPointedToStreams().length
158: + " other pointers/streams");
159: for (int j = 0; j < pcs.getPointedToStreams().length; j++) {
160: Stream ss = pcs.getPointedToStreams()[j];
161: Pointer sptr = ss.getPointer();
162: System.err.println("\t\t" + j + " - Type is "
163: + sptr.getType() + "\t\t"
164: + Integer.toHexString(sptr.getType()));
165: System.err.println("\t\t" + j + " - Length is "
166: + sptr.getLength() + "\t\t"
167: + Long.toHexString(sptr.getLength()));
168: }
169: }
170: }
171:
172: if (stream instanceof StringsStream) {
173: System.err.println("\t\t**strings**");
174: StringsStream ss = (StringsStream) stream;
175: System.err.println("\t\t" + ss._getContentsLength());
176: }
177: }
178: }
179:
180: /**
181: * For testing only
182: */
183: public static void main(String args[]) throws Exception {
184: HDGFDiagram hdgf = new HDGFDiagram(new POIFSFileSystem(
185: new FileInputStream(args[0])));
186: hdgf.debug();
187: }
188: }
|