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.streams;
018:
019: import org.apache.poi.hdgf.chunks.ChunkFactory;
020: import org.apache.poi.hdgf.pointers.Pointer;
021: import org.apache.poi.hdgf.pointers.PointerFactory;
022: import org.apache.poi.util.LittleEndian;
023:
024: /**
025: * A stream that holds pointers, possibly in addition to some
026: * other data too.
027: */
028: public class PointerContainingStream extends Stream {
029: private Pointer[] childPointers;
030: private Stream[] childStreams;
031:
032: private ChunkFactory chunkFactory;
033: private PointerFactory pointerFactory;
034: private int numPointersLocalOffset;
035:
036: protected PointerContainingStream(Pointer pointer,
037: StreamStore store, ChunkFactory chunkFactory,
038: PointerFactory pointerFactory) {
039: super (pointer, store);
040: this .chunkFactory = chunkFactory;
041: this .pointerFactory = pointerFactory;
042:
043: // Find the offset to the number of child pointers we have
044: // This ought to be the first thing stored in us
045: numPointersLocalOffset = (int) LittleEndian.getUInt(store
046: .getContents(), 0);
047:
048: // Generate the objects for the pointers we contain
049: int numPointers = (int) LittleEndian.getUInt(store
050: .getContents(), numPointersLocalOffset);
051: childPointers = new Pointer[numPointers];
052:
053: // After the number of pointers is another (unknown)
054: // 4 byte value
055: int pos = numPointersLocalOffset + 4 + 4;
056:
057: // Now create the pointer objects
058: for (int i = 0; i < numPointers; i++) {
059: childPointers[i] = pointerFactory.createPointer(store
060: .getContents(), pos);
061: pos += childPointers[i].getSizeInBytes();
062: }
063: }
064:
065: /**
066: * Returns all the pointers that we contain
067: */
068: protected Pointer[] getChildPointers() {
069: return childPointers;
070: }
071:
072: /**
073: * Returns all the "child" streams.
074: * These are all the streams pointed to by the pointers
075: * that we contain.
076: */
077: public Stream[] getPointedToStreams() {
078: return childStreams;
079: }
080:
081: /**
082: * Performs a recursive search, identifying the pointers we contain,
083: * creating the Streams for where they point to, then searching
084: * those if appropriate.
085: */
086: public void findChildren(byte[] documentData) {
087: // For each pointer, generate the Stream it points to
088: childStreams = new Stream[childPointers.length];
089: for (int i = 0; i < childPointers.length; i++) {
090: Pointer ptr = childPointers[i];
091: childStreams[i] = Stream.createStream(ptr, documentData,
092: chunkFactory, pointerFactory);
093:
094: // Process chunk streams into their chunks
095: if (childStreams[i] instanceof ChunkStream) {
096: ChunkStream child = (ChunkStream) childStreams[i];
097: child.findChunks();
098: }
099:
100: // Recurse into pointer containing streams
101: if (childStreams[i] instanceof PointerContainingStream) {
102: PointerContainingStream child = (PointerContainingStream) childStreams[i];
103: child.findChildren(documentData);
104: }
105: }
106: }
107: }
|