| /* ==================================================================== |
| 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.poifs.filesystem; |
| |
| import java.io.IOException; |
| import java.io.InputStream; |
| |
| import org.apache.poi.util.LittleEndianInput; |
| import org.apache.poi.util.SuppressForbidden; |
| |
| /** |
| * This class provides methods to read a DocumentEntry managed by a |
| * {@link POIFSFileSystem} or {@link NPOIFSFileSystem} instance. |
| * It creates the appropriate one, and delegates, allowing us to |
| * work transparently with the two. |
| */ |
| public class DocumentInputStream extends InputStream implements LittleEndianInput { |
| /** returned by read operations if we're at end of document */ |
| protected static final int EOF = -1; |
| |
| protected static final int SIZE_SHORT = 2; |
| protected static final int SIZE_INT = 4; |
| protected static final int SIZE_LONG = 8; |
| |
| private DocumentInputStream delegate; |
| |
| /** For use by downstream implementations */ |
| protected DocumentInputStream() {} |
| |
| /** |
| * Create an InputStream from the specified DocumentEntry |
| * |
| * @param document the DocumentEntry to be read |
| * |
| * @exception IOException if the DocumentEntry cannot be opened (like, maybe it has |
| * been deleted?) |
| */ |
| public DocumentInputStream(DocumentEntry document) throws IOException { |
| if (!(document instanceof DocumentNode)) { |
| throw new IOException("Cannot open internal document storage"); |
| } |
| DocumentNode documentNode = (DocumentNode)document; |
| DirectoryNode parentNode = (DirectoryNode)document.getParent(); |
| |
| if(documentNode.getDocument() != null) { |
| delegate = new ODocumentInputStream(document); |
| } else if(parentNode.getOFileSystem() != null) { |
| delegate = new ODocumentInputStream(document); |
| } else if(parentNode.getNFileSystem() != null) { |
| delegate = new NDocumentInputStream(document); |
| } else { |
| throw new IOException("No FileSystem bound on the parent, can't read contents"); |
| } |
| } |
| |
| /** |
| * Create an InputStream from the specified Document |
| * |
| * @param document the Document to be read |
| */ |
| public DocumentInputStream(OPOIFSDocument document) { |
| delegate = new ODocumentInputStream(document); |
| } |
| |
| /** |
| * Create an InputStream from the specified Document |
| * |
| * @param document the Document to be read |
| */ |
| public DocumentInputStream(NPOIFSDocument document) { |
| delegate = new NDocumentInputStream(document); |
| } |
| |
| @Override |
| @SuppressForbidden("just delegating") |
| public int available() { |
| return delegate.available(); |
| } |
| |
| @Override |
| public void close() { |
| delegate.close(); |
| } |
| |
| @Override |
| public void mark(int ignoredReadlimit) { |
| delegate.mark(ignoredReadlimit); |
| } |
| |
| /** |
| * Tests if this input stream supports the mark and reset methods. |
| * |
| * @return <code>true</code> always |
| */ |
| @Override |
| public boolean markSupported() { |
| return true; |
| } |
| |
| @Override |
| public int read() throws IOException { |
| return delegate.read(); |
| } |
| |
| @Override |
| public int read(byte[] b) throws IOException { |
| return read(b, 0, b.length); |
| } |
| |
| @Override |
| public int read(byte[] b, int off, int len) throws IOException { |
| return delegate.read(b, off, len); |
| } |
| |
| /** |
| * Repositions this stream to the position at the time the mark() method was |
| * last called on this input stream. If mark() has not been called this |
| * method repositions the stream to its beginning. |
| */ |
| @Override |
| public void reset() { |
| delegate.reset(); |
| } |
| |
| @Override |
| public long skip(long n) throws IOException { |
| return delegate.skip(n); |
| } |
| |
| @Override |
| public byte readByte() { |
| return delegate.readByte(); |
| } |
| |
| @Override |
| public double readDouble() { |
| return delegate.readDouble(); |
| } |
| |
| @Override |
| public short readShort() { |
| return (short) readUShort(); |
| } |
| |
| @Override |
| public void readFully(byte[] buf) { |
| readFully(buf, 0, buf.length); |
| } |
| |
| @Override |
| public void readFully(byte[] buf, int off, int len) { |
| delegate.readFully(buf, off, len); |
| } |
| |
| @Override |
| public long readLong() { |
| return delegate.readLong(); |
| } |
| |
| @Override |
| public int readInt() { |
| return delegate.readInt(); |
| } |
| |
| @Override |
| public int readUShort() { |
| return delegate.readUShort(); |
| } |
| |
| @Override |
| public int readUByte() { |
| return delegate.readUByte(); |
| } |
| |
| public long readUInt() { |
| int i = readInt(); |
| return i & 0xFFFFFFFFL; |
| } |
| |
| @Override |
| public void readPlain(byte[] buf, int off, int len) { |
| readFully(buf, off, len); |
| } |
| } |