package org.apache.poi.poifs.filesystem;
import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
+import org.apache.poi.poifs.common.POIFSConstants;
+import org.apache.poi.poifs.property.DocumentProperty;
+
/**
* This class provides methods to write a DocumentEntry managed by a
* {@link NPOIFSFileSystem} instance.
/** the actual Document */
private NPOIFSDocument _document;
+ /** and its Property */
+ private DocumentProperty _property;
+
+ /** our buffer, when null we're into normal blocks */
+ private ByteArrayOutputStream _buffer =
+ new ByteArrayOutputStream(POIFSConstants.BIG_BLOCK_MINIMUM_DOCUMENT_SIZE);
+
+ /** our main block stream, when we're into normal blocks */
+ private NPOIFSStream _stream;
+ private OutputStream _stream_output;
/**
* Create an OutputStream from the specified DocumentEntry.
_document_size = 0;
_closed = false;
+ _property = (DocumentProperty)((DocumentNode)document).getProperty();
+
_document = new NPOIFSDocument((DocumentNode)document);
_document.free();
}
// Have an empty one created for now
DocumentEntry doc = parent.createDocument(name, new ByteArrayInputStream(new byte[0]));
+ _property = (DocumentProperty)((DocumentNode)doc).getProperty();
_document = new NPOIFSDocument((DocumentNode)doc);
}
+
+ private void dieIfClosed() throws IOException {
+ if (_closed) {
+ throw new IOException("cannot perform requested operation on a closed stream");
+ }
+ }
+
+ private void checkBufferSize() throws IOException {
+ // Have we gone over the mini stream limit yet?
+ if (_buffer.size() > POIFSConstants.BIG_BLOCK_MINIMUM_DOCUMENT_SIZE) {
+ // Will need to be in the main stream
+ byte[] data = _buffer.toByteArray();
+ _buffer = null;
+ write(data, 0, data.length);
+ } else {
+ // So far, mini stream will work, keep going
+ }
+ }
public void write(int b) throws IOException {
- // TODO
+ dieIfClosed();
+
+ if (_buffer != null) {
+ _buffer.write(b);
+ checkBufferSize();
+ } else {
+ write(new byte[] { (byte)b });
+ }
}
public void write(byte[] b) throws IOException {
- // TODO
+ dieIfClosed();
+
+ if (_buffer != null) {
+ _buffer.write(b);
+ checkBufferSize();
+ } else {
+ write(b, 0, b.length);
+ }
}
public void write(byte[] b, int off, int len) throws IOException {
- // TODO
+ dieIfClosed();
+
+ if (_buffer != null) {
+ _buffer.write(b, off, len);
+ checkBufferSize();
+ } else {
+ if (_stream == null) {
+ _stream = new NPOIFSStream(_document.getFileSystem());
+ _stream_output = _stream.getOutputStream();
+ }
+ _stream_output.write(b, off, len);
+ _document_size += len;
+ }
}
public void close() throws IOException {
- // TODO
+ // Do we have a pending buffer for the mini stream?
+ if (_buffer != null) {
+ // It's not much data, so ask NPOIFSDocument to do it for us
+ _document.replaceContents(new ByteArrayInputStream(_buffer.toByteArray()));
+ }
+ else {
+ // We've been writing to the stream as we've gone along
+ // Update the details on the property now
+ _stream_output.close();
+ _property.updateSize(_document_size);
+ _property.setStartBlock(_stream.getStartBlock());
+ }
+
+ // No more!
+ _closed = true;
}
}