NDocumentOutputStream write logic

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1590191 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Nick Burch 2014-04-25 23:34:09 +00:00
parent b77ce4fede
commit 73bc57db74
5 changed files with 88 additions and 14 deletions

View File

@ -246,6 +246,9 @@ public class MutablePropertySet extends PropertySet
final MutableSection s = (MutableSection) i.next();
offset += s.write(out);
}
/* Indicate that we're done */
out.close();
}

View File

@ -261,8 +261,6 @@ public abstract class SpecialPropertySet extends MutablePropertySet
delegate.write(dir, name);
}
/**
* @see org.apache.poi.hpsf.MutablePropertySet#write(java.io.OutputStream)
*/
@ -271,8 +269,6 @@ public abstract class SpecialPropertySet extends MutablePropertySet
delegate.write(out);
}
/**
* @see org.apache.poi.hpsf.PropertySet#equals(java.lang.Object)
*/
@ -281,8 +277,6 @@ public abstract class SpecialPropertySet extends MutablePropertySet
return delegate.equals(o);
}
/**
* @see org.apache.poi.hpsf.PropertySet#getProperties()
*/
@ -291,8 +285,6 @@ public abstract class SpecialPropertySet extends MutablePropertySet
return delegate.getProperties();
}
/**
* @see org.apache.poi.hpsf.PropertySet#getProperty(int)
*/

View File

@ -18,9 +18,13 @@
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.
@ -34,6 +38,16 @@ public final class NDocumentOutputStream extends OutputStream {
/** 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.
@ -48,6 +62,8 @@ public final class NDocumentOutputStream extends OutputStream {
_document_size = 0;
_closed = false;
_property = (DocumentProperty)((DocumentNode)document).getProperty();
_document = new NPOIFSDocument((DocumentNode)document);
_document.free();
}
@ -67,22 +83,81 @@ public final class NDocumentOutputStream extends OutputStream {
// 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;
}
}

View File

@ -154,6 +154,11 @@ public final class NPOIFSDocument implements POIFSViewable {
_property.setStartBlock(POIFSConstants.END_OF_CHAIN);
}
NPOIFSFileSystem getFileSystem()
{
return _filesystem;
}
int getDocumentBlockSize() {
return _block_size;
}

View File

@ -799,9 +799,8 @@ public class TestWrite extends TestCase
/**
* Tests that when using NPOIFS, we can do an in-place write
* without needing to stream in + out the whole kitchen sink
* TODO Finish implementing the logic for this
*/
public void DISBALEDtestInPlaceNPOIFSWrite() throws Exception {
public void DISABLEDtestInPlaceNPOIFSWrite() throws Exception {
NPOIFSFileSystem fs = null;
DirectoryEntry root = null;
DocumentNode sinfDoc = null;